blob: 9c44628683307ec05ebacee2b5fbb0037fb7db52 [file] [log] [blame]
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001/*
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002 em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB
3 video capture devices
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08004
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -08005 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
6 Markus Rechberger <mrechberger@gmail.com>
Mauro Carvalho Chehab2e7c6dc2006-04-03 07:53:40 -03007 Mauro Carvalho Chehab <mchehab@infradead.org>
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -08008 Sascha Sommer <saschasommer@freenet.de>
Frank Schaefer0fa4a402012-11-08 14:11:45 -03009 Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080010
Mauro Carvalho Chehab439090d2006-01-23 17:10:54 -020011 Some parts based on SN9C10x PC Camera Controllers GPL driver made
12 by Luca Risolia <luca.risolia@studio.unibo.it>
13
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080014 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/init.h>
30#include <linux/list.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -020033#include <linux/bitmap.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080034#include <linux/usb.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080035#include <linux/i2c.h>
Trent Piepho6d35c8f2007-11-01 01:16:09 -030036#include <linux/mm.h>
Ingo Molnar1e4baed2006-01-15 07:52:23 -020037#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090038#include <linux/slab.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080039
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -080040#include "em28xx.h"
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -030041#include "em28xx-v4l.h"
Mauro Carvalho Chehabc0477ad2006-01-09 15:25:14 -020042#include <media/v4l2-common.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030043#include <media/v4l2-ioctl.h>
Hans Verkuil50fdf402012-09-07 06:10:12 -030044#include <media/v4l2-event.h>
Hans Verkuil2474ed42006-03-19 12:35:57 -030045#include <media/msp3400.h>
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -030046#include <media/tuner.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080047
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -080048#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
49 "Markus Rechberger <mrechberger@gmail.com>, " \
Mauro Carvalho Chehab2e7c6dc2006-04-03 07:53:40 -030050 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -080051 "Sascha Sommer <saschasommer@freenet.de>"
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080052
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -030053static unsigned int isoc_debug;
54module_param(isoc_debug, int, 0644);
55MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
56
57static unsigned int disable_vbi;
58module_param(disable_vbi, int, 0644);
59MODULE_PARM_DESC(disable_vbi, "disable vbi support");
60
61static int alt;
62module_param(alt, int, 0644);
63MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
64
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -080065#define em28xx_videodbg(fmt, arg...) do {\
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -080066 if (video_debug) \
67 printk(KERN_INFO "%s %s :"fmt, \
Harvey Harrisond80e1342008-04-08 23:20:00 -030068 dev->name, __func__ , ##arg); } while (0)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080069
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -030070#define em28xx_isocdbg(fmt, arg...) \
71do {\
72 if (isoc_debug) { \
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -030073 printk(KERN_INFO "%s %s :"fmt, \
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -030074 dev->name, __func__ , ##arg); \
75 } \
76 } while (0)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -030077
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080078MODULE_AUTHOR(DRIVER_AUTHOR);
Mauro Carvalho Chehabd8992b02013-12-27 11:14:59 -030079MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080080MODULE_LICENSE("GPL");
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -030081MODULE_VERSION(EM28XX_VERSION);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080082
Frank Schaefere507e0e2013-03-26 13:38:38 -030083
84#define EM25XX_FRMDATAHDR_BYTE1 0x02
85#define EM25XX_FRMDATAHDR_BYTE2_STILL_IMAGE 0x20
86#define EM25XX_FRMDATAHDR_BYTE2_FRAME_END 0x02
87#define EM25XX_FRMDATAHDR_BYTE2_FRAME_ID 0x01
88#define EM25XX_FRMDATAHDR_BYTE2_MASK (EM25XX_FRMDATAHDR_BYTE2_STILL_IMAGE | \
89 EM25XX_FRMDATAHDR_BYTE2_FRAME_END | \
90 EM25XX_FRMDATAHDR_BYTE2_FRAME_ID)
91
92
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -030093static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
94static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
95static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -030096
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -020097module_param_array(video_nr, int, NULL, 0444);
98module_param_array(vbi_nr, int, NULL, 0444);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -030099module_param_array(radio_nr, int, NULL, 0444);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -0300100MODULE_PARM_DESC(video_nr, "video device numbers");
101MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
102MODULE_PARM_DESC(radio_nr, "radio device numbers");
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800103
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300104static unsigned int video_debug;
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -0300105module_param(video_debug, int, 0644);
106MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800107
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300108/* supported video standards */
109static struct em28xx_fmt format[] = {
110 {
Mauro Carvalho Chehab58fc1ce2009-07-03 02:54:18 -0300111 .name = "16 bpp YUY2, 4:2:2, packed",
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300112 .fourcc = V4L2_PIX_FMT_YUYV,
113 .depth = 16,
Devin Heitmueller3fbf9302008-12-29 23:34:37 -0300114 .reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
Mauro Carvalho Chehab43cb9fe2009-06-30 08:36:17 -0300115 }, {
Mauro Carvalho Chehab58fc1ce2009-07-03 02:54:18 -0300116 .name = "16 bpp RGB 565, LE",
Mauro Carvalho Chehab43cb9fe2009-06-30 08:36:17 -0300117 .fourcc = V4L2_PIX_FMT_RGB565,
118 .depth = 16,
Mauro Carvalho Chehab58fc1ce2009-07-03 02:54:18 -0300119 .reg = EM28XX_OUTFMT_RGB_16_656,
120 }, {
121 .name = "8 bpp Bayer BGBG..GRGR",
122 .fourcc = V4L2_PIX_FMT_SBGGR8,
123 .depth = 8,
124 .reg = EM28XX_OUTFMT_RGB_8_BGBG,
125 }, {
126 .name = "8 bpp Bayer GRGR..BGBG",
127 .fourcc = V4L2_PIX_FMT_SGRBG8,
128 .depth = 8,
129 .reg = EM28XX_OUTFMT_RGB_8_GRGR,
130 }, {
131 .name = "8 bpp Bayer GBGB..RGRG",
132 .fourcc = V4L2_PIX_FMT_SGBRG8,
133 .depth = 8,
134 .reg = EM28XX_OUTFMT_RGB_8_GBGB,
135 }, {
136 .name = "12 bpp YUV411",
137 .fourcc = V4L2_PIX_FMT_YUV411P,
138 .depth = 12,
139 .reg = EM28XX_OUTFMT_YUV411,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300140 },
141};
142
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300143static int em28xx_vbi_supported(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300144{
145 /* Modprobe option to manually disable */
146 if (disable_vbi == 1)
147 return 0;
148
149 if (dev->board.is_webcam)
150 return 0;
151
152 /* FIXME: check subdevices for VBI support */
153
154 if (dev->chip_id == CHIP_ID_EM2860 ||
155 dev->chip_id == CHIP_ID_EM2883)
156 return 1;
157
158 /* Version of em28xx that does not support VBI */
159 return 0;
160}
161
162/*
163 * em28xx_wake_i2c()
164 * configure i2c attached devices
165 */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300166static void em28xx_wake_i2c(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300167{
168 v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
169 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
170 INPUT(dev->ctl_input)->vmux, 0, 0);
171 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
172}
173
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300174static int em28xx_colorlevels_set_default(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300175{
176 em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT);
177 em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT);
178 em28xx_write_reg(dev, EM28XX_R22_UVGAIN, SATURATION_DEFAULT);
179 em28xx_write_reg(dev, EM28XX_R23_UOFFSET, BLUE_BALANCE_DEFAULT);
180 em28xx_write_reg(dev, EM28XX_R24_VOFFSET, RED_BALANCE_DEFAULT);
181 em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, SHARPNESS_DEFAULT);
182
183 em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
184 em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
185 em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
186 em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
187 em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
188 em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
189 return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
190}
191
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300192static int em28xx_set_outfmt(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300193{
194 int ret;
195 u8 fmt, vinctrl;
196
197 fmt = dev->format->reg;
198 if (!dev->is_em25xx)
199 fmt |= 0x20;
200 /*
201 * NOTE: it's not clear if this is really needed !
202 * The datasheets say bit 5 is a reserved bit and devices seem to work
203 * fine without it. But the Windows driver sets it for em2710/50+em28xx
204 * devices and we've always been setting it, too.
205 *
206 * em2765 (em25xx, em276x/7x/8x) devices do NOT work with this bit set,
207 * it's likely used for an additional (compressed ?) format there.
208 */
209 ret = em28xx_write_reg(dev, EM28XX_R27_OUTFMT, fmt);
210 if (ret < 0)
211 return ret;
212
213 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
214 if (ret < 0)
215 return ret;
216
217 vinctrl = dev->vinctl;
218 if (em28xx_vbi_supported(dev) == 1) {
219 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
220 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
221 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
222 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
223 if (dev->norm & V4L2_STD_525_60) {
224 /* NTSC */
225 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
226 } else if (dev->norm & V4L2_STD_625_50) {
227 /* PAL */
228 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
229 }
230 }
231
232 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
233}
234
235static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
236 u8 ymin, u8 ymax)
237{
238 em28xx_videodbg("em28xx Scale: (%d,%d)-(%d,%d)\n",
239 xmin, ymin, xmax, ymax);
240
241 em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1);
242 em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1);
243 em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1);
244 return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1);
245}
246
247static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
248 u16 width, u16 height)
249{
250 u8 cwidth = width >> 2;
251 u8 cheight = height >> 2;
252 u8 overflow = (height >> 9 & 0x02) | (width >> 10 & 0x01);
253 /* NOTE: size limit: 2047x1023 = 2MPix */
254
255 em28xx_videodbg("capture area set to (%d,%d): %dx%d\n",
256 hstart, vstart,
257 ((overflow & 2) << 9 | cwidth << 2),
258 ((overflow & 1) << 10 | cheight << 2));
259
260 em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1);
261 em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1);
262 em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1);
263 em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1);
264 em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1);
265
266 /* FIXME: function/meaning of these registers ? */
267 /* FIXME: align width+height to multiples of 4 ?! */
268 if (dev->is_em25xx) {
269 em28xx_write_reg(dev, 0x34, width >> 4);
270 em28xx_write_reg(dev, 0x35, height >> 4);
271 }
272}
273
274static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
275{
276 u8 mode;
277 /* the em2800 scaler only supports scaling down to 50% */
278
279 if (dev->board.is_em2800) {
280 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
281 } else {
282 u8 buf[2];
283
284 buf[0] = h;
285 buf[1] = h >> 8;
286 em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2);
287
288 buf[0] = v;
289 buf[1] = v >> 8;
290 em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
291 /* it seems that both H and V scalers must be active
292 to work correctly */
293 mode = (h || v) ? 0x30 : 0x00;
294 }
295 return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
296}
297
298/* FIXME: this only function read values from dev */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300299static int em28xx_resolution_set(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300300{
301 int width, height;
302 width = norm_maxw(dev);
303 height = norm_maxh(dev);
304
305 /* Properly setup VBI */
306 dev->vbi_width = 720;
307 if (dev->norm & V4L2_STD_525_60)
308 dev->vbi_height = 12;
309 else
310 dev->vbi_height = 18;
311
312 em28xx_set_outfmt(dev);
313
314 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
315
316 /* If we don't set the start position to 2 in VBI mode, we end up
317 with line 20/21 being YUYV encoded instead of being in 8-bit
318 greyscale. The core of the issue is that line 21 (and line 23 for
319 PAL WSS) are inside of active video region, and as a result they
320 get the pixelformatting associated with that area. So by cropping
321 it out, we end up with the same format as the rest of the VBI
322 region */
323 if (em28xx_vbi_supported(dev) == 1)
324 em28xx_capture_area_set(dev, 0, 2, width, height);
325 else
326 em28xx_capture_area_set(dev, 0, 0, width, height);
327
328 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
329}
330
331/* Set USB alternate setting for analog video */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300332static int em28xx_set_alternate(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300333{
334 int errCode;
335 int i;
336 unsigned int min_pkt_size = dev->width * 2 + 4;
337
338 /* NOTE: for isoc transfers, only alt settings > 0 are allowed
339 bulk transfers seem to work only with alt=0 ! */
340 dev->alt = 0;
341 if ((alt > 0) && (alt < dev->num_alt)) {
342 em28xx_videodbg("alternate forced to %d\n", dev->alt);
343 dev->alt = alt;
344 goto set_alt;
345 }
346 if (dev->analog_xfer_bulk)
347 goto set_alt;
348
349 /* When image size is bigger than a certain value,
350 the frame size should be increased, otherwise, only
351 green screen will be received.
352 */
353 if (dev->width * 2 * dev->height > 720 * 240 * 2)
354 min_pkt_size *= 2;
355
356 for (i = 0; i < dev->num_alt; i++) {
357 /* stop when the selected alt setting offers enough bandwidth */
358 if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) {
359 dev->alt = i;
360 break;
361 /* otherwise make sure that we end up with the maximum bandwidth
362 because the min_pkt_size equation might be wrong...
363 */
364 } else if (dev->alt_max_pkt_size_isoc[i] >
365 dev->alt_max_pkt_size_isoc[dev->alt])
366 dev->alt = i;
367 }
368
369set_alt:
370 /* NOTE: for bulk transfers, we need to call usb_set_interface()
371 * even if the previous settings were the same. Otherwise streaming
372 * fails with all urbs having status = -EOVERFLOW ! */
373 if (dev->analog_xfer_bulk) {
374 dev->max_pkt_size = 512; /* USB 2.0 spec */
375 dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
376 } else { /* isoc */
377 em28xx_videodbg("minimum isoc packet size: %u (alt=%d)\n",
378 min_pkt_size, dev->alt);
379 dev->max_pkt_size =
380 dev->alt_max_pkt_size_isoc[dev->alt];
381 dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS;
382 }
383 em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n",
384 dev->alt, dev->max_pkt_size);
385 errCode = usb_set_interface(dev->udev, 0, dev->alt);
386 if (errCode < 0) {
387 em28xx_errdev("cannot change alternate number to %d (error=%i)\n",
388 dev->alt, errCode);
389 return errCode;
390 }
391 return 0;
392}
393
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300394/* ------------------------------------------------------------------
395 DMA and thread functions
396 ------------------------------------------------------------------*/
397
398/*
Frank Schaefer948a49a2012-12-08 11:31:25 -0300399 * Finish the current buffer
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300400 */
Frank Schaefer948a49a2012-12-08 11:31:25 -0300401static inline void finish_buffer(struct em28xx *dev,
402 struct em28xx_buffer *buf)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300403{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300404 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field);
405
406 buf->vb.v4l2_buf.sequence = dev->field_count++;
407 buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
408 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
409
410 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300411}
412
413/*
Frank Schaefer36016a32012-12-08 11:31:32 -0300414 * Copy picture data from USB buffer to videobuf buffer
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300415 */
416static void em28xx_copy_video(struct em28xx *dev,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300417 struct em28xx_buffer *buf,
Frank Schaefer36016a32012-12-08 11:31:32 -0300418 unsigned char *usb_buf,
Frank Schaefer4078d622012-12-08 11:31:29 -0300419 unsigned long len)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300420{
421 void *fieldstart, *startwrite, *startread;
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300422 int linesdone, currlinedone, offset, lencopy, remain;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300423 int bytesperline = dev->width << 1;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300424
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300425 if (buf->pos + len > buf->length)
426 len = buf->length - buf->pos;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300427
Frank Schaefer36016a32012-12-08 11:31:32 -0300428 startread = usb_buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300429 remain = len;
430
Frank Schaeferc02ec712012-11-08 14:11:33 -0300431 if (dev->progressive || buf->top_field)
Frank Schaefer36016a32012-12-08 11:31:32 -0300432 fieldstart = buf->vb_buf;
Frank Schaeferc02ec712012-11-08 14:11:33 -0300433 else /* interlaced mode, even nr. of lines */
Frank Schaefer36016a32012-12-08 11:31:32 -0300434 fieldstart = buf->vb_buf + bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300435
Frank Schaefer87325332012-12-08 11:31:27 -0300436 linesdone = buf->pos / bytesperline;
437 currlinedone = buf->pos % bytesperline;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -0300438
439 if (dev->progressive)
440 offset = linesdone * bytesperline + currlinedone;
441 else
442 offset = linesdone * bytesperline * 2 + currlinedone;
443
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300444 startwrite = fieldstart + offset;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300445 lencopy = bytesperline - currlinedone;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300446 lencopy = lencopy > remain ? remain : lencopy;
447
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300448 if ((char *)startwrite + lencopy > (char *)buf->vb_buf + buf->length) {
Mauro Carvalho Chehabea8df7e2008-04-13 14:39:29 -0300449 em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
Frank Schaefer36016a32012-12-08 11:31:32 -0300450 ((char *)startwrite + lencopy) -
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300451 ((char *)buf->vb_buf + buf->length));
452 remain = (char *)buf->vb_buf + buf->length -
Frank Schaefer36016a32012-12-08 11:31:32 -0300453 (char *)startwrite;
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -0300454 lencopy = remain;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300455 }
Aidan Thorntone0fadfd342008-04-13 14:56:02 -0300456 if (lencopy <= 0)
457 return;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300458 memcpy(startwrite, startread, lencopy);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300459
460 remain -= lencopy;
461
462 while (remain > 0) {
Frank Schaeferc02ec712012-11-08 14:11:33 -0300463 if (dev->progressive)
464 startwrite += lencopy;
465 else
466 startwrite += lencopy + bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300467 startread += lencopy;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300468 if (bytesperline > remain)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300469 lencopy = remain;
470 else
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300471 lencopy = bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300472
Frank Schaefer36016a32012-12-08 11:31:32 -0300473 if ((char *)startwrite + lencopy > (char *)buf->vb_buf +
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300474 buf->length) {
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -0300475 em28xx_isocdbg("Overflow of %zi bytes past buffer end"
476 "(2)\n",
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300477 ((char *)startwrite + lencopy) -
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300478 ((char *)buf->vb_buf + buf->length));
479 lencopy = remain = (char *)buf->vb_buf + buf->length -
480 (char *)startwrite;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300481 }
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300482 if (lencopy <= 0)
483 break;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300484
485 memcpy(startwrite, startread, lencopy);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300486
487 remain -= lencopy;
488 }
489
Frank Schaefer87325332012-12-08 11:31:27 -0300490 buf->pos += len;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300491}
492
Frank Schaefer36016a32012-12-08 11:31:32 -0300493/*
494 * Copy VBI data from USB buffer to videobuf buffer
495 */
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300496static void em28xx_copy_vbi(struct em28xx *dev,
Frank Schaefer87325332012-12-08 11:31:27 -0300497 struct em28xx_buffer *buf,
Frank Schaefer36016a32012-12-08 11:31:32 -0300498 unsigned char *usb_buf,
Frank Schaefer4078d622012-12-08 11:31:29 -0300499 unsigned long len)
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300500{
Frank Schaefer36016a32012-12-08 11:31:32 -0300501 unsigned int offset;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300502
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300503 if (buf->pos + len > buf->length)
504 len = buf->length - buf->pos;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300505
Frank Schaefer87325332012-12-08 11:31:27 -0300506 offset = buf->pos;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300507 /* Make sure the bottom field populates the second half of the frame */
Frank Schaefer36016a32012-12-08 11:31:32 -0300508 if (buf->top_field == 0)
509 offset += dev->vbi_width * dev->vbi_height;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300510
Frank Schaefer36016a32012-12-08 11:31:32 -0300511 memcpy(buf->vb_buf + offset, usb_buf, len);
Frank Schaefer87325332012-12-08 11:31:27 -0300512 buf->pos += len;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300513}
514
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300515static inline void print_err_status(struct em28xx *dev,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300516 int packet, int status)
517{
518 char *errmsg = "Unknown";
519
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300520 switch (status) {
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300521 case -ENOENT:
522 errmsg = "unlinked synchronuously";
523 break;
524 case -ECONNRESET:
525 errmsg = "unlinked asynchronuously";
526 break;
527 case -ENOSR:
528 errmsg = "Buffer error (overrun)";
529 break;
530 case -EPIPE:
531 errmsg = "Stalled (device not responding)";
532 break;
533 case -EOVERFLOW:
534 errmsg = "Babble (bad cable?)";
535 break;
536 case -EPROTO:
537 errmsg = "Bit-stuff error (bad cable?)";
538 break;
539 case -EILSEQ:
540 errmsg = "CRC/Timeout (could be anything)";
541 break;
542 case -ETIME:
543 errmsg = "Device does not respond";
544 break;
545 }
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300546 if (packet < 0) {
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300547 em28xx_isocdbg("URB status %d [%s].\n", status, errmsg);
548 } else {
549 em28xx_isocdbg("URB packet %d, status %d [%s].\n",
550 packet, status, errmsg);
551 }
552}
553
554/*
Frank Schaefer24a6d842012-12-08 11:31:24 -0300555 * get the next available buffer from dma queue
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300556 */
Frank Schaefer24a6d842012-12-08 11:31:24 -0300557static inline struct em28xx_buffer *get_next_buf(struct em28xx *dev,
558 struct em28xx_dmaqueue *dma_q)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300559{
Frank Schaefer24a6d842012-12-08 11:31:24 -0300560 struct em28xx_buffer *buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300561
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300562 if (list_empty(&dma_q->active)) {
563 em28xx_isocdbg("No active queue to serve\n");
Frank Schaefer24a6d842012-12-08 11:31:24 -0300564 return NULL;
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300565 }
566
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300567 /* Get the next buffer */
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300568 buf = list_entry(dma_q->active.next, struct em28xx_buffer, list);
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300569 /* Cleans up buffer - Useful for testing for frame/URB loss */
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300570 list_del(&buf->list);
Frank Schaefer87325332012-12-08 11:31:27 -0300571 buf->pos = 0;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300572 buf->vb_buf = buf->mem;
Mauro Carvalho Chehabcb784722008-04-13 15:06:52 -0300573
Frank Schaefer24a6d842012-12-08 11:31:24 -0300574 return buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300575}
576
Frank Schaefere04c00d2012-12-08 11:31:30 -0300577/*
578 * Finish the current buffer if completed and prepare for the next field
579 */
580static struct em28xx_buffer *
581finish_field_prepare_next(struct em28xx *dev,
582 struct em28xx_buffer *buf,
583 struct em28xx_dmaqueue *dma_q)
584{
585 if (dev->progressive || dev->top_field) { /* Brand new frame */
586 if (buf != NULL)
587 finish_buffer(dev, buf);
588 buf = get_next_buf(dev, dma_q);
589 }
590 if (buf != NULL) {
591 buf->top_field = dev->top_field;
592 buf->pos = 0;
593 }
594
595 return buf;
596}
597
Frank Schaefer227b7c92012-12-08 11:31:31 -0300598/*
599 * Process data packet according to the em2710/em2750/em28xx frame data format
600 */
601static inline void process_frame_data_em28xx(struct em28xx *dev,
602 unsigned char *data_pkt,
603 unsigned int data_len)
604{
605 struct em28xx_buffer *buf = dev->usb_ctl.vid_buf;
606 struct em28xx_buffer *vbi_buf = dev->usb_ctl.vbi_buf;
607 struct em28xx_dmaqueue *dma_q = &dev->vidq;
608 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
609
610 /* capture type 0 = vbi start
611 capture type 1 = vbi in progress
612 capture type 2 = video start
613 capture type 3 = video in progress */
614 if (data_len >= 4) {
615 /* NOTE: Headers are always 4 bytes and
616 * never split across packets */
617 if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 &&
618 data_pkt[2] == 0x88 && data_pkt[3] == 0x88) {
619 /* Continuation */
620 data_pkt += 4;
621 data_len -= 4;
622 } else if (data_pkt[0] == 0x33 && data_pkt[1] == 0x95) {
623 /* Field start (VBI mode) */
624 dev->capture_type = 0;
625 dev->vbi_read = 0;
626 em28xx_isocdbg("VBI START HEADER !!!\n");
627 dev->top_field = !(data_pkt[2] & 1);
628 data_pkt += 4;
629 data_len -= 4;
630 } else if (data_pkt[0] == 0x22 && data_pkt[1] == 0x5a) {
631 /* Field start (VBI disabled) */
632 dev->capture_type = 2;
633 em28xx_isocdbg("VIDEO START HEADER !!!\n");
634 dev->top_field = !(data_pkt[2] & 1);
635 data_pkt += 4;
636 data_len -= 4;
637 }
638 }
639 /* NOTE: With bulk transfers, intermediate data packets
640 * have no continuation header */
641
642 if (dev->capture_type == 0) {
643 vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q);
644 dev->usb_ctl.vbi_buf = vbi_buf;
645 dev->capture_type = 1;
646 }
647
648 if (dev->capture_type == 1) {
649 int vbi_size = dev->vbi_width * dev->vbi_height;
650 int vbi_data_len = ((dev->vbi_read + data_len) > vbi_size) ?
651 (vbi_size - dev->vbi_read) : data_len;
652
653 /* Copy VBI data */
654 if (vbi_buf != NULL)
655 em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len);
656 dev->vbi_read += vbi_data_len;
657
658 if (vbi_data_len < data_len) {
659 /* Continue with copying video data */
660 dev->capture_type = 2;
661 data_pkt += vbi_data_len;
662 data_len -= vbi_data_len;
663 }
664 }
665
666 if (dev->capture_type == 2) {
667 buf = finish_field_prepare_next(dev, buf, dma_q);
668 dev->usb_ctl.vid_buf = buf;
669 dev->capture_type = 3;
670 }
671
672 if (dev->capture_type == 3 && buf != NULL && data_len > 0)
673 em28xx_copy_video(dev, buf, data_pkt, data_len);
674}
675
Frank Schaefere507e0e2013-03-26 13:38:38 -0300676/*
677 * Process data packet according to the em25xx/em276x/7x/8x frame data format
678 */
679static inline void process_frame_data_em25xx(struct em28xx *dev,
680 unsigned char *data_pkt,
681 unsigned int data_len)
682{
683 struct em28xx_buffer *buf = dev->usb_ctl.vid_buf;
684 struct em28xx_dmaqueue *dmaq = &dev->vidq;
685 bool frame_end = 0;
686
687 /* Check for header */
688 /* NOTE: at least with bulk transfers, only the first packet
689 * has a header and has always set the FRAME_END bit */
690 if (data_len >= 2) { /* em25xx header is only 2 bytes long */
691 if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) &&
692 ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) {
693 dev->top_field = !(data_pkt[1] &
694 EM25XX_FRMDATAHDR_BYTE2_FRAME_ID);
695 frame_end = data_pkt[1] &
696 EM25XX_FRMDATAHDR_BYTE2_FRAME_END;
697 data_pkt += 2;
698 data_len -= 2;
699 }
700
701 /* Finish field and prepare next (BULK only) */
702 if (dev->analog_xfer_bulk && frame_end) {
703 buf = finish_field_prepare_next(dev, buf, dmaq);
704 dev->usb_ctl.vid_buf = buf;
705 }
706 /* NOTE: in ISOC mode when a new frame starts and buf==NULL,
707 * we COULD already prepare a buffer here to avoid skipping the
708 * first frame.
709 */
710 }
711
712 /* Copy data */
713 if (buf != NULL && data_len > 0)
714 em28xx_copy_video(dev, buf, data_pkt, data_len);
715
716 /* Finish frame (ISOC only) => avoids lag of 1 frame */
717 if (!dev->analog_xfer_bulk && frame_end) {
718 buf = finish_field_prepare_next(dev, buf, dmaq);
719 dev->usb_ctl.vid_buf = buf;
720 }
721
722 /* NOTE: Tested with USB bulk transfers only !
723 * The wording in the datasheet suggests that isoc might work different.
724 * The current code assumes that with isoc transfers each packet has a
725 * header like with the other em28xx devices.
726 */
727 /* NOTE: Support for interlaced mode is pure theory. It has not been
728 * tested and it is unknown if these devices actually support it. */
729 /* NOTE: No VBI support yet (these chips likely do not support VBI). */
730}
731
Frank Schaefer960da932012-11-25 06:37:37 -0300732/* Processes and copies the URB data content (video and VBI data) */
Frank Schaefer0fa4a402012-11-08 14:11:45 -0300733static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300734{
Frank Schaefer227b7c92012-12-08 11:31:31 -0300735 int xfer_bulk, num_packets, i;
736 unsigned char *usb_data_pkt;
737 unsigned int usb_data_len;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300738
739 if (!dev)
740 return 0;
741
Frank Schaefer2665c292012-12-27 19:02:43 -0300742 if (dev->disconnected)
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300743 return 0;
744
Frank Schaefer1653cb0c2012-11-08 14:11:44 -0300745 if (urb->status < 0)
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300746 print_err_status(dev, -1, urb->status);
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300747
Frank Schaefer4601cc32012-11-08 14:11:46 -0300748 xfer_bulk = usb_pipebulk(urb->pipe);
749
Frank Schaefer4601cc32012-11-08 14:11:46 -0300750 if (xfer_bulk) /* bulk */
751 num_packets = 1;
752 else /* isoc */
753 num_packets = urb->number_of_packets;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300754
Frank Schaefer4601cc32012-11-08 14:11:46 -0300755 for (i = 0; i < num_packets; i++) {
756 if (xfer_bulk) { /* bulk */
Frank Schaefer227b7c92012-12-08 11:31:31 -0300757 usb_data_len = urb->actual_length;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300758
Frank Schaefer227b7c92012-12-08 11:31:31 -0300759 usb_data_pkt = urb->transfer_buffer;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300760 } else { /* isoc */
761 if (urb->iso_frame_desc[i].status < 0) {
762 print_err_status(dev, i,
763 urb->iso_frame_desc[i].status);
764 if (urb->iso_frame_desc[i].status != -EPROTO)
765 continue;
766 }
767
Frank Schaefer227b7c92012-12-08 11:31:31 -0300768 usb_data_len = urb->iso_frame_desc[i].actual_length;
769 if (usb_data_len > dev->max_pkt_size) {
Frank Schaefer4601cc32012-11-08 14:11:46 -0300770 em28xx_isocdbg("packet bigger than packet size");
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300771 continue;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300772 }
773
Frank Schaefer227b7c92012-12-08 11:31:31 -0300774 usb_data_pkt = urb->transfer_buffer +
775 urb->iso_frame_desc[i].offset;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300776 }
777
Frank Schaefer227b7c92012-12-08 11:31:31 -0300778 if (usb_data_len == 0) {
Frank Schaefer4601cc32012-11-08 14:11:46 -0300779 /* NOTE: happens very often with isoc transfers */
780 /* em28xx_usbdbg("packet %d is empty",i); - spammy */
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300781 continue;
782 }
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300783
Frank Schaefere507e0e2013-03-26 13:38:38 -0300784 if (dev->is_em25xx)
785 process_frame_data_em25xx(dev,
786 usb_data_pkt, usb_data_len);
787 else
788 process_frame_data_em28xx(dev,
789 usb_data_pkt, usb_data_len);
790
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300791 }
Frank Schaefer227b7c92012-12-08 11:31:31 -0300792 return 1;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300793}
794
795
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300796static int get_ressource(enum v4l2_buf_type f_type)
797{
798 switch (f_type) {
799 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
800 return EM28XX_RESOURCE_VIDEO;
801 case V4L2_BUF_TYPE_VBI_CAPTURE:
802 return EM28XX_RESOURCE_VBI;
803 default:
804 BUG();
805 return 0;
806 }
807}
808
809/* Usage lock check functions */
810static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type)
811{
812 int res_type = get_ressource(f_type);
813
814 /* is it free? */
815 if (dev->resources & res_type) {
816 /* no, someone else uses it */
817 return -EBUSY;
818 }
819
820 /* it's free, grab it */
821 dev->resources |= res_type;
822 em28xx_videodbg("res: get %d\n", res_type);
823 return 0;
824}
825
826static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type)
827{
828 int res_type = get_ressource(f_type);
829
830 dev->resources &= ~res_type;
831 em28xx_videodbg("res: put %d\n", res_type);
832}
833
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300834/* ------------------------------------------------------------------
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300835 Videobuf2 operations
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300836 ------------------------------------------------------------------*/
837
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300838static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
839 unsigned int *nbuffers, unsigned int *nplanes,
840 unsigned int sizes[], void *alloc_ctxs[])
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300841{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300842 struct em28xx *dev = vb2_get_drv_priv(vq);
843 unsigned long size;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300844
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300845 if (fmt)
846 size = fmt->fmt.pix.sizeimage;
847 else
848 size = (dev->width * dev->height * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300849
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300850 if (size == 0)
851 return -EINVAL;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300852
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300853 if (0 == *nbuffers)
854 *nbuffers = 32;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300855
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300856 *nplanes = 1;
857 sizes[0] = size;
Mauro Carvalho Chehabd2d9fbf2008-04-17 21:38:53 -0300858
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300859 return 0;
860}
861
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300862static int
863buffer_prepare(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300864{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300865 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
866 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
867 unsigned long size;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300868
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300869 em28xx_videodbg("%s, field=%d\n", __func__, vb->v4l2_buf.field);
Aidan Thornton3b5fa922008-04-13 15:09:36 -0300870
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300871 size = (dev->width * dev->height * dev->format->depth + 7) >> 3;
Aidan Thornton3b5fa922008-04-13 15:09:36 -0300872
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300873 if (vb2_plane_size(vb, 0) < size) {
874 em28xx_videodbg("%s data will not fit into plane (%lu < %lu)\n",
875 __func__, vb2_plane_size(vb, 0), size);
876 return -EINVAL;
877 }
878 vb2_set_plane_payload(&buf->vb, 0, size);
879
880 return 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300881}
882
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300883int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300884{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300885 struct em28xx *dev = vb2_get_drv_priv(vq);
886 struct v4l2_frequency f;
887 int rc = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300888
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300889 em28xx_videodbg("%s\n", __func__);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300890
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300891 /* Make sure streaming is not already in progress for this type
892 of filehandle (e.g. video, vbi) */
893 rc = res_get(dev, vq->type);
894 if (rc)
895 return rc;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300896
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300897 if (dev->streaming_users == 0) {
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300898 /* First active streaming user, so allocate all the URBs */
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300899
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300900 /* Allocate the USB bandwidth */
901 em28xx_set_alternate(dev);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300902
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300903 /* Needed, since GPIO might have disabled power of
904 some i2c device
905 */
906 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300907
Frank Schaefer0455eeb2012-11-25 06:37:34 -0300908 dev->capture_type = -1;
Frank Schaefer960da932012-11-25 06:37:37 -0300909 rc = em28xx_init_usb_xfer(dev, EM28XX_ANALOG_MODE,
910 dev->analog_xfer_bulk,
911 EM28XX_NUM_BUFS,
912 dev->max_pkt_size,
913 dev->packet_multiplier,
914 em28xx_urb_data_copy);
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300915 if (rc < 0)
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300916 return rc;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300917
918 /*
919 * djh: it's not clear whether this code is still needed. I'm
920 * leaving it in here for now entirely out of concern for
921 * backward compatibility (the old code did it)
922 */
923
924 /* Ask tuner to go to analog or radio mode */
925 memset(&f, 0, sizeof(f));
926 f.frequency = dev->ctl_freq;
927 if (vq->owner && vq->owner->vdev->vfl_type == VFL_TYPE_RADIO)
928 f.type = V4L2_TUNER_RADIO;
929 else
930 f.type = V4L2_TUNER_ANALOG_TV;
931 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300932 }
933
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300934 dev->streaming_users++;
935
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300936 return rc;
937}
938
Mauro Carvalho Chehab3a799c22013-01-05 01:27:21 -0200939static int em28xx_stop_streaming(struct vb2_queue *vq)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300940{
941 struct em28xx *dev = vb2_get_drv_priv(vq);
942 struct em28xx_dmaqueue *vidq = &dev->vidq;
943 unsigned long flags = 0;
944
945 em28xx_videodbg("%s\n", __func__);
946
947 res_free(dev, vq->type);
948
949 if (dev->streaming_users-- == 1) {
950 /* Last active user, so shutdown all the URBS */
951 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
952 }
953
954 spin_lock_irqsave(&dev->slock, flags);
955 while (!list_empty(&vidq->active)) {
956 struct em28xx_buffer *buf;
957 buf = list_entry(vidq->active.next, struct em28xx_buffer, list);
958 list_del(&buf->list);
959 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
960 }
961 dev->usb_ctl.vid_buf = NULL;
962 spin_unlock_irqrestore(&dev->slock, flags);
963
964 return 0;
965}
966
967int em28xx_stop_vbi_streaming(struct vb2_queue *vq)
968{
969 struct em28xx *dev = vb2_get_drv_priv(vq);
970 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
971 unsigned long flags = 0;
972
973 em28xx_videodbg("%s\n", __func__);
974
975 res_free(dev, vq->type);
976
977 if (dev->streaming_users-- == 1) {
978 /* Last active user, so shutdown all the URBS */
979 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
980 }
981
982 spin_lock_irqsave(&dev->slock, flags);
983 while (!list_empty(&vbiq->active)) {
984 struct em28xx_buffer *buf;
985 buf = list_entry(vbiq->active.next, struct em28xx_buffer, list);
986 list_del(&buf->list);
987 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
988 }
989 dev->usb_ctl.vbi_buf = NULL;
990 spin_unlock_irqrestore(&dev->slock, flags);
991
992 return 0;
993}
994
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300995static void
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300996buffer_queue(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300997{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300998 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
999 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
1000 struct em28xx_dmaqueue *vidq = &dev->vidq;
1001 unsigned long flags = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001002
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001003 em28xx_videodbg("%s\n", __func__);
1004 buf->mem = vb2_plane_vaddr(vb, 0);
1005 buf->length = vb2_plane_size(vb, 0);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001006
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001007 spin_lock_irqsave(&dev->slock, flags);
1008 list_add_tail(&buf->list, &vidq->active);
1009 spin_unlock_irqrestore(&dev->slock, flags);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001010}
1011
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001012static struct vb2_ops em28xx_video_qops = {
1013 .queue_setup = queue_setup,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001014 .buf_prepare = buffer_prepare,
1015 .buf_queue = buffer_queue,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001016 .start_streaming = em28xx_start_analog_streaming,
1017 .stop_streaming = em28xx_stop_streaming,
1018 .wait_prepare = vb2_ops_wait_prepare,
1019 .wait_finish = vb2_ops_wait_finish,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001020};
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001021
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001022static int em28xx_vb2_setup(struct em28xx *dev)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001023{
1024 int rc;
1025 struct vb2_queue *q;
1026
1027 /* Setup Videobuf2 for Video capture */
1028 q = &dev->vb_vidq;
1029 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Mauro Carvalho Chehabef85cd92013-01-06 00:34:22 -02001030 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
Frank Schaefer195281d2013-03-09 06:53:01 -03001031 q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001032 q->drv_priv = dev;
1033 q->buf_struct_size = sizeof(struct em28xx_buffer);
1034 q->ops = &em28xx_video_qops;
1035 q->mem_ops = &vb2_vmalloc_memops;
1036
1037 rc = vb2_queue_init(q);
1038 if (rc < 0)
1039 return rc;
1040
1041 /* Setup Videobuf2 for VBI capture */
1042 q = &dev->vb_vbiq;
1043 q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1044 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR;
Frank Schaefer195281d2013-03-09 06:53:01 -03001045 q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001046 q->drv_priv = dev;
1047 q->buf_struct_size = sizeof(struct em28xx_buffer);
1048 q->ops = &em28xx_vbi_qops;
1049 q->mem_ops = &vb2_vmalloc_memops;
1050
1051 rc = vb2_queue_init(q);
1052 if (rc < 0)
1053 return rc;
1054
1055 return 0;
1056}
1057
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001058/********************* v4l2 interface **************************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001059
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001060static void video_mux(struct em28xx *dev, int index)
1061{
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001062 dev->ctl_input = index;
1063 dev->ctl_ainput = INPUT(index)->amux;
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001064 dev->ctl_aoutput = INPUT(index)->aout;
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001065
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001066 if (!dev->ctl_aoutput)
1067 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
1068
Hans Verkuil5325b422009-04-02 11:26:22 -03001069 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
1070 INPUT(index)->vmux, 0, 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001071
Mauro Carvalho Chehab505b6d02008-11-25 09:39:50 -03001072 if (dev->board.has_msp34xx) {
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001073 if (dev->i2s_speed) {
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001074 v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
1075 s_i2s_clock_freq, dev->i2s_speed);
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001076 }
Hans Verkuil2474ed42006-03-19 12:35:57 -03001077 /* Note: this is msp3400 specific */
Hans Verkuil5325b422009-04-02 11:26:22 -03001078 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1079 dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001080 }
Mauro Carvalho Chehab539c96d2008-01-05 09:53:54 -03001081
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001082 if (dev->board.adecoder != EM28XX_NOADECODER) {
Hans Verkuil5325b422009-04-02 11:26:22 -03001083 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1084 dev->ctl_ainput, dev->ctl_aoutput, 0);
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001085 }
1086
Mauro Carvalho Chehab00b87302008-02-06 18:34:13 -03001087 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001088}
1089
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001090static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001091{
Hans Verkuil081b9452012-09-07 05:43:59 -03001092 struct em28xx *dev = priv;
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001093
Hans Verkuil081b9452012-09-07 05:43:59 -03001094 /*
1095 * In the case of non-AC97 volume controls, we still need
1096 * to do some setups at em28xx, in order to mute/unmute
1097 * and to adjust audio volume. However, the value ranges
1098 * should be checked by the corresponding V4L subdriver.
1099 */
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001100 switch (ctrl->id) {
1101 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil081b9452012-09-07 05:43:59 -03001102 dev->mute = ctrl->val;
1103 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001104 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001105 case V4L2_CID_AUDIO_VOLUME:
Hans Verkuil081b9452012-09-07 05:43:59 -03001106 dev->volume = ctrl->val;
1107 em28xx_audio_analog_set(dev);
1108 break;
1109 }
1110}
1111
1112static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
1113{
1114 struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler);
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001115 int ret = -EINVAL;
Hans Verkuil081b9452012-09-07 05:43:59 -03001116
1117 switch (ctrl->id) {
1118 case V4L2_CID_AUDIO_MUTE:
1119 dev->mute = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001120 ret = em28xx_audio_analog_set(dev);
Hans Verkuil081b9452012-09-07 05:43:59 -03001121 break;
1122 case V4L2_CID_AUDIO_VOLUME:
1123 dev->volume = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001124 ret = em28xx_audio_analog_set(dev);
1125 break;
1126 case V4L2_CID_CONTRAST:
1127 ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val);
1128 break;
1129 case V4L2_CID_BRIGHTNESS:
1130 ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val);
1131 break;
1132 case V4L2_CID_SATURATION:
1133 ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val);
1134 break;
1135 case V4L2_CID_BLUE_BALANCE:
1136 ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val);
1137 break;
1138 case V4L2_CID_RED_BALANCE:
1139 ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val);
1140 break;
1141 case V4L2_CID_SHARPNESS:
1142 ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001143 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001144 }
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001145
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001146 return (ret < 0) ? ret : 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001147}
1148
Hans Verkuil081b9452012-09-07 05:43:59 -03001149const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
1150 .s_ctrl = em28xx_s_ctrl,
1151};
1152
Frank Schaefer6b09a212013-02-10 16:05:12 -03001153static void size_to_scale(struct em28xx *dev,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001154 unsigned int width, unsigned int height,
1155 unsigned int *hscale, unsigned int *vscale)
1156{
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001157 unsigned int maxw = norm_maxw(dev);
1158 unsigned int maxh = norm_maxh(dev);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001159
1160 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001161 if (*hscale > EM28XX_HVSCALE_MAX)
1162 *hscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001163
1164 *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001165 if (*vscale > EM28XX_HVSCALE_MAX)
1166 *vscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001167}
1168
Frank Schaeferb8374132013-02-10 16:05:13 -03001169static void scale_to_size(struct em28xx *dev,
1170 unsigned int hscale, unsigned int vscale,
1171 unsigned int *width, unsigned int *height)
1172{
1173 unsigned int maxw = norm_maxw(dev);
1174 unsigned int maxh = norm_maxh(dev);
1175
1176 *width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
1177 *height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
1178}
1179
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001180/* ------------------------------------------------------------------
1181 IOCTL vidioc handling
1182 ------------------------------------------------------------------*/
1183
Hans Verkuil78b526a2008-05-28 12:16:41 -03001184static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001185 struct v4l2_format *f)
1186{
1187 struct em28xx_fh *fh = priv;
1188 struct em28xx *dev = fh->dev;
1189
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001190 f->fmt.pix.width = dev->width;
1191 f->fmt.pix.height = dev->height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001192 f->fmt.pix.pixelformat = dev->format->fourcc;
1193 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -03001194 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001195 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1196
1197 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001198 if (dev->progressive)
1199 f->fmt.pix.field = V4L2_FIELD_NONE;
1200 else
1201 f->fmt.pix.field = dev->interlaced ?
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001202 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001203 return 0;
1204}
1205
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001206static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
1207{
1208 unsigned int i;
1209
1210 for (i = 0; i < ARRAY_SIZE(format); i++)
1211 if (format[i].fourcc == fourcc)
1212 return &format[i];
1213
1214 return NULL;
1215}
1216
Hans Verkuil78b526a2008-05-28 12:16:41 -03001217static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001218 struct v4l2_format *f)
1219{
1220 struct em28xx_fh *fh = priv;
1221 struct em28xx *dev = fh->dev;
Trent Piephoccb83402009-05-30 21:45:46 -03001222 unsigned int width = f->fmt.pix.width;
1223 unsigned int height = f->fmt.pix.height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001224 unsigned int maxw = norm_maxw(dev);
1225 unsigned int maxh = norm_maxh(dev);
1226 unsigned int hscale, vscale;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001227 struct em28xx_fmt *fmt;
1228
1229 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1230 if (!fmt) {
1231 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1232 f->fmt.pix.pixelformat);
1233 return -EINVAL;
1234 }
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001235
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001236 if (dev->board.is_em2800) {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001237 /* the em2800 can only scale down to 50% */
Trent Piephoccb83402009-05-30 21:45:46 -03001238 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1239 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001240 /*
1241 * MaxPacketSize for em2800 is too small to capture at full
1242 * resolution use half of maxw as the scaler can only scale
1243 * to 50%
1244 */
Sascha Sommer1020d132012-01-08 16:54:28 -03001245 if (width == maxw && height == maxh)
1246 width /= 2;
Trent Piephoccb83402009-05-30 21:45:46 -03001247 } else {
1248 /* width must even because of the YUYV format
1249 height must be even because of interlacing */
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001250 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1251 1, 0);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001252 }
1253
Frank Schaefer6b09a212013-02-10 16:05:12 -03001254 size_to_scale(dev, width, height, &hscale, &vscale);
Hans Verkuil46f85972013-03-30 05:31:42 -03001255 scale_to_size(dev, hscale, vscale, &width, &height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001256
1257 f->fmt.pix.width = width;
1258 f->fmt.pix.height = height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001259 f->fmt.pix.pixelformat = fmt->fourcc;
Hans Verkuile6066db2013-02-06 08:14:47 -03001260 f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001261 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001262 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001263 if (dev->progressive)
1264 f->fmt.pix.field = V4L2_FIELD_NONE;
1265 else
1266 f->fmt.pix.field = dev->interlaced ?
1267 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Alban Browaeys51dd4d72013-07-16 19:06:46 -03001268 f->fmt.pix.priv = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001269
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001270 return 0;
1271}
1272
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001273static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
1274 unsigned width, unsigned height)
1275{
1276 struct em28xx_fmt *fmt;
1277
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001278 fmt = format_by_fourcc(fourcc);
1279 if (!fmt)
1280 return -EINVAL;
1281
1282 dev->format = fmt;
1283 dev->width = width;
1284 dev->height = height;
1285
1286 /* set new image size */
Frank Schaefer6b09a212013-02-10 16:05:12 -03001287 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001288
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001289 em28xx_resolution_set(dev);
1290
1291 return 0;
1292}
1293
Hans Verkuil78b526a2008-05-28 12:16:41 -03001294static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001295 struct v4l2_format *f)
1296{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001297 struct em28xx *dev = video_drvdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001298
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001299 if (dev->streaming_users > 0)
1300 return -EBUSY;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001301
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001302 vidioc_try_fmt_vid_cap(file, priv, f);
1303
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001304 return em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001305 f->fmt.pix.width, f->fmt.pix.height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001306}
1307
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001308static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1309{
1310 struct em28xx_fh *fh = priv;
1311 struct em28xx *dev = fh->dev;
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001312
1313 *norm = dev->norm;
1314
1315 return 0;
1316}
1317
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001318static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
1319{
1320 struct em28xx_fh *fh = priv;
1321 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001322
1323 v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm);
1324
1325 return 0;
1326}
1327
Hans Verkuil314527a2013-03-15 06:10:40 -03001328static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001329{
1330 struct em28xx_fh *fh = priv;
1331 struct em28xx *dev = fh->dev;
1332 struct v4l2_format f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001333
Hans Verkuil314527a2013-03-15 06:10:40 -03001334 if (norm == dev->norm)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001335 return 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001336
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001337 if (dev->streaming_users > 0)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001338 return -EBUSY;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001339
Hans Verkuil314527a2013-03-15 06:10:40 -03001340 dev->norm = norm;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001341
1342 /* Adjusts width/height, if needed */
Hans Verkuild8c95c02012-09-07 07:31:54 -03001343 f.fmt.pix.width = 720;
Hans Verkuil314527a2013-03-15 06:10:40 -03001344 f.fmt.pix.height = (norm & V4L2_STD_525_60) ? 480 : 576;
Hans Verkuil78b526a2008-05-28 12:16:41 -03001345 vidioc_try_fmt_vid_cap(file, priv, &f);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001346
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001347 /* set new image size */
1348 dev->width = f.fmt.pix.width;
1349 dev->height = f.fmt.pix.height;
Frank Schaefer6b09a212013-02-10 16:05:12 -03001350 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001351
1352 em28xx_resolution_set(dev);
Hans Verkuilf41737e2009-04-01 03:52:39 -03001353 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001354
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001355 return 0;
1356}
1357
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001358static int vidioc_g_parm(struct file *file, void *priv,
1359 struct v4l2_streamparm *p)
1360{
1361 struct em28xx_fh *fh = priv;
1362 struct em28xx *dev = fh->dev;
1363 int rc = 0;
1364
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001365 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001366 if (dev->board.is_webcam)
1367 rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1368 video, g_parm, p);
1369 else
1370 v4l2_video_std_frame_period(dev->norm,
1371 &p->parm.capture.timeperframe);
1372
1373 return rc;
1374}
1375
1376static int vidioc_s_parm(struct file *file, void *priv,
1377 struct v4l2_streamparm *p)
1378{
1379 struct em28xx_fh *fh = priv;
1380 struct em28xx *dev = fh->dev;
1381
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001382 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001383 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
1384}
1385
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001386static const char *iname[] = {
1387 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
1388 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
1389 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
1390 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
1391 [EM28XX_VMUX_SVIDEO] = "S-Video",
1392 [EM28XX_VMUX_TELEVISION] = "Television",
1393 [EM28XX_VMUX_CABLE] = "Cable TV",
1394 [EM28XX_VMUX_DVB] = "DVB",
1395 [EM28XX_VMUX_DEBUG] = "for debug only",
1396};
1397
1398static int vidioc_enum_input(struct file *file, void *priv,
1399 struct v4l2_input *i)
1400{
1401 struct em28xx_fh *fh = priv;
1402 struct em28xx *dev = fh->dev;
1403 unsigned int n;
1404
1405 n = i->index;
1406 if (n >= MAX_EM28XX_INPUT)
1407 return -EINVAL;
1408 if (0 == INPUT(n)->type)
1409 return -EINVAL;
1410
1411 i->index = n;
1412 i->type = V4L2_INPUT_TYPE_CAMERA;
1413
1414 strcpy(i->name, iname[INPUT(n)->type]);
1415
1416 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
1417 (EM28XX_VMUX_CABLE == INPUT(n)->type))
1418 i->type = V4L2_INPUT_TYPE_TUNER;
1419
Mauro Carvalho Chehab7d497f82007-11-11 14:15:34 -03001420 i->std = dev->vdev->tvnorms;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001421 /* webcams do not have the STD API */
1422 if (dev->board.is_webcam)
1423 i->capabilities = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001424
1425 return 0;
1426}
1427
1428static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1429{
1430 struct em28xx_fh *fh = priv;
1431 struct em28xx *dev = fh->dev;
1432
1433 *i = dev->ctl_input;
1434
1435 return 0;
1436}
1437
1438static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1439{
1440 struct em28xx_fh *fh = priv;
1441 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001442
1443 if (i >= MAX_EM28XX_INPUT)
1444 return -EINVAL;
1445 if (0 == INPUT(i)->type)
1446 return -EINVAL;
1447
Ezequiel García96371fc2012-03-23 18:09:34 -03001448 video_mux(dev, i);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001449 return 0;
1450}
1451
1452static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1453{
1454 struct em28xx_fh *fh = priv;
1455 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001456
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001457 switch (a->index) {
1458 case EM28XX_AMUX_VIDEO:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001459 strcpy(a->name, "Television");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001460 break;
1461 case EM28XX_AMUX_LINE_IN:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001462 strcpy(a->name, "Line In");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001463 break;
1464 case EM28XX_AMUX_VIDEO2:
1465 strcpy(a->name, "Television alt");
1466 break;
1467 case EM28XX_AMUX_PHONE:
1468 strcpy(a->name, "Phone");
1469 break;
1470 case EM28XX_AMUX_MIC:
1471 strcpy(a->name, "Mic");
1472 break;
1473 case EM28XX_AMUX_CD:
1474 strcpy(a->name, "CD");
1475 break;
1476 case EM28XX_AMUX_AUX:
1477 strcpy(a->name, "Aux");
1478 break;
1479 case EM28XX_AMUX_PCM_OUT:
1480 strcpy(a->name, "PCM");
1481 break;
1482 default:
1483 return -EINVAL;
1484 }
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001485
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001486 a->index = dev->ctl_ainput;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001487 a->capability = V4L2_AUDCAP_STEREO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001488
1489 return 0;
1490}
1491
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001492static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001493{
1494 struct em28xx_fh *fh = priv;
1495 struct em28xx *dev = fh->dev;
1496
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03001497 if (a->index >= MAX_EM28XX_INPUT)
1498 return -EINVAL;
1499 if (0 == INPUT(a->index)->type)
1500 return -EINVAL;
1501
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001502 dev->ctl_ainput = INPUT(a->index)->amux;
1503 dev->ctl_aoutput = INPUT(a->index)->aout;
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001504
1505 if (!dev->ctl_aoutput)
1506 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001507
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001508 return 0;
1509}
1510
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001511static int vidioc_g_tuner(struct file *file, void *priv,
1512 struct v4l2_tuner *t)
1513{
1514 struct em28xx_fh *fh = priv;
1515 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001516
1517 if (0 != t->index)
1518 return -EINVAL;
1519
1520 strcpy(t->name, "Tuner");
1521
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001522 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001523 return 0;
1524}
1525
1526static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001527 const struct v4l2_tuner *t)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001528{
1529 struct em28xx_fh *fh = priv;
1530 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001531
1532 if (0 != t->index)
1533 return -EINVAL;
1534
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001535 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001536 return 0;
1537}
1538
1539static int vidioc_g_frequency(struct file *file, void *priv,
1540 struct v4l2_frequency *f)
1541{
1542 struct em28xx_fh *fh = priv;
1543 struct em28xx *dev = fh->dev;
1544
Hans Verkuil20deebf2012-09-06 10:07:25 -03001545 if (0 != f->tuner)
1546 return -EINVAL;
1547
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001548 f->frequency = dev->ctl_freq;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001549 return 0;
1550}
1551
1552static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001553 const struct v4l2_frequency *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001554{
Hans Verkuilb530a442013-03-19 04:09:26 -03001555 struct v4l2_frequency new_freq = *f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001556 struct em28xx_fh *fh = priv;
1557 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001558
1559 if (0 != f->tuner)
1560 return -EINVAL;
1561
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001562 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
Hans Verkuilb530a442013-03-19 04:09:26 -03001563 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
1564 dev->ctl_freq = new_freq.frequency;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001565
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001566 return 0;
1567}
1568
Hans Verkuilcd634f12013-03-27 08:04:23 -03001569#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03001570static int vidioc_g_chip_info(struct file *file, void *priv,
1571 struct v4l2_dbg_chip_info *chip)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001572{
1573 struct em28xx_fh *fh = priv;
1574 struct em28xx *dev = fh->dev;
1575
1576 if (chip->match.addr > 1)
1577 return -EINVAL;
1578 if (chip->match.addr == 1)
1579 strlcpy(chip->name, "ac97", sizeof(chip->name));
1580 else
1581 strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
1582 return 0;
1583}
1584
Frank Schaefer35deba32013-02-07 13:39:19 -03001585static int em28xx_reg_len(int reg)
1586{
1587 switch (reg) {
1588 case EM28XX_R40_AC97LSB:
1589 case EM28XX_R30_HSCALELOW:
1590 case EM28XX_R32_VSCALELOW:
1591 return 2;
1592 default:
1593 return 1;
1594 }
1595}
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001596
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001597static int vidioc_g_register(struct file *file, void *priv,
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001598 struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001599{
1600 struct em28xx_fh *fh = priv;
1601 struct em28xx *dev = fh->dev;
1602 int ret;
1603
Hans Verkuilabca2052013-05-29 06:59:35 -03001604 if (reg->match.addr > 1)
1605 return -EINVAL;
1606 if (reg->match.addr) {
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001607 ret = em28xx_read_ac97(dev, reg->reg);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001608 if (ret < 0)
1609 return ret;
1610
1611 reg->val = ret;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001612 reg->size = 1;
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001613 return 0;
1614 }
1615
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001616 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001617 reg->size = em28xx_reg_len(reg->reg);
1618 if (reg->size == 1) {
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001619 ret = em28xx_read_reg(dev, reg->reg);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001620
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001621 if (ret < 0)
1622 return ret;
1623
1624 reg->val = ret;
1625 } else {
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001626 __le16 val = 0;
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001627 ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001628 reg->reg, (char *)&val, 2);
1629 if (ret < 0)
1630 return ret;
1631
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001632 reg->val = le16_to_cpu(val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001633 }
1634
1635 return 0;
1636}
1637
1638static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001639 const struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001640{
1641 struct em28xx_fh *fh = priv;
1642 struct em28xx *dev = fh->dev;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001643 __le16 buf;
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001644
Hans Verkuilabca2052013-05-29 06:59:35 -03001645 if (reg->match.addr > 1)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001646 return -EINVAL;
Hans Verkuilabca2052013-05-29 06:59:35 -03001647 if (reg->match.addr)
1648 return em28xx_write_ac97(dev, reg->reg, reg->val);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001649
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001650 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001651 buf = cpu_to_le16(reg->val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001652
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001653 return em28xx_write_regs(dev, reg->reg, (char *)&buf,
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001654 em28xx_reg_len(reg->reg));
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001655}
1656#endif
1657
1658
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001659static int vidioc_querycap(struct file *file, void *priv,
1660 struct v4l2_capability *cap)
1661{
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001662 struct video_device *vdev = video_devdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001663 struct em28xx_fh *fh = priv;
1664 struct em28xx *dev = fh->dev;
1665
1666 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1667 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
Thierry MERLEcb977162009-01-20 18:01:33 -03001668 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001669
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001670 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1671 cap->device_caps = V4L2_CAP_READWRITE |
1672 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1673 else if (vdev->vfl_type == VFL_TYPE_RADIO)
1674 cap->device_caps = V4L2_CAP_RADIO;
1675 else
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001676 cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
Devin Heitmueller04146142009-09-11 00:08:44 -03001677
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001678 if (dev->audio_mode.has_audio)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001679 cap->device_caps |= V4L2_CAP_AUDIO;
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001680
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -03001681 if (dev->tuner_type != TUNER_ABSENT)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001682 cap->device_caps |= V4L2_CAP_TUNER;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001683
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001684 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1685 V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1686 if (dev->vbi_dev)
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001687 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001688 if (dev->radio_dev)
1689 cap->capabilities |= V4L2_CAP_RADIO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001690 return 0;
1691}
1692
Hans Verkuil78b526a2008-05-28 12:16:41 -03001693static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001694 struct v4l2_fmtdesc *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001695{
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001696 if (unlikely(f->index >= ARRAY_SIZE(format)))
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001697 return -EINVAL;
1698
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001699 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1700 f->pixelformat = format[f->index].fourcc;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001701
1702 return 0;
1703}
1704
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001705static int vidioc_enum_framesizes(struct file *file, void *priv,
1706 struct v4l2_frmsizeenum *fsize)
1707{
1708 struct em28xx_fh *fh = priv;
1709 struct em28xx *dev = fh->dev;
1710 struct em28xx_fmt *fmt;
1711 unsigned int maxw = norm_maxw(dev);
1712 unsigned int maxh = norm_maxh(dev);
1713
1714 fmt = format_by_fourcc(fsize->pixel_format);
1715 if (!fmt) {
1716 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1717 fsize->pixel_format);
1718 return -EINVAL;
1719 }
1720
1721 if (dev->board.is_em2800) {
1722 if (fsize->index > 1)
1723 return -EINVAL;
1724 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1725 fsize->discrete.width = maxw / (1 + fsize->index);
1726 fsize->discrete.height = maxh / (1 + fsize->index);
1727 return 0;
1728 }
1729
1730 if (fsize->index != 0)
1731 return -EINVAL;
1732
1733 /* Report a continuous range */
1734 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
Frank Schaefer6c3598e2013-02-10 16:05:14 -03001735 scale_to_size(dev, EM28XX_HVSCALE_MAX, EM28XX_HVSCALE_MAX,
1736 &fsize->stepwise.min_width, &fsize->stepwise.min_height);
1737 if (fsize->stepwise.min_width < 48)
1738 fsize->stepwise.min_width = 48;
1739 if (fsize->stepwise.min_height < 38)
1740 fsize->stepwise.min_height = 38;
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001741 fsize->stepwise.max_width = maxw;
1742 fsize->stepwise.max_height = maxh;
1743 fsize->stepwise.step_width = 1;
1744 fsize->stepwise.step_height = 1;
1745 return 0;
1746}
1747
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001748/* RAW VBI ioctls */
1749
1750static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1751 struct v4l2_format *format)
1752{
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001753 struct em28xx_fh *fh = priv;
1754 struct em28xx *dev = fh->dev;
1755
1756 format->fmt.vbi.samples_per_line = dev->vbi_width;
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001757 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1758 format->fmt.vbi.offset = 0;
1759 format->fmt.vbi.flags = 0;
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001760 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1761 format->fmt.vbi.count[0] = dev->vbi_height;
1762 format->fmt.vbi.count[1] = dev->vbi_height;
Hans Verkuil2a221d32012-09-07 08:51:32 -03001763 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001764
1765 /* Varies by video standard (NTSC, PAL, etc.) */
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001766 if (dev->norm & V4L2_STD_525_60) {
1767 /* NTSC */
1768 format->fmt.vbi.start[0] = 10;
1769 format->fmt.vbi.start[1] = 273;
1770 } else if (dev->norm & V4L2_STD_625_50) {
1771 /* PAL */
1772 format->fmt.vbi.start[0] = 6;
1773 format->fmt.vbi.start[1] = 318;
1774 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001775
1776 return 0;
1777}
1778
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001779/* ----------------------------------------------------------- */
1780/* RADIO ESPECIFIC IOCTLS */
1781/* ----------------------------------------------------------- */
1782
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001783static int radio_g_tuner(struct file *file, void *priv,
1784 struct v4l2_tuner *t)
1785{
1786 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1787
1788 if (unlikely(t->index > 0))
1789 return -EINVAL;
1790
1791 strcpy(t->name, "Radio");
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001792
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001793 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001794
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001795 return 0;
1796}
1797
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001798static int radio_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001799 const struct v4l2_tuner *t)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001800{
1801 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1802
1803 if (0 != t->index)
1804 return -EINVAL;
1805
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001806 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001807
1808 return 0;
1809}
1810
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001811/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001812 * em28xx_v4l2_open()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001813 * inits the device and starts isoc transfer
1814 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001815static int em28xx_v4l2_open(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001816{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001817 struct video_device *vdev = video_devdata(filp);
1818 struct em28xx *dev = video_drvdata(filp);
1819 enum v4l2_buf_type fh_type = 0;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001820 struct em28xx_fh *fh;
Markus Rechberger9c755412005-11-08 21:37:52 -08001821
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001822 switch (vdev->vfl_type) {
1823 case VFL_TYPE_GRABBER:
1824 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1825 break;
1826 case VFL_TYPE_VBI:
1827 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1828 break;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001829 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03001830
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001831 em28xx_videodbg("open dev=%s type=%s users=%d\n",
1832 video_device_node_name(vdev), v4l2_type_names[fh_type],
1833 dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001834
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001835
Hans Verkuil876cb142012-06-23 08:12:47 -03001836 if (mutex_lock_interruptible(&dev->lock))
1837 return -ERESTARTSYS;
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001838 fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001839 if (!fh) {
1840 em28xx_errdev("em28xx-video.c: Out of memory?!\n");
Hans Verkuil876cb142012-06-23 08:12:47 -03001841 mutex_unlock(&dev->lock);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001842 return -ENOMEM;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001843 }
Hans Verkuil69a61642012-09-07 05:52:40 -03001844 v4l2_fh_init(&fh->fh, vdev);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001845 fh->dev = dev;
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001846 fh->type = fh_type;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001847 filp->private_data = fh;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001848
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001849 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001850 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001851 em28xx_resolution_set(dev);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001852
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001853 /* Needed, since GPIO might have disabled power of
1854 some i2c device
1855 */
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03001856 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001857
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001858 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001859
1860 if (vdev->vfl_type == VFL_TYPE_RADIO) {
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001861 em28xx_videodbg("video_open: setting radio device\n");
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001862 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001863 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001864
1865 dev->users++;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001866
Hans Verkuil876cb142012-06-23 08:12:47 -03001867 mutex_unlock(&dev->lock);
Hans Verkuil69a61642012-09-07 05:52:40 -03001868 v4l2_fh_add(&fh->fh);
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001869
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001870 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001871}
1872
1873/*
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001874 * em28xx_v4l2_fini()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001875 * unregisters the v4l2,i2c and usb devices
1876 * called when the device gets disconected or at module unload
1877*/
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001878static int em28xx_v4l2_fini(struct em28xx *dev)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001879{
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03001880 if (dev->is_audio_only) {
1881 /* Shouldn't initialize IR for this interface */
1882 return 0;
1883 }
1884
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001885 if (!dev->has_video) {
1886 /* This device does not support the v4l2 extension */
1887 return 0;
1888 }
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001889
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001890 if (dev->radio_dev) {
Laurent Pinchartf0813b42009-11-27 13:57:30 -03001891 if (video_is_registered(dev->radio_dev))
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001892 video_unregister_device(dev->radio_dev);
1893 else
1894 video_device_release(dev->radio_dev);
1895 dev->radio_dev = NULL;
1896 }
1897 if (dev->vbi_dev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001898 em28xx_info("V4L2 device %s deregistered\n",
1899 video_device_node_name(dev->vbi_dev));
Laurent Pinchartf0813b42009-11-27 13:57:30 -03001900 if (video_is_registered(dev->vbi_dev))
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001901 video_unregister_device(dev->vbi_dev);
1902 else
1903 video_device_release(dev->vbi_dev);
1904 dev->vbi_dev = NULL;
1905 }
1906 if (dev->vdev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001907 em28xx_info("V4L2 device %s deregistered\n",
1908 video_device_node_name(dev->vdev));
Laurent Pinchartf0813b42009-11-27 13:57:30 -03001909 if (video_is_registered(dev->vdev))
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001910 video_unregister_device(dev->vdev);
1911 else
1912 video_device_release(dev->vdev);
1913 dev->vdev = NULL;
1914 }
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001915
1916 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001917}
1918
1919/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001920 * em28xx_v4l2_close()
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001921 * stops streaming and deallocates all resources allocated by the v4l2
1922 * calls and ioctls
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001923 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001924static int em28xx_v4l2_close(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001925{
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001926 struct em28xx_fh *fh = filp->private_data;
1927 struct em28xx *dev = fh->dev;
1928 int errCode;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001929
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001930 em28xx_videodbg("users=%d\n", dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001931
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001932 vb2_fop_release(filp);
Ricardo Ribalda98c24dcd2013-11-06 05:39:35 -03001933 mutex_lock(&dev->lock);
Devin Heitmueller8c873d32009-09-03 00:23:27 -03001934
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001935 if (dev->users == 1) {
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001936 /* the device is already disconnect,
1937 free the remaining resources */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001938
Frank Schaefer2665c292012-12-27 19:02:43 -03001939 if (dev->disconnected) {
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001940 em28xx_release_resources(dev);
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001941 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1942 v4l2_device_unregister(&dev->v4l2_dev);
Frank Schaefer0cf544a2012-11-08 14:11:49 -03001943 kfree(dev->alt_max_pkt_size_isoc);
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001944 goto exit;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001945 }
1946
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03001947 /* Save some power by putting tuner to sleep */
Laurent Pinchart622b8282009-10-05 10:48:17 -03001948 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03001949
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001950 /* do this before setting alternate! */
Mauro Carvalho Chehab2fe3e2e2008-11-27 09:10:40 -03001951 em28xx_set_mode(dev, EM28XX_SUSPEND);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001952
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001953 /* set alternate 0 */
1954 dev->alt = 0;
1955 em28xx_videodbg("setting alternate 0\n");
1956 errCode = usb_set_interface(dev->udev, 0, 0);
1957 if (errCode < 0) {
1958 em28xx_errdev("cannot change alternate number to "
1959 "0 (error=%i)\n", errCode);
1960 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001961 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001962
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001963exit:
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001964 dev->users--;
Hans Verkuil876cb142012-06-23 08:12:47 -03001965 mutex_unlock(&dev->lock);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001966 return 0;
1967}
1968
Hans Verkuilbec43662008-12-30 06:58:20 -03001969static const struct v4l2_file_operations em28xx_v4l_fops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001970 .owner = THIS_MODULE,
1971 .open = em28xx_v4l2_open,
1972 .release = em28xx_v4l2_close,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001973 .read = vb2_fop_read,
1974 .poll = vb2_fop_poll,
1975 .mmap = vb2_fop_mmap,
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001976 .unlocked_ioctl = video_ioctl2,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001977};
1978
Hans Verkuila3998102008-07-21 02:57:38 -03001979static const struct v4l2_ioctl_ops video_ioctl_ops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001980 .vidioc_querycap = vidioc_querycap,
Hans Verkuil78b526a2008-05-28 12:16:41 -03001981 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1982 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1983 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1984 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001985 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil2a221d32012-09-07 08:51:32 -03001986 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Frank Schaeferaab34612013-02-07 13:39:16 -03001987 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001988 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001989 .vidioc_g_audio = vidioc_g_audio,
1990 .vidioc_s_audio = vidioc_s_audio,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001991
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001992 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1993 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1994 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1995 .vidioc_querybuf = vb2_ioctl_querybuf,
1996 .vidioc_qbuf = vb2_ioctl_qbuf,
1997 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1998
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001999 .vidioc_g_std = vidioc_g_std,
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03002000 .vidioc_querystd = vidioc_querystd,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002001 .vidioc_s_std = vidioc_s_std,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03002002 .vidioc_g_parm = vidioc_g_parm,
2003 .vidioc_s_parm = vidioc_s_parm,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002004 .vidioc_enum_input = vidioc_enum_input,
2005 .vidioc_g_input = vidioc_g_input,
2006 .vidioc_s_input = vidioc_s_input,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002007 .vidioc_streamon = vb2_ioctl_streamon,
2008 .vidioc_streamoff = vb2_ioctl_streamoff,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002009 .vidioc_g_tuner = vidioc_g_tuner,
2010 .vidioc_s_tuner = vidioc_s_tuner,
2011 .vidioc_g_frequency = vidioc_g_frequency,
2012 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002013 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2014 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002015#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03002016 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002017 .vidioc_g_register = vidioc_g_register,
2018 .vidioc_s_register = vidioc_s_register,
2019#endif
Hans Verkuila3998102008-07-21 02:57:38 -03002020};
2021
2022static const struct video_device em28xx_video_template = {
2023 .fops = &em28xx_v4l_fops,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002024 .release = video_device_release_empty,
Hans Verkuila3998102008-07-21 02:57:38 -03002025 .ioctl_ops = &video_ioctl_ops,
2026
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002027 .tvnorms = V4L2_STD_ALL,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002028};
2029
Hans Verkuilbec43662008-12-30 06:58:20 -03002030static const struct v4l2_file_operations radio_fops = {
Hans Verkuila3998102008-07-21 02:57:38 -03002031 .owner = THIS_MODULE,
2032 .open = em28xx_v4l2_open,
2033 .release = em28xx_v4l2_close,
Hans Verkuil8fd0bda2010-12-18 09:59:51 -03002034 .unlocked_ioctl = video_ioctl2,
Hans Verkuila3998102008-07-21 02:57:38 -03002035};
2036
2037static const struct v4l2_ioctl_ops radio_ioctl_ops = {
Hans Verkuila9d79fe2012-09-06 07:31:04 -03002038 .vidioc_querycap = vidioc_querycap,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002039 .vidioc_g_tuner = radio_g_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002040 .vidioc_s_tuner = radio_s_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002041 .vidioc_g_frequency = vidioc_g_frequency,
2042 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002043 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2044 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002045#ifdef CONFIG_VIDEO_ADV_DEBUG
Michal Marek430c73f2013-04-16 08:06:30 -03002046 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002047 .vidioc_g_register = vidioc_g_register,
2048 .vidioc_s_register = vidioc_s_register,
2049#endif
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002050};
2051
Hans Verkuila3998102008-07-21 02:57:38 -03002052static struct video_device em28xx_radio_template = {
2053 .name = "em28xx-radio",
Hans Verkuila3998102008-07-21 02:57:38 -03002054 .fops = &radio_fops,
2055 .ioctl_ops = &radio_ioctl_ops,
Hans Verkuila3998102008-07-21 02:57:38 -03002056};
2057
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002058/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2059static unsigned short saa711x_addrs[] = {
2060 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2061 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2062 I2C_CLIENT_END };
2063
2064static unsigned short tvp5150_addrs[] = {
2065 0xb8 >> 1,
2066 0xba >> 1,
2067 I2C_CLIENT_END
2068};
2069
2070static unsigned short msp3400_addrs[] = {
2071 0x80 >> 1,
2072 0x88 >> 1,
2073 I2C_CLIENT_END
2074};
2075
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002076/******************************** usb interface ******************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002077
Adrian Bunk532fe652008-01-28 22:10:48 -03002078static struct video_device *em28xx_vdev_init(struct em28xx *dev,
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002079 const struct video_device *template,
2080 const char *type_name)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002081{
2082 struct video_device *vfd;
2083
2084 vfd = video_device_alloc();
2085 if (NULL == vfd)
2086 return NULL;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002087
2088 *vfd = *template;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002089 vfd->v4l2_dev = &dev->v4l2_dev;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002090 vfd->debug = video_debug;
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002091 vfd->lock = &dev->lock;
Hans Verkuil69a61642012-09-07 05:52:40 -03002092 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
Hans Verkuild8c95c02012-09-07 07:31:54 -03002093 if (dev->board.is_webcam)
2094 vfd->tvnorms = 0;
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002095
2096 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
2097 dev->name, type_name);
2098
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002099 video_set_drvdata(vfd, dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002100 return vfd;
2101}
2102
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002103static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2104{
2105 memset(ctl, 0, sizeof(*ctl));
2106
2107 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2108 ctl->max_len = 64;
2109 ctl->mts = em28xx_boards[dev->model].mts_firmware;
2110
2111 switch (dev->model) {
2112 case EM2880_BOARD_EMPIRE_DUAL_TV:
2113 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
2114 case EM2882_BOARD_TERRATEC_HYBRID_XS:
2115 ctl->demod = XC3028_FE_ZARLINK456;
2116 break;
2117 case EM2880_BOARD_TERRATEC_HYBRID_XS:
2118 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
2119 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
2120 ctl->demod = XC3028_FE_ZARLINK456;
2121 break;
2122 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
2123 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
2124 ctl->demod = XC3028_FE_DEFAULT;
2125 break;
2126 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
2127 ctl->demod = XC3028_FE_DEFAULT;
2128 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
2129 break;
2130 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
2131 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
2132 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
2133 /* FIXME: Better to specify the needed IF */
2134 ctl->demod = XC3028_FE_DEFAULT;
2135 break;
2136 case EM2883_BOARD_KWORLD_HYBRID_330U:
2137 case EM2882_BOARD_DIKOM_DK300:
2138 case EM2882_BOARD_KWORLD_VS_DVBT:
2139 ctl->demod = XC3028_FE_CHINA;
2140 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2141 break;
2142 case EM2882_BOARD_EVGA_INDTUBE:
2143 ctl->demod = XC3028_FE_CHINA;
2144 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
2145 break;
2146 default:
2147 ctl->demod = XC3028_FE_OREN538;
2148 }
2149}
2150
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002151static void em28xx_tuner_setup(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002152{
2153 struct tuner_setup tun_setup;
2154 struct v4l2_frequency f;
2155
2156 if (dev->tuner_type == TUNER_ABSENT)
2157 return;
2158
2159 memset(&tun_setup, 0, sizeof(tun_setup));
2160
2161 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2162 tun_setup.tuner_callback = em28xx_tuner_callback;
2163
2164 if (dev->board.radio.type) {
2165 tun_setup.type = dev->board.radio.type;
2166 tun_setup.addr = dev->board.radio_addr;
2167
2168 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2169 }
2170
2171 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2172 tun_setup.type = dev->tuner_type;
2173 tun_setup.addr = dev->tuner_addr;
2174
2175 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2176 }
2177
2178 if (dev->tda9887_conf) {
2179 struct v4l2_priv_tun_config tda9887_cfg;
2180
2181 tda9887_cfg.tuner = TUNER_TDA9887;
2182 tda9887_cfg.priv = &dev->tda9887_conf;
2183
2184 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
2185 }
2186
2187 if (dev->tuner_type == TUNER_XC2028) {
2188 struct v4l2_priv_tun_config xc2028_cfg;
2189 struct xc2028_ctrl ctl;
2190
2191 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2192 memset(&ctl, 0, sizeof(ctl));
2193
2194 em28xx_setup_xc3028(dev, &ctl);
2195
2196 xc2028_cfg.tuner = TUNER_XC2028;
2197 xc2028_cfg.priv = &ctl;
2198
2199 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
2200 }
2201
2202 /* configure tuner */
2203 f.tuner = 0;
2204 f.type = V4L2_TUNER_ANALOG_TV;
2205 f.frequency = 9076; /* just a magic number */
2206 dev->ctl_freq = f.frequency;
2207 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
2208}
2209
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002210static int em28xx_v4l2_init(struct em28xx *dev)
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002211{
Hans Verkuil081b9452012-09-07 05:43:59 -03002212 u8 val;
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002213 int ret;
Sascha Sommer1020d132012-01-08 16:54:28 -03002214 unsigned int maxw;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002215 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2216
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03002217 if (dev->is_audio_only) {
2218 /* Shouldn't initialize IR for this interface */
2219 return 0;
2220 }
2221
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002222 if (!dev->has_video) {
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002223 /* This device does not support the v4l2 extension */
2224 return 0;
2225 }
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002226
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002227 em28xx_info("Registering V4L2 extension\n");
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002228
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002229 mutex_lock(&dev->lock);
2230
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002231 ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
2232 if (ret < 0) {
2233 em28xx_errdev("Call to v4l2_device_register() failed!\n");
2234 goto err;
2235 }
2236
2237 v4l2_ctrl_handler_init(hdl, 8);
2238 dev->v4l2_dev.ctrl_handler = hdl;
2239
2240 /*
2241 * Default format, used for tvp5150 or saa711x output formats
2242 */
2243 dev->vinmode = 0x10;
2244 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2245 EM28XX_VINCTRL_CCIR656_ENABLE;
2246
2247 /* request some modules */
2248
2249 if (dev->board.has_msp34xx)
2250 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2251 "msp3400", 0, msp3400_addrs);
2252
2253 if (dev->board.decoder == EM28XX_SAA711X)
2254 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2255 "saa7115_auto", 0, saa711x_addrs);
2256
2257 if (dev->board.decoder == EM28XX_TVP5150)
2258 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2259 "tvp5150", 0, tvp5150_addrs);
2260
2261 if (dev->board.adecoder == EM28XX_TVAUDIO)
2262 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2263 "tvaudio", dev->board.tvaudio_addr, NULL);
2264
2265 /* Initialize tuner and camera */
2266
2267 if (dev->board.tuner_type != TUNER_ABSENT) {
2268 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2269
2270 if (dev->board.radio.type)
2271 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2272 "tuner", dev->board.radio_addr, NULL);
2273
2274 if (has_demod)
2275 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2276 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2277 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2278 if (dev->tuner_addr == 0) {
2279 enum v4l2_i2c_tuner_type type =
2280 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2281 struct v4l2_subdev *sd;
2282
2283 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2284 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2285 0, v4l2_i2c_tuner_addrs(type));
2286
2287 if (sd)
2288 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2289 } else {
2290 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2291 "tuner", dev->tuner_addr, NULL);
2292 }
2293 }
2294
2295 em28xx_tuner_setup(dev);
2296 em28xx_init_camera(dev);
2297
2298 /* Configure audio */
2299 ret = em28xx_audio_setup(dev);
2300 if (ret < 0) {
2301 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2302 __func__, ret);
2303 goto unregister_dev;
2304 }
2305 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
2306 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2307 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
2308 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2309 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
2310 } else {
2311 /* install the em28xx notify callback */
2312 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
2313 em28xx_ctrl_notify, dev);
2314 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
2315 em28xx_ctrl_notify, dev);
2316 }
2317
2318 /* wake i2c devices */
2319 em28xx_wake_i2c(dev);
2320
2321 /* init video dma queues */
2322 INIT_LIST_HEAD(&dev->vidq.active);
2323 INIT_LIST_HEAD(&dev->vbiq.active);
2324
2325 if (dev->board.has_msp34xx) {
2326 /* Send a reset to other chips via gpio */
2327 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
2328 if (ret < 0) {
2329 em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
2330 __func__, ret);
2331 goto unregister_dev;
2332 }
2333 msleep(3);
2334
2335 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
2336 if (ret < 0) {
2337 em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
2338 __func__, ret);
2339 goto unregister_dev;
2340 }
2341 msleep(3);
2342 }
2343
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002344 /* set default norm */
Hans Verkuild8c95c02012-09-07 07:31:54 -03002345 dev->norm = V4L2_STD_PAL;
Hans Verkuild5906dd2010-09-26 07:45:15 -03002346 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002347 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002348
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002349 /* Analog specific initialization */
2350 dev->format = &format[0];
Sascha Sommer1020d132012-01-08 16:54:28 -03002351
2352 maxw = norm_maxw(dev);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002353 /* MaxPacketSize for em2800 is too small to capture at full resolution
2354 * use half of maxw as the scaler can only scale to 50% */
2355 if (dev->board.is_em2800)
2356 maxw /= 2;
Sascha Sommer1020d132012-01-08 16:54:28 -03002357
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002358 em28xx_set_video_format(dev, format[0].fourcc,
Sascha Sommer1020d132012-01-08 16:54:28 -03002359 maxw, norm_maxh(dev));
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002360
Ezequiel García96371fc2012-03-23 18:09:34 -03002361 video_mux(dev, 0);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002362
2363 /* Audio defaults */
2364 dev->mute = 1;
2365 dev->volume = 0x1f;
2366
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002367/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002368 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2369 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2370 (EM28XX_XCLK_AUDIO_UNMUTE | val));
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002371
2372 em28xx_set_outfmt(dev);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002373 em28xx_compression_disable(dev);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002374
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002375 /* Add image controls */
2376 /* NOTE: at this point, the subdevices are already registered, so bridge
2377 * controls are only added/enabled when no subdevice provides them */
2378 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_CONTRAST))
2379 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2380 V4L2_CID_CONTRAST,
2381 0, 0x1f, 1, CONTRAST_DEFAULT);
2382 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BRIGHTNESS))
2383 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2384 V4L2_CID_BRIGHTNESS,
2385 -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT);
2386 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SATURATION))
2387 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2388 V4L2_CID_SATURATION,
2389 0, 0x1f, 1, SATURATION_DEFAULT);
2390 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BLUE_BALANCE))
2391 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2392 V4L2_CID_BLUE_BALANCE,
2393 -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT);
2394 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RED_BALANCE))
2395 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2396 V4L2_CID_RED_BALANCE,
2397 -0x30, 0x30, 1, RED_BALANCE_DEFAULT);
2398 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SHARPNESS))
2399 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2400 V4L2_CID_SHARPNESS,
2401 0, 0x0f, 1, SHARPNESS_DEFAULT);
2402
2403 /* Reset image controls */
2404 em28xx_colorlevels_set_default(dev);
2405 v4l2_ctrl_handler_setup(&dev->ctrl_handler);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002406 ret = dev->ctrl_handler.error;
2407 if (ret)
2408 goto unregister_dev;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002409
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002410 /* allocate and fill video video_device struct */
2411 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
2412 if (!dev->vdev) {
2413 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002414 ret = -ENODEV;
2415 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002416 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002417 dev->vdev->queue = &dev->vb_vidq;
2418 dev->vdev->queue->lock = &dev->vb_queue_lock;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002419
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002420 /* disable inapplicable ioctls */
2421 if (dev->board.is_webcam) {
2422 v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD);
2423 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD);
2424 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD);
Frank Schaefer3bc85cc2013-02-07 13:39:12 -03002425 } else {
2426 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002427 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002428 if (dev->tuner_type == TUNER_ABSENT) {
2429 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER);
2430 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_TUNER);
2431 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY);
2432 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY);
2433 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002434 if (!dev->audio_mode.has_audio) {
2435 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_AUDIO);
2436 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_AUDIO);
2437 }
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002438
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002439 /* register v4l2 video video_device */
2440 ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
2441 video_nr[dev->devno]);
2442 if (ret) {
2443 em28xx_errdev("unable to register video device (error=%i).\n",
2444 ret);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002445 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002446 }
2447
2448 /* Allocate and fill vbi video_device struct */
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002449 if (em28xx_vbi_supported(dev) == 1) {
2450 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
2451 "vbi");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002452
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002453 dev->vbi_dev->queue = &dev->vb_vbiq;
2454 dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock;
2455
Frank Schaefer66df67b2013-02-07 13:39:10 -03002456 /* disable inapplicable ioctls */
Frank Schaefer83c8bcc2013-02-07 13:39:13 -03002457 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002458 if (dev->tuner_type == TUNER_ABSENT) {
2459 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER);
2460 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER);
2461 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY);
2462 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY);
2463 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002464 if (!dev->audio_mode.has_audio) {
2465 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_AUDIO);
2466 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_AUDIO);
2467 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002468
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002469 /* register v4l2 vbi video_device */
2470 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
2471 vbi_nr[dev->devno]);
2472 if (ret < 0) {
2473 em28xx_errdev("unable to register vbi device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002474 goto unregister_dev;
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002475 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002476 }
2477
2478 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002479 dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
2480 "radio");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002481 if (!dev->radio_dev) {
2482 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002483 ret = -ENODEV;
2484 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002485 }
2486 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
2487 radio_nr[dev->devno]);
2488 if (ret < 0) {
2489 em28xx_errdev("can't register radio device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002490 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002491 }
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002492 em28xx_info("Registered radio device as %s\n",
2493 video_device_node_name(dev->radio_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002494 }
2495
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002496 em28xx_info("V4L2 video device registered as %s\n",
2497 video_device_node_name(dev->vdev));
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002498
2499 if (dev->vbi_dev)
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002500 em28xx_info("V4L2 VBI device registered as %s\n",
2501 video_device_node_name(dev->vbi_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002502
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002503 /* Save some power by putting tuner to sleep */
2504 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2505
2506 /* initialize videobuf2 stuff */
2507 em28xx_vb2_setup(dev);
2508
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002509 em28xx_info("V4L2 extension successfully initialized\n");
2510
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002511 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002512 return 0;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002513
2514unregister_dev:
2515 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2516 v4l2_device_unregister(&dev->v4l2_dev);
2517err:
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002518 mutex_unlock(&dev->lock);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002519 return ret;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002520}
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002521
2522static struct em28xx_ops v4l2_ops = {
2523 .id = EM28XX_V4L2,
2524 .name = "Em28xx v4l2 Extension",
2525 .init = em28xx_v4l2_init,
2526 .fini = em28xx_v4l2_fini,
2527};
2528
2529static int __init em28xx_video_register(void)
2530{
2531 return em28xx_register_extension(&v4l2_ops);
2532}
2533
2534static void __exit em28xx_video_unregister(void)
2535{
2536 em28xx_unregister_extension(&v4l2_ops);
2537}
2538
2539module_init(em28xx_video_register);
2540module_exit(em28xx_video_unregister);