blob: 0856e5d367b6d9a7c495dfd9223eb7acf527ed05 [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>
Frank Schaefer25dd1652014-01-12 13:24:23 -030045#include <media/v4l2-clk.h>
Hans Verkuil2474ed42006-03-19 12:35:57 -030046#include <media/msp3400.h>
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -030047#include <media/tuner.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080048
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -080049#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
50 "Markus Rechberger <mrechberger@gmail.com>, " \
Mauro Carvalho Chehab2e7c6dc2006-04-03 07:53:40 -030051 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
Mauro Carvalho Chehabf7abcd32005-11-08 21:38:25 -080052 "Sascha Sommer <saschasommer@freenet.de>"
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080053
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -030054static unsigned int isoc_debug;
55module_param(isoc_debug, int, 0644);
56MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
57
58static unsigned int disable_vbi;
59module_param(disable_vbi, int, 0644);
60MODULE_PARM_DESC(disable_vbi, "disable vbi support");
61
62static int alt;
63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
65
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -080066#define em28xx_videodbg(fmt, arg...) do {\
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -080067 if (video_debug) \
68 printk(KERN_INFO "%s %s :"fmt, \
Harvey Harrisond80e1342008-04-08 23:20:00 -030069 dev->name, __func__ , ##arg); } while (0)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080070
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -030071#define em28xx_isocdbg(fmt, arg...) \
72do {\
73 if (isoc_debug) { \
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -030074 printk(KERN_INFO "%s %s :"fmt, \
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -030075 dev->name, __func__ , ##arg); \
76 } \
77 } while (0)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -030078
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080079MODULE_AUTHOR(DRIVER_AUTHOR);
Mauro Carvalho Chehabd8992b02013-12-27 11:14:59 -030080MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080081MODULE_LICENSE("GPL");
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -030082MODULE_VERSION(EM28XX_VERSION);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080083
Frank Schaefere507e0e2013-03-26 13:38:38 -030084
85#define EM25XX_FRMDATAHDR_BYTE1 0x02
86#define EM25XX_FRMDATAHDR_BYTE2_STILL_IMAGE 0x20
87#define EM25XX_FRMDATAHDR_BYTE2_FRAME_END 0x02
88#define EM25XX_FRMDATAHDR_BYTE2_FRAME_ID 0x01
89#define EM25XX_FRMDATAHDR_BYTE2_MASK (EM25XX_FRMDATAHDR_BYTE2_STILL_IMAGE | \
90 EM25XX_FRMDATAHDR_BYTE2_FRAME_END | \
91 EM25XX_FRMDATAHDR_BYTE2_FRAME_ID)
92
93
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -030094static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
95static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
96static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -030097
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -020098module_param_array(video_nr, int, NULL, 0444);
99module_param_array(vbi_nr, int, NULL, 0444);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -0300100module_param_array(radio_nr, int, NULL, 0444);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -0300101MODULE_PARM_DESC(video_nr, "video device numbers");
102MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
103MODULE_PARM_DESC(radio_nr, "radio device numbers");
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800104
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300105static unsigned int video_debug;
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -0300106module_param(video_debug, int, 0644);
107MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800108
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300109/* supported video standards */
110static struct em28xx_fmt format[] = {
111 {
Mauro Carvalho Chehab58fc1ce2009-07-03 02:54:18 -0300112 .name = "16 bpp YUY2, 4:2:2, packed",
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300113 .fourcc = V4L2_PIX_FMT_YUYV,
114 .depth = 16,
Devin Heitmueller3fbf9302008-12-29 23:34:37 -0300115 .reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
Mauro Carvalho Chehab43cb9fe2009-06-30 08:36:17 -0300116 }, {
Mauro Carvalho Chehab58fc1ce2009-07-03 02:54:18 -0300117 .name = "16 bpp RGB 565, LE",
Mauro Carvalho Chehab43cb9fe2009-06-30 08:36:17 -0300118 .fourcc = V4L2_PIX_FMT_RGB565,
119 .depth = 16,
Mauro Carvalho Chehab58fc1ce2009-07-03 02:54:18 -0300120 .reg = EM28XX_OUTFMT_RGB_16_656,
121 }, {
122 .name = "8 bpp Bayer BGBG..GRGR",
123 .fourcc = V4L2_PIX_FMT_SBGGR8,
124 .depth = 8,
125 .reg = EM28XX_OUTFMT_RGB_8_BGBG,
126 }, {
127 .name = "8 bpp Bayer GRGR..BGBG",
128 .fourcc = V4L2_PIX_FMT_SGRBG8,
129 .depth = 8,
130 .reg = EM28XX_OUTFMT_RGB_8_GRGR,
131 }, {
132 .name = "8 bpp Bayer GBGB..RGRG",
133 .fourcc = V4L2_PIX_FMT_SGBRG8,
134 .depth = 8,
135 .reg = EM28XX_OUTFMT_RGB_8_GBGB,
136 }, {
137 .name = "12 bpp YUV411",
138 .fourcc = V4L2_PIX_FMT_YUV411P,
139 .depth = 12,
140 .reg = EM28XX_OUTFMT_YUV411,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300141 },
142};
143
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300144static int em28xx_vbi_supported(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300145{
146 /* Modprobe option to manually disable */
147 if (disable_vbi == 1)
148 return 0;
149
150 if (dev->board.is_webcam)
151 return 0;
152
153 /* FIXME: check subdevices for VBI support */
154
155 if (dev->chip_id == CHIP_ID_EM2860 ||
156 dev->chip_id == CHIP_ID_EM2883)
157 return 1;
158
159 /* Version of em28xx that does not support VBI */
160 return 0;
161}
162
163/*
164 * em28xx_wake_i2c()
165 * configure i2c attached devices
166 */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300167static void em28xx_wake_i2c(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300168{
169 v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
170 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
171 INPUT(dev->ctl_input)->vmux, 0, 0);
172 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
173}
174
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300175static int em28xx_colorlevels_set_default(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300176{
177 em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT);
178 em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT);
179 em28xx_write_reg(dev, EM28XX_R22_UVGAIN, SATURATION_DEFAULT);
180 em28xx_write_reg(dev, EM28XX_R23_UOFFSET, BLUE_BALANCE_DEFAULT);
181 em28xx_write_reg(dev, EM28XX_R24_VOFFSET, RED_BALANCE_DEFAULT);
182 em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, SHARPNESS_DEFAULT);
183
184 em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
185 em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
186 em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
187 em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
188 em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
189 em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
190 return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
191}
192
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300193static int em28xx_set_outfmt(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300194{
195 int ret;
196 u8 fmt, vinctrl;
197
198 fmt = dev->format->reg;
199 if (!dev->is_em25xx)
200 fmt |= 0x20;
201 /*
202 * NOTE: it's not clear if this is really needed !
203 * The datasheets say bit 5 is a reserved bit and devices seem to work
204 * fine without it. But the Windows driver sets it for em2710/50+em28xx
205 * devices and we've always been setting it, too.
206 *
207 * em2765 (em25xx, em276x/7x/8x) devices do NOT work with this bit set,
208 * it's likely used for an additional (compressed ?) format there.
209 */
210 ret = em28xx_write_reg(dev, EM28XX_R27_OUTFMT, fmt);
211 if (ret < 0)
212 return ret;
213
214 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
215 if (ret < 0)
216 return ret;
217
218 vinctrl = dev->vinctl;
219 if (em28xx_vbi_supported(dev) == 1) {
220 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
221 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
222 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
223 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
224 if (dev->norm & V4L2_STD_525_60) {
225 /* NTSC */
226 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
227 } else if (dev->norm & V4L2_STD_625_50) {
228 /* PAL */
229 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
230 }
231 }
232
233 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
234}
235
236static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
237 u8 ymin, u8 ymax)
238{
239 em28xx_videodbg("em28xx Scale: (%d,%d)-(%d,%d)\n",
240 xmin, ymin, xmax, ymax);
241
242 em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1);
243 em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1);
244 em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1);
245 return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1);
246}
247
248static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
249 u16 width, u16 height)
250{
251 u8 cwidth = width >> 2;
252 u8 cheight = height >> 2;
253 u8 overflow = (height >> 9 & 0x02) | (width >> 10 & 0x01);
254 /* NOTE: size limit: 2047x1023 = 2MPix */
255
256 em28xx_videodbg("capture area set to (%d,%d): %dx%d\n",
257 hstart, vstart,
258 ((overflow & 2) << 9 | cwidth << 2),
259 ((overflow & 1) << 10 | cheight << 2));
260
261 em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1);
262 em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1);
263 em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1);
264 em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1);
265 em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1);
266
267 /* FIXME: function/meaning of these registers ? */
268 /* FIXME: align width+height to multiples of 4 ?! */
269 if (dev->is_em25xx) {
270 em28xx_write_reg(dev, 0x34, width >> 4);
271 em28xx_write_reg(dev, 0x35, height >> 4);
272 }
273}
274
275static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
276{
277 u8 mode;
278 /* the em2800 scaler only supports scaling down to 50% */
279
280 if (dev->board.is_em2800) {
281 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
282 } else {
283 u8 buf[2];
284
285 buf[0] = h;
286 buf[1] = h >> 8;
287 em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2);
288
289 buf[0] = v;
290 buf[1] = v >> 8;
291 em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
292 /* it seems that both H and V scalers must be active
293 to work correctly */
294 mode = (h || v) ? 0x30 : 0x00;
295 }
296 return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
297}
298
299/* FIXME: this only function read values from dev */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300300static int em28xx_resolution_set(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300301{
302 int width, height;
303 width = norm_maxw(dev);
304 height = norm_maxh(dev);
305
306 /* Properly setup VBI */
307 dev->vbi_width = 720;
308 if (dev->norm & V4L2_STD_525_60)
309 dev->vbi_height = 12;
310 else
311 dev->vbi_height = 18;
312
313 em28xx_set_outfmt(dev);
314
315 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
316
317 /* If we don't set the start position to 2 in VBI mode, we end up
318 with line 20/21 being YUYV encoded instead of being in 8-bit
319 greyscale. The core of the issue is that line 21 (and line 23 for
320 PAL WSS) are inside of active video region, and as a result they
321 get the pixelformatting associated with that area. So by cropping
322 it out, we end up with the same format as the rest of the VBI
323 region */
324 if (em28xx_vbi_supported(dev) == 1)
325 em28xx_capture_area_set(dev, 0, 2, width, height);
326 else
327 em28xx_capture_area_set(dev, 0, 0, width, height);
328
329 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
330}
331
332/* Set USB alternate setting for analog video */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300333static int em28xx_set_alternate(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300334{
335 int errCode;
336 int i;
337 unsigned int min_pkt_size = dev->width * 2 + 4;
338
339 /* NOTE: for isoc transfers, only alt settings > 0 are allowed
340 bulk transfers seem to work only with alt=0 ! */
341 dev->alt = 0;
342 if ((alt > 0) && (alt < dev->num_alt)) {
343 em28xx_videodbg("alternate forced to %d\n", dev->alt);
344 dev->alt = alt;
345 goto set_alt;
346 }
347 if (dev->analog_xfer_bulk)
348 goto set_alt;
349
350 /* When image size is bigger than a certain value,
351 the frame size should be increased, otherwise, only
352 green screen will be received.
353 */
354 if (dev->width * 2 * dev->height > 720 * 240 * 2)
355 min_pkt_size *= 2;
356
357 for (i = 0; i < dev->num_alt; i++) {
358 /* stop when the selected alt setting offers enough bandwidth */
359 if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) {
360 dev->alt = i;
361 break;
362 /* otherwise make sure that we end up with the maximum bandwidth
363 because the min_pkt_size equation might be wrong...
364 */
365 } else if (dev->alt_max_pkt_size_isoc[i] >
366 dev->alt_max_pkt_size_isoc[dev->alt])
367 dev->alt = i;
368 }
369
370set_alt:
371 /* NOTE: for bulk transfers, we need to call usb_set_interface()
372 * even if the previous settings were the same. Otherwise streaming
373 * fails with all urbs having status = -EOVERFLOW ! */
374 if (dev->analog_xfer_bulk) {
375 dev->max_pkt_size = 512; /* USB 2.0 spec */
376 dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
377 } else { /* isoc */
378 em28xx_videodbg("minimum isoc packet size: %u (alt=%d)\n",
379 min_pkt_size, dev->alt);
380 dev->max_pkt_size =
381 dev->alt_max_pkt_size_isoc[dev->alt];
382 dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS;
383 }
384 em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n",
385 dev->alt, dev->max_pkt_size);
Frank Schaefer961717b2014-01-13 19:02:06 -0300386 errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300387 if (errCode < 0) {
388 em28xx_errdev("cannot change alternate number to %d (error=%i)\n",
389 dev->alt, errCode);
390 return errCode;
391 }
392 return 0;
393}
394
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300395/* ------------------------------------------------------------------
396 DMA and thread functions
397 ------------------------------------------------------------------*/
398
399/*
Frank Schaefer948a49a2012-12-08 11:31:25 -0300400 * Finish the current buffer
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300401 */
Frank Schaefer948a49a2012-12-08 11:31:25 -0300402static inline void finish_buffer(struct em28xx *dev,
403 struct em28xx_buffer *buf)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300404{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300405 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field);
406
407 buf->vb.v4l2_buf.sequence = dev->field_count++;
408 buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
409 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
410
411 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300412}
413
414/*
Frank Schaefer36016a32012-12-08 11:31:32 -0300415 * Copy picture data from USB buffer to videobuf buffer
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300416 */
417static void em28xx_copy_video(struct em28xx *dev,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300418 struct em28xx_buffer *buf,
Frank Schaefer36016a32012-12-08 11:31:32 -0300419 unsigned char *usb_buf,
Frank Schaefer4078d622012-12-08 11:31:29 -0300420 unsigned long len)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300421{
422 void *fieldstart, *startwrite, *startread;
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300423 int linesdone, currlinedone, offset, lencopy, remain;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300424 int bytesperline = dev->width << 1;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300425
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300426 if (buf->pos + len > buf->length)
427 len = buf->length - buf->pos;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300428
Frank Schaefer36016a32012-12-08 11:31:32 -0300429 startread = usb_buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300430 remain = len;
431
Frank Schaeferc02ec712012-11-08 14:11:33 -0300432 if (dev->progressive || buf->top_field)
Frank Schaefer36016a32012-12-08 11:31:32 -0300433 fieldstart = buf->vb_buf;
Frank Schaeferc02ec712012-11-08 14:11:33 -0300434 else /* interlaced mode, even nr. of lines */
Frank Schaefer36016a32012-12-08 11:31:32 -0300435 fieldstart = buf->vb_buf + bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300436
Frank Schaefer87325332012-12-08 11:31:27 -0300437 linesdone = buf->pos / bytesperline;
438 currlinedone = buf->pos % bytesperline;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -0300439
440 if (dev->progressive)
441 offset = linesdone * bytesperline + currlinedone;
442 else
443 offset = linesdone * bytesperline * 2 + currlinedone;
444
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300445 startwrite = fieldstart + offset;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300446 lencopy = bytesperline - currlinedone;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300447 lencopy = lencopy > remain ? remain : lencopy;
448
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300449 if ((char *)startwrite + lencopy > (char *)buf->vb_buf + buf->length) {
Mauro Carvalho Chehabea8df7e2008-04-13 14:39:29 -0300450 em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
Frank Schaefer36016a32012-12-08 11:31:32 -0300451 ((char *)startwrite + lencopy) -
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300452 ((char *)buf->vb_buf + buf->length));
453 remain = (char *)buf->vb_buf + buf->length -
Frank Schaefer36016a32012-12-08 11:31:32 -0300454 (char *)startwrite;
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -0300455 lencopy = remain;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300456 }
Aidan Thorntone0fadfd342008-04-13 14:56:02 -0300457 if (lencopy <= 0)
458 return;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300459 memcpy(startwrite, startread, lencopy);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300460
461 remain -= lencopy;
462
463 while (remain > 0) {
Frank Schaeferc02ec712012-11-08 14:11:33 -0300464 if (dev->progressive)
465 startwrite += lencopy;
466 else
467 startwrite += lencopy + bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300468 startread += lencopy;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300469 if (bytesperline > remain)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300470 lencopy = remain;
471 else
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300472 lencopy = bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300473
Frank Schaefer36016a32012-12-08 11:31:32 -0300474 if ((char *)startwrite + lencopy > (char *)buf->vb_buf +
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300475 buf->length) {
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -0300476 em28xx_isocdbg("Overflow of %zi bytes past buffer end"
477 "(2)\n",
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300478 ((char *)startwrite + lencopy) -
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300479 ((char *)buf->vb_buf + buf->length));
480 lencopy = remain = (char *)buf->vb_buf + buf->length -
481 (char *)startwrite;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300482 }
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300483 if (lencopy <= 0)
484 break;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300485
486 memcpy(startwrite, startread, lencopy);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300487
488 remain -= lencopy;
489 }
490
Frank Schaefer87325332012-12-08 11:31:27 -0300491 buf->pos += len;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300492}
493
Frank Schaefer36016a32012-12-08 11:31:32 -0300494/*
495 * Copy VBI data from USB buffer to videobuf buffer
496 */
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300497static void em28xx_copy_vbi(struct em28xx *dev,
Frank Schaefer87325332012-12-08 11:31:27 -0300498 struct em28xx_buffer *buf,
Frank Schaefer36016a32012-12-08 11:31:32 -0300499 unsigned char *usb_buf,
Frank Schaefer4078d622012-12-08 11:31:29 -0300500 unsigned long len)
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300501{
Frank Schaefer36016a32012-12-08 11:31:32 -0300502 unsigned int offset;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300503
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300504 if (buf->pos + len > buf->length)
505 len = buf->length - buf->pos;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300506
Frank Schaefer87325332012-12-08 11:31:27 -0300507 offset = buf->pos;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300508 /* Make sure the bottom field populates the second half of the frame */
Frank Schaefer36016a32012-12-08 11:31:32 -0300509 if (buf->top_field == 0)
510 offset += dev->vbi_width * dev->vbi_height;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300511
Frank Schaefer36016a32012-12-08 11:31:32 -0300512 memcpy(buf->vb_buf + offset, usb_buf, len);
Frank Schaefer87325332012-12-08 11:31:27 -0300513 buf->pos += len;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300514}
515
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300516static inline void print_err_status(struct em28xx *dev,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300517 int packet, int status)
518{
519 char *errmsg = "Unknown";
520
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300521 switch (status) {
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300522 case -ENOENT:
523 errmsg = "unlinked synchronuously";
524 break;
525 case -ECONNRESET:
526 errmsg = "unlinked asynchronuously";
527 break;
528 case -ENOSR:
529 errmsg = "Buffer error (overrun)";
530 break;
531 case -EPIPE:
532 errmsg = "Stalled (device not responding)";
533 break;
534 case -EOVERFLOW:
535 errmsg = "Babble (bad cable?)";
536 break;
537 case -EPROTO:
538 errmsg = "Bit-stuff error (bad cable?)";
539 break;
540 case -EILSEQ:
541 errmsg = "CRC/Timeout (could be anything)";
542 break;
543 case -ETIME:
544 errmsg = "Device does not respond";
545 break;
546 }
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300547 if (packet < 0) {
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300548 em28xx_isocdbg("URB status %d [%s].\n", status, errmsg);
549 } else {
550 em28xx_isocdbg("URB packet %d, status %d [%s].\n",
551 packet, status, errmsg);
552 }
553}
554
555/*
Frank Schaefer24a6d842012-12-08 11:31:24 -0300556 * get the next available buffer from dma queue
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300557 */
Frank Schaefer24a6d842012-12-08 11:31:24 -0300558static inline struct em28xx_buffer *get_next_buf(struct em28xx *dev,
559 struct em28xx_dmaqueue *dma_q)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300560{
Frank Schaefer24a6d842012-12-08 11:31:24 -0300561 struct em28xx_buffer *buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300562
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300563 if (list_empty(&dma_q->active)) {
564 em28xx_isocdbg("No active queue to serve\n");
Frank Schaefer24a6d842012-12-08 11:31:24 -0300565 return NULL;
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300566 }
567
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300568 /* Get the next buffer */
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300569 buf = list_entry(dma_q->active.next, struct em28xx_buffer, list);
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300570 /* Cleans up buffer - Useful for testing for frame/URB loss */
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300571 list_del(&buf->list);
Frank Schaefer87325332012-12-08 11:31:27 -0300572 buf->pos = 0;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300573 buf->vb_buf = buf->mem;
Mauro Carvalho Chehabcb784722008-04-13 15:06:52 -0300574
Frank Schaefer24a6d842012-12-08 11:31:24 -0300575 return buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300576}
577
Frank Schaefere04c00d2012-12-08 11:31:30 -0300578/*
579 * Finish the current buffer if completed and prepare for the next field
580 */
581static struct em28xx_buffer *
582finish_field_prepare_next(struct em28xx *dev,
583 struct em28xx_buffer *buf,
584 struct em28xx_dmaqueue *dma_q)
585{
586 if (dev->progressive || dev->top_field) { /* Brand new frame */
587 if (buf != NULL)
588 finish_buffer(dev, buf);
589 buf = get_next_buf(dev, dma_q);
590 }
591 if (buf != NULL) {
592 buf->top_field = dev->top_field;
593 buf->pos = 0;
594 }
595
596 return buf;
597}
598
Frank Schaefer227b7c92012-12-08 11:31:31 -0300599/*
600 * Process data packet according to the em2710/em2750/em28xx frame data format
601 */
602static inline void process_frame_data_em28xx(struct em28xx *dev,
603 unsigned char *data_pkt,
604 unsigned int data_len)
605{
606 struct em28xx_buffer *buf = dev->usb_ctl.vid_buf;
607 struct em28xx_buffer *vbi_buf = dev->usb_ctl.vbi_buf;
608 struct em28xx_dmaqueue *dma_q = &dev->vidq;
609 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
610
611 /* capture type 0 = vbi start
612 capture type 1 = vbi in progress
613 capture type 2 = video start
614 capture type 3 = video in progress */
615 if (data_len >= 4) {
616 /* NOTE: Headers are always 4 bytes and
617 * never split across packets */
618 if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 &&
619 data_pkt[2] == 0x88 && data_pkt[3] == 0x88) {
620 /* Continuation */
621 data_pkt += 4;
622 data_len -= 4;
623 } else if (data_pkt[0] == 0x33 && data_pkt[1] == 0x95) {
624 /* Field start (VBI mode) */
625 dev->capture_type = 0;
626 dev->vbi_read = 0;
627 em28xx_isocdbg("VBI START HEADER !!!\n");
628 dev->top_field = !(data_pkt[2] & 1);
629 data_pkt += 4;
630 data_len -= 4;
631 } else if (data_pkt[0] == 0x22 && data_pkt[1] == 0x5a) {
632 /* Field start (VBI disabled) */
633 dev->capture_type = 2;
634 em28xx_isocdbg("VIDEO START HEADER !!!\n");
635 dev->top_field = !(data_pkt[2] & 1);
636 data_pkt += 4;
637 data_len -= 4;
638 }
639 }
640 /* NOTE: With bulk transfers, intermediate data packets
641 * have no continuation header */
642
643 if (dev->capture_type == 0) {
644 vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q);
645 dev->usb_ctl.vbi_buf = vbi_buf;
646 dev->capture_type = 1;
647 }
648
649 if (dev->capture_type == 1) {
650 int vbi_size = dev->vbi_width * dev->vbi_height;
651 int vbi_data_len = ((dev->vbi_read + data_len) > vbi_size) ?
652 (vbi_size - dev->vbi_read) : data_len;
653
654 /* Copy VBI data */
655 if (vbi_buf != NULL)
656 em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len);
657 dev->vbi_read += vbi_data_len;
658
659 if (vbi_data_len < data_len) {
660 /* Continue with copying video data */
661 dev->capture_type = 2;
662 data_pkt += vbi_data_len;
663 data_len -= vbi_data_len;
664 }
665 }
666
667 if (dev->capture_type == 2) {
668 buf = finish_field_prepare_next(dev, buf, dma_q);
669 dev->usb_ctl.vid_buf = buf;
670 dev->capture_type = 3;
671 }
672
673 if (dev->capture_type == 3 && buf != NULL && data_len > 0)
674 em28xx_copy_video(dev, buf, data_pkt, data_len);
675}
676
Frank Schaefere507e0e2013-03-26 13:38:38 -0300677/*
678 * Process data packet according to the em25xx/em276x/7x/8x frame data format
679 */
680static inline void process_frame_data_em25xx(struct em28xx *dev,
681 unsigned char *data_pkt,
682 unsigned int data_len)
683{
684 struct em28xx_buffer *buf = dev->usb_ctl.vid_buf;
685 struct em28xx_dmaqueue *dmaq = &dev->vidq;
686 bool frame_end = 0;
687
688 /* Check for header */
689 /* NOTE: at least with bulk transfers, only the first packet
690 * has a header and has always set the FRAME_END bit */
691 if (data_len >= 2) { /* em25xx header is only 2 bytes long */
692 if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) &&
693 ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) {
694 dev->top_field = !(data_pkt[1] &
695 EM25XX_FRMDATAHDR_BYTE2_FRAME_ID);
696 frame_end = data_pkt[1] &
697 EM25XX_FRMDATAHDR_BYTE2_FRAME_END;
698 data_pkt += 2;
699 data_len -= 2;
700 }
701
702 /* Finish field and prepare next (BULK only) */
703 if (dev->analog_xfer_bulk && frame_end) {
704 buf = finish_field_prepare_next(dev, buf, dmaq);
705 dev->usb_ctl.vid_buf = buf;
706 }
707 /* NOTE: in ISOC mode when a new frame starts and buf==NULL,
708 * we COULD already prepare a buffer here to avoid skipping the
709 * first frame.
710 */
711 }
712
713 /* Copy data */
714 if (buf != NULL && data_len > 0)
715 em28xx_copy_video(dev, buf, data_pkt, data_len);
716
717 /* Finish frame (ISOC only) => avoids lag of 1 frame */
718 if (!dev->analog_xfer_bulk && frame_end) {
719 buf = finish_field_prepare_next(dev, buf, dmaq);
720 dev->usb_ctl.vid_buf = buf;
721 }
722
723 /* NOTE: Tested with USB bulk transfers only !
724 * The wording in the datasheet suggests that isoc might work different.
725 * The current code assumes that with isoc transfers each packet has a
726 * header like with the other em28xx devices.
727 */
728 /* NOTE: Support for interlaced mode is pure theory. It has not been
729 * tested and it is unknown if these devices actually support it. */
730 /* NOTE: No VBI support yet (these chips likely do not support VBI). */
731}
732
Frank Schaefer960da932012-11-25 06:37:37 -0300733/* Processes and copies the URB data content (video and VBI data) */
Frank Schaefer0fa4a402012-11-08 14:11:45 -0300734static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300735{
Frank Schaefer227b7c92012-12-08 11:31:31 -0300736 int xfer_bulk, num_packets, i;
737 unsigned char *usb_data_pkt;
738 unsigned int usb_data_len;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300739
740 if (!dev)
741 return 0;
742
Frank Schaefer2665c292012-12-27 19:02:43 -0300743 if (dev->disconnected)
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300744 return 0;
745
Frank Schaefer1653cb0c2012-11-08 14:11:44 -0300746 if (urb->status < 0)
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300747 print_err_status(dev, -1, urb->status);
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300748
Frank Schaefer4601cc32012-11-08 14:11:46 -0300749 xfer_bulk = usb_pipebulk(urb->pipe);
750
Frank Schaefer4601cc32012-11-08 14:11:46 -0300751 if (xfer_bulk) /* bulk */
752 num_packets = 1;
753 else /* isoc */
754 num_packets = urb->number_of_packets;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300755
Frank Schaefer4601cc32012-11-08 14:11:46 -0300756 for (i = 0; i < num_packets; i++) {
757 if (xfer_bulk) { /* bulk */
Frank Schaefer227b7c92012-12-08 11:31:31 -0300758 usb_data_len = urb->actual_length;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300759
Frank Schaefer227b7c92012-12-08 11:31:31 -0300760 usb_data_pkt = urb->transfer_buffer;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300761 } else { /* isoc */
762 if (urb->iso_frame_desc[i].status < 0) {
763 print_err_status(dev, i,
764 urb->iso_frame_desc[i].status);
765 if (urb->iso_frame_desc[i].status != -EPROTO)
766 continue;
767 }
768
Frank Schaefer227b7c92012-12-08 11:31:31 -0300769 usb_data_len = urb->iso_frame_desc[i].actual_length;
770 if (usb_data_len > dev->max_pkt_size) {
Frank Schaefer4601cc32012-11-08 14:11:46 -0300771 em28xx_isocdbg("packet bigger than packet size");
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300772 continue;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300773 }
774
Frank Schaefer227b7c92012-12-08 11:31:31 -0300775 usb_data_pkt = urb->transfer_buffer +
776 urb->iso_frame_desc[i].offset;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300777 }
778
Frank Schaefer227b7c92012-12-08 11:31:31 -0300779 if (usb_data_len == 0) {
Frank Schaefer4601cc32012-11-08 14:11:46 -0300780 /* NOTE: happens very often with isoc transfers */
781 /* em28xx_usbdbg("packet %d is empty",i); - spammy */
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300782 continue;
783 }
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300784
Frank Schaefere507e0e2013-03-26 13:38:38 -0300785 if (dev->is_em25xx)
786 process_frame_data_em25xx(dev,
787 usb_data_pkt, usb_data_len);
788 else
789 process_frame_data_em28xx(dev,
790 usb_data_pkt, usb_data_len);
791
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300792 }
Frank Schaefer227b7c92012-12-08 11:31:31 -0300793 return 1;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300794}
795
796
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300797static int get_ressource(enum v4l2_buf_type f_type)
798{
799 switch (f_type) {
800 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
801 return EM28XX_RESOURCE_VIDEO;
802 case V4L2_BUF_TYPE_VBI_CAPTURE:
803 return EM28XX_RESOURCE_VBI;
804 default:
805 BUG();
806 return 0;
807 }
808}
809
810/* Usage lock check functions */
811static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type)
812{
813 int res_type = get_ressource(f_type);
814
815 /* is it free? */
816 if (dev->resources & res_type) {
817 /* no, someone else uses it */
818 return -EBUSY;
819 }
820
821 /* it's free, grab it */
822 dev->resources |= res_type;
823 em28xx_videodbg("res: get %d\n", res_type);
824 return 0;
825}
826
827static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type)
828{
829 int res_type = get_ressource(f_type);
830
831 dev->resources &= ~res_type;
832 em28xx_videodbg("res: put %d\n", res_type);
833}
834
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300835/* ------------------------------------------------------------------
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300836 Videobuf2 operations
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300837 ------------------------------------------------------------------*/
838
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300839static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
840 unsigned int *nbuffers, unsigned int *nplanes,
841 unsigned int sizes[], void *alloc_ctxs[])
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300842{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300843 struct em28xx *dev = vb2_get_drv_priv(vq);
844 unsigned long size;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300845
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300846 if (fmt)
847 size = fmt->fmt.pix.sizeimage;
848 else
849 size = (dev->width * dev->height * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300850
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300851 if (size == 0)
852 return -EINVAL;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300853
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300854 if (0 == *nbuffers)
855 *nbuffers = 32;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300856
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300857 *nplanes = 1;
858 sizes[0] = size;
Mauro Carvalho Chehabd2d9fbf2008-04-17 21:38:53 -0300859
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300860 return 0;
861}
862
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300863static int
864buffer_prepare(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300865{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300866 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
867 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
868 unsigned long size;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300869
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300870 em28xx_videodbg("%s, field=%d\n", __func__, vb->v4l2_buf.field);
Aidan Thornton3b5fa922008-04-13 15:09:36 -0300871
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300872 size = (dev->width * dev->height * dev->format->depth + 7) >> 3;
Aidan Thornton3b5fa922008-04-13 15:09:36 -0300873
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300874 if (vb2_plane_size(vb, 0) < size) {
875 em28xx_videodbg("%s data will not fit into plane (%lu < %lu)\n",
876 __func__, vb2_plane_size(vb, 0), size);
877 return -EINVAL;
878 }
879 vb2_set_plane_payload(&buf->vb, 0, size);
880
881 return 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300882}
883
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300884int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300885{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300886 struct em28xx *dev = vb2_get_drv_priv(vq);
887 struct v4l2_frequency f;
888 int rc = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300889
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300890 em28xx_videodbg("%s\n", __func__);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300891
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300892 /* Make sure streaming is not already in progress for this type
893 of filehandle (e.g. video, vbi) */
894 rc = res_get(dev, vq->type);
895 if (rc)
896 return rc;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300897
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300898 if (dev->streaming_users == 0) {
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300899 /* First active streaming user, so allocate all the URBs */
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300900
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300901 /* Allocate the USB bandwidth */
902 em28xx_set_alternate(dev);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300903
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300904 /* Needed, since GPIO might have disabled power of
905 some i2c device
906 */
907 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300908
Frank Schaefer0455eeb2012-11-25 06:37:34 -0300909 dev->capture_type = -1;
Frank Schaefer960da932012-11-25 06:37:37 -0300910 rc = em28xx_init_usb_xfer(dev, EM28XX_ANALOG_MODE,
911 dev->analog_xfer_bulk,
912 EM28XX_NUM_BUFS,
913 dev->max_pkt_size,
914 dev->packet_multiplier,
915 em28xx_urb_data_copy);
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300916 if (rc < 0)
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300917 return rc;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300918
919 /*
920 * djh: it's not clear whether this code is still needed. I'm
921 * leaving it in here for now entirely out of concern for
922 * backward compatibility (the old code did it)
923 */
924
925 /* Ask tuner to go to analog or radio mode */
926 memset(&f, 0, sizeof(f));
927 f.frequency = dev->ctl_freq;
928 if (vq->owner && vq->owner->vdev->vfl_type == VFL_TYPE_RADIO)
929 f.type = V4L2_TUNER_RADIO;
930 else
931 f.type = V4L2_TUNER_ANALOG_TV;
932 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300933 }
934
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300935 dev->streaming_users++;
936
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300937 return rc;
938}
939
Mauro Carvalho Chehab3a799c22013-01-05 01:27:21 -0200940static int em28xx_stop_streaming(struct vb2_queue *vq)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300941{
942 struct em28xx *dev = vb2_get_drv_priv(vq);
943 struct em28xx_dmaqueue *vidq = &dev->vidq;
944 unsigned long flags = 0;
945
946 em28xx_videodbg("%s\n", __func__);
947
948 res_free(dev, vq->type);
949
950 if (dev->streaming_users-- == 1) {
951 /* Last active user, so shutdown all the URBS */
952 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
953 }
954
955 spin_lock_irqsave(&dev->slock, flags);
956 while (!list_empty(&vidq->active)) {
957 struct em28xx_buffer *buf;
958 buf = list_entry(vidq->active.next, struct em28xx_buffer, list);
959 list_del(&buf->list);
960 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
961 }
962 dev->usb_ctl.vid_buf = NULL;
963 spin_unlock_irqrestore(&dev->slock, flags);
964
965 return 0;
966}
967
968int em28xx_stop_vbi_streaming(struct vb2_queue *vq)
969{
970 struct em28xx *dev = vb2_get_drv_priv(vq);
971 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
972 unsigned long flags = 0;
973
974 em28xx_videodbg("%s\n", __func__);
975
976 res_free(dev, vq->type);
977
978 if (dev->streaming_users-- == 1) {
979 /* Last active user, so shutdown all the URBS */
980 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
981 }
982
983 spin_lock_irqsave(&dev->slock, flags);
984 while (!list_empty(&vbiq->active)) {
985 struct em28xx_buffer *buf;
986 buf = list_entry(vbiq->active.next, struct em28xx_buffer, list);
987 list_del(&buf->list);
988 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
989 }
990 dev->usb_ctl.vbi_buf = NULL;
991 spin_unlock_irqrestore(&dev->slock, flags);
992
993 return 0;
994}
995
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300996static void
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300997buffer_queue(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300998{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300999 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
1000 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
1001 struct em28xx_dmaqueue *vidq = &dev->vidq;
1002 unsigned long flags = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001003
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001004 em28xx_videodbg("%s\n", __func__);
1005 buf->mem = vb2_plane_vaddr(vb, 0);
1006 buf->length = vb2_plane_size(vb, 0);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001007
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001008 spin_lock_irqsave(&dev->slock, flags);
1009 list_add_tail(&buf->list, &vidq->active);
1010 spin_unlock_irqrestore(&dev->slock, flags);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001011}
1012
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001013static struct vb2_ops em28xx_video_qops = {
1014 .queue_setup = queue_setup,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001015 .buf_prepare = buffer_prepare,
1016 .buf_queue = buffer_queue,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001017 .start_streaming = em28xx_start_analog_streaming,
1018 .stop_streaming = em28xx_stop_streaming,
1019 .wait_prepare = vb2_ops_wait_prepare,
1020 .wait_finish = vb2_ops_wait_finish,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001021};
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001022
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001023static int em28xx_vb2_setup(struct em28xx *dev)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001024{
1025 int rc;
1026 struct vb2_queue *q;
1027
1028 /* Setup Videobuf2 for Video capture */
1029 q = &dev->vb_vidq;
1030 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Mauro Carvalho Chehabef85cd92013-01-06 00:34:22 -02001031 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
Sakari Ailusade48682014-02-25 19:12:19 -03001032 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001033 q->drv_priv = dev;
1034 q->buf_struct_size = sizeof(struct em28xx_buffer);
1035 q->ops = &em28xx_video_qops;
1036 q->mem_ops = &vb2_vmalloc_memops;
1037
1038 rc = vb2_queue_init(q);
1039 if (rc < 0)
1040 return rc;
1041
1042 /* Setup Videobuf2 for VBI capture */
1043 q = &dev->vb_vbiq;
1044 q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1045 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR;
Sakari Ailusade48682014-02-25 19:12:19 -03001046 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001047 q->drv_priv = dev;
1048 q->buf_struct_size = sizeof(struct em28xx_buffer);
1049 q->ops = &em28xx_vbi_qops;
1050 q->mem_ops = &vb2_vmalloc_memops;
1051
1052 rc = vb2_queue_init(q);
1053 if (rc < 0)
1054 return rc;
1055
1056 return 0;
1057}
1058
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001059/********************* v4l2 interface **************************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001060
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001061static void video_mux(struct em28xx *dev, int index)
1062{
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001063 dev->ctl_input = index;
1064 dev->ctl_ainput = INPUT(index)->amux;
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001065 dev->ctl_aoutput = INPUT(index)->aout;
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001066
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001067 if (!dev->ctl_aoutput)
1068 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
1069
Hans Verkuil5325b422009-04-02 11:26:22 -03001070 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
1071 INPUT(index)->vmux, 0, 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001072
Mauro Carvalho Chehab505b6d02008-11-25 09:39:50 -03001073 if (dev->board.has_msp34xx) {
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001074 if (dev->i2s_speed) {
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001075 v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
1076 s_i2s_clock_freq, dev->i2s_speed);
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001077 }
Hans Verkuil2474ed42006-03-19 12:35:57 -03001078 /* Note: this is msp3400 specific */
Hans Verkuil5325b422009-04-02 11:26:22 -03001079 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1080 dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001081 }
Mauro Carvalho Chehab539c96d2008-01-05 09:53:54 -03001082
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001083 if (dev->board.adecoder != EM28XX_NOADECODER) {
Hans Verkuil5325b422009-04-02 11:26:22 -03001084 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1085 dev->ctl_ainput, dev->ctl_aoutput, 0);
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001086 }
1087
Mauro Carvalho Chehab00b87302008-02-06 18:34:13 -03001088 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001089}
1090
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001091static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001092{
Hans Verkuil081b9452012-09-07 05:43:59 -03001093 struct em28xx *dev = priv;
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001094
Hans Verkuil081b9452012-09-07 05:43:59 -03001095 /*
1096 * In the case of non-AC97 volume controls, we still need
1097 * to do some setups at em28xx, in order to mute/unmute
1098 * and to adjust audio volume. However, the value ranges
1099 * should be checked by the corresponding V4L subdriver.
1100 */
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001101 switch (ctrl->id) {
1102 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil081b9452012-09-07 05:43:59 -03001103 dev->mute = ctrl->val;
1104 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001105 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001106 case V4L2_CID_AUDIO_VOLUME:
Hans Verkuil081b9452012-09-07 05:43:59 -03001107 dev->volume = ctrl->val;
1108 em28xx_audio_analog_set(dev);
1109 break;
1110 }
1111}
1112
1113static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
1114{
1115 struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler);
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001116 int ret = -EINVAL;
Hans Verkuil081b9452012-09-07 05:43:59 -03001117
1118 switch (ctrl->id) {
1119 case V4L2_CID_AUDIO_MUTE:
1120 dev->mute = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001121 ret = em28xx_audio_analog_set(dev);
Hans Verkuil081b9452012-09-07 05:43:59 -03001122 break;
1123 case V4L2_CID_AUDIO_VOLUME:
1124 dev->volume = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001125 ret = em28xx_audio_analog_set(dev);
1126 break;
1127 case V4L2_CID_CONTRAST:
1128 ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val);
1129 break;
1130 case V4L2_CID_BRIGHTNESS:
1131 ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val);
1132 break;
1133 case V4L2_CID_SATURATION:
1134 ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val);
1135 break;
1136 case V4L2_CID_BLUE_BALANCE:
1137 ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val);
1138 break;
1139 case V4L2_CID_RED_BALANCE:
1140 ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val);
1141 break;
1142 case V4L2_CID_SHARPNESS:
1143 ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001144 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001145 }
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001146
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001147 return (ret < 0) ? ret : 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001148}
1149
Fengguang Wu8068eb82014-01-07 12:50:47 -03001150static const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
Hans Verkuil081b9452012-09-07 05:43:59 -03001151 .s_ctrl = em28xx_s_ctrl,
1152};
1153
Frank Schaefer6b09a212013-02-10 16:05:12 -03001154static void size_to_scale(struct em28xx *dev,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001155 unsigned int width, unsigned int height,
1156 unsigned int *hscale, unsigned int *vscale)
1157{
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001158 unsigned int maxw = norm_maxw(dev);
1159 unsigned int maxh = norm_maxh(dev);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001160
1161 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001162 if (*hscale > EM28XX_HVSCALE_MAX)
1163 *hscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001164
1165 *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001166 if (*vscale > EM28XX_HVSCALE_MAX)
1167 *vscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001168}
1169
Frank Schaeferb8374132013-02-10 16:05:13 -03001170static void scale_to_size(struct em28xx *dev,
1171 unsigned int hscale, unsigned int vscale,
1172 unsigned int *width, unsigned int *height)
1173{
1174 unsigned int maxw = norm_maxw(dev);
1175 unsigned int maxh = norm_maxh(dev);
1176
1177 *width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
1178 *height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
1179}
1180
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001181/* ------------------------------------------------------------------
1182 IOCTL vidioc handling
1183 ------------------------------------------------------------------*/
1184
Hans Verkuil78b526a2008-05-28 12:16:41 -03001185static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001186 struct v4l2_format *f)
1187{
1188 struct em28xx_fh *fh = priv;
1189 struct em28xx *dev = fh->dev;
1190
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001191 f->fmt.pix.width = dev->width;
1192 f->fmt.pix.height = dev->height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001193 f->fmt.pix.pixelformat = dev->format->fourcc;
1194 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -03001195 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001196 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1197
1198 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001199 if (dev->progressive)
1200 f->fmt.pix.field = V4L2_FIELD_NONE;
1201 else
1202 f->fmt.pix.field = dev->interlaced ?
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001203 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001204 return 0;
1205}
1206
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001207static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
1208{
1209 unsigned int i;
1210
1211 for (i = 0; i < ARRAY_SIZE(format); i++)
1212 if (format[i].fourcc == fourcc)
1213 return &format[i];
1214
1215 return NULL;
1216}
1217
Hans Verkuil78b526a2008-05-28 12:16:41 -03001218static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001219 struct v4l2_format *f)
1220{
1221 struct em28xx_fh *fh = priv;
1222 struct em28xx *dev = fh->dev;
Trent Piephoccb83402009-05-30 21:45:46 -03001223 unsigned int width = f->fmt.pix.width;
1224 unsigned int height = f->fmt.pix.height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001225 unsigned int maxw = norm_maxw(dev);
1226 unsigned int maxh = norm_maxh(dev);
1227 unsigned int hscale, vscale;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001228 struct em28xx_fmt *fmt;
1229
1230 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1231 if (!fmt) {
1232 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1233 f->fmt.pix.pixelformat);
1234 return -EINVAL;
1235 }
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001236
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001237 if (dev->board.is_em2800) {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001238 /* the em2800 can only scale down to 50% */
Trent Piephoccb83402009-05-30 21:45:46 -03001239 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1240 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001241 /*
1242 * MaxPacketSize for em2800 is too small to capture at full
1243 * resolution use half of maxw as the scaler can only scale
1244 * to 50%
1245 */
Sascha Sommer1020d132012-01-08 16:54:28 -03001246 if (width == maxw && height == maxh)
1247 width /= 2;
Trent Piephoccb83402009-05-30 21:45:46 -03001248 } else {
1249 /* width must even because of the YUYV format
1250 height must be even because of interlacing */
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001251 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1252 1, 0);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001253 }
1254
Frank Schaefer6b09a212013-02-10 16:05:12 -03001255 size_to_scale(dev, width, height, &hscale, &vscale);
Hans Verkuil46f85972013-03-30 05:31:42 -03001256 scale_to_size(dev, hscale, vscale, &width, &height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001257
1258 f->fmt.pix.width = width;
1259 f->fmt.pix.height = height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001260 f->fmt.pix.pixelformat = fmt->fourcc;
Hans Verkuile6066db2013-02-06 08:14:47 -03001261 f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001262 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001263 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001264 if (dev->progressive)
1265 f->fmt.pix.field = V4L2_FIELD_NONE;
1266 else
1267 f->fmt.pix.field = dev->interlaced ?
1268 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Alban Browaeys51dd4d72013-07-16 19:06:46 -03001269 f->fmt.pix.priv = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001270
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001271 return 0;
1272}
1273
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001274static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
1275 unsigned width, unsigned height)
1276{
1277 struct em28xx_fmt *fmt;
1278
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001279 fmt = format_by_fourcc(fourcc);
1280 if (!fmt)
1281 return -EINVAL;
1282
1283 dev->format = fmt;
1284 dev->width = width;
1285 dev->height = height;
1286
1287 /* set new image size */
Frank Schaefer6b09a212013-02-10 16:05:12 -03001288 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001289
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001290 em28xx_resolution_set(dev);
1291
1292 return 0;
1293}
1294
Hans Verkuil78b526a2008-05-28 12:16:41 -03001295static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001296 struct v4l2_format *f)
1297{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001298 struct em28xx *dev = video_drvdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001299
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001300 if (dev->streaming_users > 0)
1301 return -EBUSY;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001302
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001303 vidioc_try_fmt_vid_cap(file, priv, f);
1304
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001305 return em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001306 f->fmt.pix.width, f->fmt.pix.height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001307}
1308
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001309static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1310{
1311 struct em28xx_fh *fh = priv;
1312 struct em28xx *dev = fh->dev;
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001313
1314 *norm = dev->norm;
1315
1316 return 0;
1317}
1318
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001319static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
1320{
1321 struct em28xx_fh *fh = priv;
1322 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001323
1324 v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm);
1325
1326 return 0;
1327}
1328
Hans Verkuil314527a2013-03-15 06:10:40 -03001329static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001330{
1331 struct em28xx_fh *fh = priv;
1332 struct em28xx *dev = fh->dev;
1333 struct v4l2_format f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001334
Hans Verkuil314527a2013-03-15 06:10:40 -03001335 if (norm == dev->norm)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001336 return 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001337
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001338 if (dev->streaming_users > 0)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001339 return -EBUSY;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001340
Hans Verkuil314527a2013-03-15 06:10:40 -03001341 dev->norm = norm;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001342
1343 /* Adjusts width/height, if needed */
Hans Verkuild8c95c02012-09-07 07:31:54 -03001344 f.fmt.pix.width = 720;
Hans Verkuil314527a2013-03-15 06:10:40 -03001345 f.fmt.pix.height = (norm & V4L2_STD_525_60) ? 480 : 576;
Hans Verkuil78b526a2008-05-28 12:16:41 -03001346 vidioc_try_fmt_vid_cap(file, priv, &f);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001347
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001348 /* set new image size */
1349 dev->width = f.fmt.pix.width;
1350 dev->height = f.fmt.pix.height;
Frank Schaefer6b09a212013-02-10 16:05:12 -03001351 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001352
1353 em28xx_resolution_set(dev);
Hans Verkuilf41737e2009-04-01 03:52:39 -03001354 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001355
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001356 return 0;
1357}
1358
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001359static int vidioc_g_parm(struct file *file, void *priv,
1360 struct v4l2_streamparm *p)
1361{
1362 struct em28xx_fh *fh = priv;
1363 struct em28xx *dev = fh->dev;
1364 int rc = 0;
1365
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001366 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001367 if (dev->board.is_webcam)
1368 rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1369 video, g_parm, p);
1370 else
1371 v4l2_video_std_frame_period(dev->norm,
1372 &p->parm.capture.timeperframe);
1373
1374 return rc;
1375}
1376
1377static int vidioc_s_parm(struct file *file, void *priv,
1378 struct v4l2_streamparm *p)
1379{
1380 struct em28xx_fh *fh = priv;
1381 struct em28xx *dev = fh->dev;
1382
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001383 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001384 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
1385}
1386
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001387static const char *iname[] = {
1388 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
1389 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
1390 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
1391 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
1392 [EM28XX_VMUX_SVIDEO] = "S-Video",
1393 [EM28XX_VMUX_TELEVISION] = "Television",
1394 [EM28XX_VMUX_CABLE] = "Cable TV",
1395 [EM28XX_VMUX_DVB] = "DVB",
1396 [EM28XX_VMUX_DEBUG] = "for debug only",
1397};
1398
1399static int vidioc_enum_input(struct file *file, void *priv,
1400 struct v4l2_input *i)
1401{
1402 struct em28xx_fh *fh = priv;
1403 struct em28xx *dev = fh->dev;
1404 unsigned int n;
1405
1406 n = i->index;
1407 if (n >= MAX_EM28XX_INPUT)
1408 return -EINVAL;
1409 if (0 == INPUT(n)->type)
1410 return -EINVAL;
1411
1412 i->index = n;
1413 i->type = V4L2_INPUT_TYPE_CAMERA;
1414
1415 strcpy(i->name, iname[INPUT(n)->type]);
1416
1417 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
1418 (EM28XX_VMUX_CABLE == INPUT(n)->type))
1419 i->type = V4L2_INPUT_TYPE_TUNER;
1420
Mauro Carvalho Chehab7d497f82007-11-11 14:15:34 -03001421 i->std = dev->vdev->tvnorms;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001422 /* webcams do not have the STD API */
1423 if (dev->board.is_webcam)
1424 i->capabilities = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001425
1426 return 0;
1427}
1428
1429static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1430{
1431 struct em28xx_fh *fh = priv;
1432 struct em28xx *dev = fh->dev;
1433
1434 *i = dev->ctl_input;
1435
1436 return 0;
1437}
1438
1439static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1440{
1441 struct em28xx_fh *fh = priv;
1442 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001443
1444 if (i >= MAX_EM28XX_INPUT)
1445 return -EINVAL;
1446 if (0 == INPUT(i)->type)
1447 return -EINVAL;
1448
Ezequiel García96371fc2012-03-23 18:09:34 -03001449 video_mux(dev, i);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001450 return 0;
1451}
1452
1453static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1454{
1455 struct em28xx_fh *fh = priv;
1456 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001457
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001458 switch (a->index) {
1459 case EM28XX_AMUX_VIDEO:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001460 strcpy(a->name, "Television");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001461 break;
1462 case EM28XX_AMUX_LINE_IN:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001463 strcpy(a->name, "Line In");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001464 break;
1465 case EM28XX_AMUX_VIDEO2:
1466 strcpy(a->name, "Television alt");
1467 break;
1468 case EM28XX_AMUX_PHONE:
1469 strcpy(a->name, "Phone");
1470 break;
1471 case EM28XX_AMUX_MIC:
1472 strcpy(a->name, "Mic");
1473 break;
1474 case EM28XX_AMUX_CD:
1475 strcpy(a->name, "CD");
1476 break;
1477 case EM28XX_AMUX_AUX:
1478 strcpy(a->name, "Aux");
1479 break;
1480 case EM28XX_AMUX_PCM_OUT:
1481 strcpy(a->name, "PCM");
1482 break;
1483 default:
1484 return -EINVAL;
1485 }
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001486
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001487 a->index = dev->ctl_ainput;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001488 a->capability = V4L2_AUDCAP_STEREO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001489
1490 return 0;
1491}
1492
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001493static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001494{
1495 struct em28xx_fh *fh = priv;
1496 struct em28xx *dev = fh->dev;
1497
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03001498 if (a->index >= MAX_EM28XX_INPUT)
1499 return -EINVAL;
1500 if (0 == INPUT(a->index)->type)
1501 return -EINVAL;
1502
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001503 dev->ctl_ainput = INPUT(a->index)->amux;
1504 dev->ctl_aoutput = INPUT(a->index)->aout;
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001505
1506 if (!dev->ctl_aoutput)
1507 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001508
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001509 return 0;
1510}
1511
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001512static int vidioc_g_tuner(struct file *file, void *priv,
1513 struct v4l2_tuner *t)
1514{
1515 struct em28xx_fh *fh = priv;
1516 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001517
1518 if (0 != t->index)
1519 return -EINVAL;
1520
1521 strcpy(t->name, "Tuner");
1522
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001523 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001524 return 0;
1525}
1526
1527static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001528 const struct v4l2_tuner *t)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001529{
1530 struct em28xx_fh *fh = priv;
1531 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001532
1533 if (0 != t->index)
1534 return -EINVAL;
1535
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001536 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001537 return 0;
1538}
1539
1540static int vidioc_g_frequency(struct file *file, void *priv,
1541 struct v4l2_frequency *f)
1542{
1543 struct em28xx_fh *fh = priv;
1544 struct em28xx *dev = fh->dev;
1545
Hans Verkuil20deebf2012-09-06 10:07:25 -03001546 if (0 != f->tuner)
1547 return -EINVAL;
1548
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001549 f->frequency = dev->ctl_freq;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001550 return 0;
1551}
1552
1553static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001554 const struct v4l2_frequency *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001555{
Hans Verkuilb530a442013-03-19 04:09:26 -03001556 struct v4l2_frequency new_freq = *f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001557 struct em28xx_fh *fh = priv;
1558 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001559
1560 if (0 != f->tuner)
1561 return -EINVAL;
1562
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001563 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
Hans Verkuilb530a442013-03-19 04:09:26 -03001564 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
1565 dev->ctl_freq = new_freq.frequency;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001566
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001567 return 0;
1568}
1569
Hans Verkuilcd634f12013-03-27 08:04:23 -03001570#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03001571static int vidioc_g_chip_info(struct file *file, void *priv,
1572 struct v4l2_dbg_chip_info *chip)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001573{
1574 struct em28xx_fh *fh = priv;
1575 struct em28xx *dev = fh->dev;
1576
1577 if (chip->match.addr > 1)
1578 return -EINVAL;
1579 if (chip->match.addr == 1)
1580 strlcpy(chip->name, "ac97", sizeof(chip->name));
1581 else
1582 strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
1583 return 0;
1584}
1585
Frank Schaefer35deba32013-02-07 13:39:19 -03001586static int em28xx_reg_len(int reg)
1587{
1588 switch (reg) {
1589 case EM28XX_R40_AC97LSB:
1590 case EM28XX_R30_HSCALELOW:
1591 case EM28XX_R32_VSCALELOW:
1592 return 2;
1593 default:
1594 return 1;
1595 }
1596}
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001597
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001598static int vidioc_g_register(struct file *file, void *priv,
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001599 struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001600{
1601 struct em28xx_fh *fh = priv;
1602 struct em28xx *dev = fh->dev;
1603 int ret;
1604
Hans Verkuilabca2052013-05-29 06:59:35 -03001605 if (reg->match.addr > 1)
1606 return -EINVAL;
1607 if (reg->match.addr) {
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001608 ret = em28xx_read_ac97(dev, reg->reg);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001609 if (ret < 0)
1610 return ret;
1611
1612 reg->val = ret;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001613 reg->size = 1;
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001614 return 0;
1615 }
1616
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001617 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001618 reg->size = em28xx_reg_len(reg->reg);
1619 if (reg->size == 1) {
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001620 ret = em28xx_read_reg(dev, reg->reg);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001621
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001622 if (ret < 0)
1623 return ret;
1624
1625 reg->val = ret;
1626 } else {
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001627 __le16 val = 0;
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001628 ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001629 reg->reg, (char *)&val, 2);
1630 if (ret < 0)
1631 return ret;
1632
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001633 reg->val = le16_to_cpu(val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001634 }
1635
1636 return 0;
1637}
1638
1639static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001640 const struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001641{
1642 struct em28xx_fh *fh = priv;
1643 struct em28xx *dev = fh->dev;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001644 __le16 buf;
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001645
Hans Verkuilabca2052013-05-29 06:59:35 -03001646 if (reg->match.addr > 1)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001647 return -EINVAL;
Hans Verkuilabca2052013-05-29 06:59:35 -03001648 if (reg->match.addr)
1649 return em28xx_write_ac97(dev, reg->reg, reg->val);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001650
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001651 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001652 buf = cpu_to_le16(reg->val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001653
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001654 return em28xx_write_regs(dev, reg->reg, (char *)&buf,
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001655 em28xx_reg_len(reg->reg));
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001656}
1657#endif
1658
1659
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001660static int vidioc_querycap(struct file *file, void *priv,
1661 struct v4l2_capability *cap)
1662{
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001663 struct video_device *vdev = video_devdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001664 struct em28xx_fh *fh = priv;
1665 struct em28xx *dev = fh->dev;
1666
1667 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1668 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
Thierry MERLEcb977162009-01-20 18:01:33 -03001669 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001670
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001671 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1672 cap->device_caps = V4L2_CAP_READWRITE |
1673 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1674 else if (vdev->vfl_type == VFL_TYPE_RADIO)
1675 cap->device_caps = V4L2_CAP_RADIO;
1676 else
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001677 cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
Devin Heitmueller04146142009-09-11 00:08:44 -03001678
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001679 if (dev->audio_mode.has_audio)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001680 cap->device_caps |= V4L2_CAP_AUDIO;
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001681
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -03001682 if (dev->tuner_type != TUNER_ABSENT)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001683 cap->device_caps |= V4L2_CAP_TUNER;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001684
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001685 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1686 V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1687 if (dev->vbi_dev)
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001688 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001689 if (dev->radio_dev)
1690 cap->capabilities |= V4L2_CAP_RADIO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001691 return 0;
1692}
1693
Hans Verkuil78b526a2008-05-28 12:16:41 -03001694static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001695 struct v4l2_fmtdesc *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001696{
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001697 if (unlikely(f->index >= ARRAY_SIZE(format)))
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001698 return -EINVAL;
1699
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001700 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1701 f->pixelformat = format[f->index].fourcc;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001702
1703 return 0;
1704}
1705
Mauro Carvalho Chehab1c5c5062011-10-16 13:52:43 -02001706static int vidioc_enum_framesizes(struct file *file, void *priv,
1707 struct v4l2_frmsizeenum *fsize)
1708{
1709 struct em28xx_fh *fh = priv;
1710 struct em28xx *dev = fh->dev;
1711 struct em28xx_fmt *fmt;
1712 unsigned int maxw = norm_maxw(dev);
1713 unsigned int maxh = norm_maxh(dev);
1714
1715 fmt = format_by_fourcc(fsize->pixel_format);
1716 if (!fmt) {
1717 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1718 fsize->pixel_format);
1719 return -EINVAL;
1720 }
1721
1722 if (dev->board.is_em2800) {
1723 if (fsize->index > 1)
1724 return -EINVAL;
1725 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1726 fsize->discrete.width = maxw / (1 + fsize->index);
1727 fsize->discrete.height = maxh / (1 + fsize->index);
1728 return 0;
1729 }
1730
1731 if (fsize->index != 0)
1732 return -EINVAL;
1733
1734 /* Report a continuous range */
1735 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
Frank Schaefer6c3598e2013-02-10 16:05:14 -03001736 scale_to_size(dev, EM28XX_HVSCALE_MAX, EM28XX_HVSCALE_MAX,
1737 &fsize->stepwise.min_width, &fsize->stepwise.min_height);
1738 if (fsize->stepwise.min_width < 48)
1739 fsize->stepwise.min_width = 48;
1740 if (fsize->stepwise.min_height < 38)
1741 fsize->stepwise.min_height = 38;
Mauro Carvalho Chehab1c5c5062011-10-16 13:52:43 -02001742 fsize->stepwise.max_width = maxw;
1743 fsize->stepwise.max_height = maxh;
1744 fsize->stepwise.step_width = 1;
1745 fsize->stepwise.step_height = 1;
1746 return 0;
1747}
1748
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001749/* RAW VBI ioctls */
1750
1751static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1752 struct v4l2_format *format)
1753{
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001754 struct em28xx_fh *fh = priv;
1755 struct em28xx *dev = fh->dev;
1756
1757 format->fmt.vbi.samples_per_line = dev->vbi_width;
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001758 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1759 format->fmt.vbi.offset = 0;
1760 format->fmt.vbi.flags = 0;
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001761 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1762 format->fmt.vbi.count[0] = dev->vbi_height;
1763 format->fmt.vbi.count[1] = dev->vbi_height;
Hans Verkuil2a221d32012-09-07 08:51:32 -03001764 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001765
1766 /* Varies by video standard (NTSC, PAL, etc.) */
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001767 if (dev->norm & V4L2_STD_525_60) {
1768 /* NTSC */
1769 format->fmt.vbi.start[0] = 10;
1770 format->fmt.vbi.start[1] = 273;
1771 } else if (dev->norm & V4L2_STD_625_50) {
1772 /* PAL */
1773 format->fmt.vbi.start[0] = 6;
1774 format->fmt.vbi.start[1] = 318;
1775 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001776
1777 return 0;
1778}
1779
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001780/* ----------------------------------------------------------- */
1781/* RADIO ESPECIFIC IOCTLS */
1782/* ----------------------------------------------------------- */
1783
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001784static int radio_g_tuner(struct file *file, void *priv,
1785 struct v4l2_tuner *t)
1786{
1787 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1788
1789 if (unlikely(t->index > 0))
1790 return -EINVAL;
1791
1792 strcpy(t->name, "Radio");
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001793
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001794 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001795
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001796 return 0;
1797}
1798
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001799static int radio_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001800 const struct v4l2_tuner *t)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001801{
1802 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1803
1804 if (0 != t->index)
1805 return -EINVAL;
1806
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001807 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001808
1809 return 0;
1810}
1811
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001812/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001813 * em28xx_v4l2_open()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001814 * inits the device and starts isoc transfer
1815 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001816static int em28xx_v4l2_open(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001817{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001818 struct video_device *vdev = video_devdata(filp);
1819 struct em28xx *dev = video_drvdata(filp);
1820 enum v4l2_buf_type fh_type = 0;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001821 struct em28xx_fh *fh;
Markus Rechberger9c755412005-11-08 21:37:52 -08001822
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001823 switch (vdev->vfl_type) {
1824 case VFL_TYPE_GRABBER:
1825 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1826 break;
1827 case VFL_TYPE_VBI:
1828 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1829 break;
Frank Schaefer4e170242014-01-12 13:24:18 -03001830 case VFL_TYPE_RADIO:
1831 break;
1832 default:
1833 return -EINVAL;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001834 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03001835
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001836 em28xx_videodbg("open dev=%s type=%s users=%d\n",
1837 video_device_node_name(vdev), v4l2_type_names[fh_type],
1838 dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001839
Hans Verkuil876cb142012-06-23 08:12:47 -03001840 if (mutex_lock_interruptible(&dev->lock))
1841 return -ERESTARTSYS;
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001842 fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001843 if (!fh) {
1844 em28xx_errdev("em28xx-video.c: Out of memory?!\n");
Hans Verkuil876cb142012-06-23 08:12:47 -03001845 mutex_unlock(&dev->lock);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001846 return -ENOMEM;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001847 }
Hans Verkuil69a61642012-09-07 05:52:40 -03001848 v4l2_fh_init(&fh->fh, vdev);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001849 fh->dev = dev;
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001850 fh->type = fh_type;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001851 filp->private_data = fh;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001852
Frank Schaefer4e170242014-01-12 13:24:18 -03001853 if (dev->users == 0) {
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001854 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001855
Frank Schaefer4e170242014-01-12 13:24:18 -03001856 if (vdev->vfl_type != VFL_TYPE_RADIO)
1857 em28xx_resolution_set(dev);
1858
1859 /*
1860 * Needed, since GPIO might have disabled power
1861 * of some i2c devices
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001862 */
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03001863 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001864 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001865
1866 if (vdev->vfl_type == VFL_TYPE_RADIO) {
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001867 em28xx_videodbg("video_open: setting radio device\n");
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001868 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001869 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001870
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001871 kref_get(&dev->ref);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001872 dev->users++;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001873
Hans Verkuil876cb142012-06-23 08:12:47 -03001874 mutex_unlock(&dev->lock);
Hans Verkuil69a61642012-09-07 05:52:40 -03001875 v4l2_fh_add(&fh->fh);
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001876
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001877 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001878}
1879
1880/*
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001881 * em28xx_v4l2_fini()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001882 * unregisters the v4l2,i2c and usb devices
1883 * called when the device gets disconected or at module unload
1884*/
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001885static int em28xx_v4l2_fini(struct em28xx *dev)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001886{
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03001887 if (dev->is_audio_only) {
1888 /* Shouldn't initialize IR for this interface */
1889 return 0;
1890 }
1891
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001892 if (!dev->has_video) {
1893 /* This device does not support the v4l2 extension */
1894 return 0;
1895 }
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001896
Mauro Carvalho Chehabaa929ad2014-01-12 19:22:07 -03001897 em28xx_info("Closing video extension");
1898
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001899 mutex_lock(&dev->lock);
1900
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001901 v4l2_device_disconnect(&dev->v4l2_dev);
1902
Frank Schaefer23e86422014-01-12 13:24:20 -03001903 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
1904
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001905 if (dev->radio_dev) {
Frank Schaefere8470222014-01-12 13:24:25 -03001906 em28xx_info("V4L2 device %s deregistered\n",
1907 video_device_node_name(dev->radio_dev));
1908 video_unregister_device(dev->radio_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001909 }
1910 if (dev->vbi_dev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001911 em28xx_info("V4L2 device %s deregistered\n",
1912 video_device_node_name(dev->vbi_dev));
Frank Schaefere8470222014-01-12 13:24:25 -03001913 video_unregister_device(dev->vbi_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001914 }
1915 if (dev->vdev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001916 em28xx_info("V4L2 device %s deregistered\n",
1917 video_device_node_name(dev->vdev));
Frank Schaefere8470222014-01-12 13:24:25 -03001918 video_unregister_device(dev->vdev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001919 }
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001920
Frank Schaefer103f18a2014-01-17 14:45:30 -03001921 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1922 v4l2_device_unregister(&dev->v4l2_dev);
1923
Frank Schaefer25dd1652014-01-12 13:24:23 -03001924 if (dev->clk) {
1925 v4l2_clk_unregister_fixed(dev->clk);
1926 dev->clk = NULL;
1927 }
1928
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001929 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001930 kref_put(&dev->ref, em28xx_free_device);
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001931
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001932 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001933}
1934
Shuah Khana61f6812014-02-21 21:50:17 -03001935static int em28xx_v4l2_suspend(struct em28xx *dev)
1936{
1937 if (dev->is_audio_only)
1938 return 0;
1939
1940 if (!dev->has_video)
1941 return 0;
1942
1943 em28xx_info("Suspending video extension");
1944 em28xx_stop_urbs(dev);
1945 return 0;
1946}
1947
1948static int em28xx_v4l2_resume(struct em28xx *dev)
1949{
1950 if (dev->is_audio_only)
1951 return 0;
1952
1953 if (!dev->has_video)
1954 return 0;
1955
1956 em28xx_info("Resuming video extension");
1957 /* what do we do here */
1958 return 0;
1959}
1960
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001961/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001962 * em28xx_v4l2_close()
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001963 * stops streaming and deallocates all resources allocated by the v4l2
1964 * calls and ioctls
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001965 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001966static int em28xx_v4l2_close(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001967{
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001968 struct em28xx_fh *fh = filp->private_data;
1969 struct em28xx *dev = fh->dev;
1970 int errCode;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001971
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001972 em28xx_videodbg("users=%d\n", dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001973
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001974 vb2_fop_release(filp);
Ricardo Ribalda98c24dcd2013-11-06 05:39:35 -03001975 mutex_lock(&dev->lock);
Devin Heitmueller8c873d32009-09-03 00:23:27 -03001976
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001977 if (dev->users == 1) {
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001978 /* No sense to try to write to the device */
1979 if (dev->disconnected)
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001980 goto exit;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001981
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03001982 /* Save some power by putting tuner to sleep */
Laurent Pinchart622b8282009-10-05 10:48:17 -03001983 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03001984
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001985 /* do this before setting alternate! */
Mauro Carvalho Chehab2fe3e2e2008-11-27 09:10:40 -03001986 em28xx_set_mode(dev, EM28XX_SUSPEND);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001987
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001988 /* set alternate 0 */
1989 dev->alt = 0;
1990 em28xx_videodbg("setting alternate 0\n");
1991 errCode = usb_set_interface(dev->udev, 0, 0);
1992 if (errCode < 0) {
1993 em28xx_errdev("cannot change alternate number to "
1994 "0 (error=%i)\n", errCode);
1995 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001996 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001997
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001998exit:
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001999 dev->users--;
Hans Verkuil876cb142012-06-23 08:12:47 -03002000 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002001 kref_put(&dev->ref, em28xx_free_device);
2002
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002003 return 0;
2004}
2005
Frank Schaefere8470222014-01-12 13:24:25 -03002006/*
2007 * em28xx_videodevice_release()
2008 * called when the last user of the video device exits and frees the memeory
2009 */
2010static void em28xx_videodevice_release(struct video_device *vdev)
2011{
2012 struct em28xx *dev = video_get_drvdata(vdev);
2013
2014 video_device_release(vdev);
2015 if (vdev == dev->vdev)
2016 dev->vdev = NULL;
2017 else if (vdev == dev->vbi_dev)
2018 dev->vbi_dev = NULL;
2019 else if (vdev == dev->radio_dev)
2020 dev->radio_dev = NULL;
2021}
2022
Hans Verkuilbec43662008-12-30 06:58:20 -03002023static const struct v4l2_file_operations em28xx_v4l_fops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002024 .owner = THIS_MODULE,
2025 .open = em28xx_v4l2_open,
2026 .release = em28xx_v4l2_close,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002027 .read = vb2_fop_read,
2028 .poll = vb2_fop_poll,
2029 .mmap = vb2_fop_mmap,
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002030 .unlocked_ioctl = video_ioctl2,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002031};
2032
Hans Verkuila3998102008-07-21 02:57:38 -03002033static const struct v4l2_ioctl_ops video_ioctl_ops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002034 .vidioc_querycap = vidioc_querycap,
Hans Verkuil78b526a2008-05-28 12:16:41 -03002035 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
2036 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
2037 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
2038 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller28abf0832009-09-01 01:54:54 -03002039 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil2a221d32012-09-07 08:51:32 -03002040 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Frank Schaeferaab34612013-02-07 13:39:16 -03002041 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Mauro Carvalho Chehab1c5c5062011-10-16 13:52:43 -02002042 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002043 .vidioc_g_audio = vidioc_g_audio,
2044 .vidioc_s_audio = vidioc_s_audio,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002045
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002046 .vidioc_reqbufs = vb2_ioctl_reqbufs,
2047 .vidioc_create_bufs = vb2_ioctl_create_bufs,
2048 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
2049 .vidioc_querybuf = vb2_ioctl_querybuf,
2050 .vidioc_qbuf = vb2_ioctl_qbuf,
2051 .vidioc_dqbuf = vb2_ioctl_dqbuf,
2052
Devin Heitmueller19bf0032009-09-11 00:40:18 -03002053 .vidioc_g_std = vidioc_g_std,
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03002054 .vidioc_querystd = vidioc_querystd,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002055 .vidioc_s_std = vidioc_s_std,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03002056 .vidioc_g_parm = vidioc_g_parm,
2057 .vidioc_s_parm = vidioc_s_parm,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002058 .vidioc_enum_input = vidioc_enum_input,
2059 .vidioc_g_input = vidioc_g_input,
2060 .vidioc_s_input = vidioc_s_input,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002061 .vidioc_streamon = vb2_ioctl_streamon,
2062 .vidioc_streamoff = vb2_ioctl_streamoff,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002063 .vidioc_g_tuner = vidioc_g_tuner,
2064 .vidioc_s_tuner = vidioc_s_tuner,
2065 .vidioc_g_frequency = vidioc_g_frequency,
2066 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002067 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2068 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002069#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03002070 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002071 .vidioc_g_register = vidioc_g_register,
2072 .vidioc_s_register = vidioc_s_register,
2073#endif
Hans Verkuila3998102008-07-21 02:57:38 -03002074};
2075
2076static const struct video_device em28xx_video_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002077 .fops = &em28xx_v4l_fops,
2078 .ioctl_ops = &video_ioctl_ops,
2079 .release = em28xx_videodevice_release,
2080 .tvnorms = V4L2_STD_ALL,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002081};
2082
Hans Verkuilbec43662008-12-30 06:58:20 -03002083static const struct v4l2_file_operations radio_fops = {
Hans Verkuila3998102008-07-21 02:57:38 -03002084 .owner = THIS_MODULE,
2085 .open = em28xx_v4l2_open,
2086 .release = em28xx_v4l2_close,
Hans Verkuil8fd0bda2010-12-18 09:59:51 -03002087 .unlocked_ioctl = video_ioctl2,
Hans Verkuila3998102008-07-21 02:57:38 -03002088};
2089
2090static const struct v4l2_ioctl_ops radio_ioctl_ops = {
Hans Verkuila9d79fe2012-09-06 07:31:04 -03002091 .vidioc_querycap = vidioc_querycap,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002092 .vidioc_g_tuner = radio_g_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002093 .vidioc_s_tuner = radio_s_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002094 .vidioc_g_frequency = vidioc_g_frequency,
2095 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002096 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2097 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002098#ifdef CONFIG_VIDEO_ADV_DEBUG
Michal Marek430c73f2013-04-16 08:06:30 -03002099 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002100 .vidioc_g_register = vidioc_g_register,
2101 .vidioc_s_register = vidioc_s_register,
2102#endif
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002103};
2104
Hans Verkuila3998102008-07-21 02:57:38 -03002105static struct video_device em28xx_radio_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002106 .fops = &radio_fops,
2107 .ioctl_ops = &radio_ioctl_ops,
2108 .release = em28xx_videodevice_release,
Hans Verkuila3998102008-07-21 02:57:38 -03002109};
2110
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002111/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2112static unsigned short saa711x_addrs[] = {
2113 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2114 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2115 I2C_CLIENT_END };
2116
2117static unsigned short tvp5150_addrs[] = {
2118 0xb8 >> 1,
2119 0xba >> 1,
2120 I2C_CLIENT_END
2121};
2122
2123static unsigned short msp3400_addrs[] = {
2124 0x80 >> 1,
2125 0x88 >> 1,
2126 I2C_CLIENT_END
2127};
2128
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002129/******************************** usb interface ******************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002130
Adrian Bunk532fe652008-01-28 22:10:48 -03002131static struct video_device *em28xx_vdev_init(struct em28xx *dev,
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002132 const struct video_device *template,
2133 const char *type_name)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002134{
2135 struct video_device *vfd;
2136
2137 vfd = video_device_alloc();
2138 if (NULL == vfd)
2139 return NULL;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002140
2141 *vfd = *template;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002142 vfd->v4l2_dev = &dev->v4l2_dev;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002143 vfd->debug = video_debug;
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002144 vfd->lock = &dev->lock;
Hans Verkuil69a61642012-09-07 05:52:40 -03002145 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
Hans Verkuild8c95c02012-09-07 07:31:54 -03002146 if (dev->board.is_webcam)
2147 vfd->tvnorms = 0;
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002148
2149 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
2150 dev->name, type_name);
2151
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002152 video_set_drvdata(vfd, dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002153 return vfd;
2154}
2155
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002156static void em28xx_tuner_setup(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002157{
2158 struct tuner_setup tun_setup;
2159 struct v4l2_frequency f;
2160
2161 if (dev->tuner_type == TUNER_ABSENT)
2162 return;
2163
2164 memset(&tun_setup, 0, sizeof(tun_setup));
2165
2166 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2167 tun_setup.tuner_callback = em28xx_tuner_callback;
2168
2169 if (dev->board.radio.type) {
2170 tun_setup.type = dev->board.radio.type;
2171 tun_setup.addr = dev->board.radio_addr;
2172
2173 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2174 }
2175
2176 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2177 tun_setup.type = dev->tuner_type;
2178 tun_setup.addr = dev->tuner_addr;
2179
2180 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2181 }
2182
2183 if (dev->tda9887_conf) {
2184 struct v4l2_priv_tun_config tda9887_cfg;
2185
2186 tda9887_cfg.tuner = TUNER_TDA9887;
2187 tda9887_cfg.priv = &dev->tda9887_conf;
2188
2189 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
2190 }
2191
2192 if (dev->tuner_type == TUNER_XC2028) {
2193 struct v4l2_priv_tun_config xc2028_cfg;
2194 struct xc2028_ctrl ctl;
2195
2196 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2197 memset(&ctl, 0, sizeof(ctl));
2198
2199 em28xx_setup_xc3028(dev, &ctl);
2200
2201 xc2028_cfg.tuner = TUNER_XC2028;
2202 xc2028_cfg.priv = &ctl;
2203
2204 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
2205 }
2206
2207 /* configure tuner */
2208 f.tuner = 0;
2209 f.type = V4L2_TUNER_ANALOG_TV;
2210 f.frequency = 9076; /* just a magic number */
2211 dev->ctl_freq = f.frequency;
2212 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
2213}
2214
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002215static int em28xx_v4l2_init(struct em28xx *dev)
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002216{
Hans Verkuil081b9452012-09-07 05:43:59 -03002217 u8 val;
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002218 int ret;
Sascha Sommer1020d132012-01-08 16:54:28 -03002219 unsigned int maxw;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002220 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2221
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03002222 if (dev->is_audio_only) {
2223 /* Shouldn't initialize IR for this interface */
2224 return 0;
2225 }
2226
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002227 if (!dev->has_video) {
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002228 /* This device does not support the v4l2 extension */
2229 return 0;
2230 }
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002231
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002232 em28xx_info("Registering V4L2 extension\n");
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002233
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002234 mutex_lock(&dev->lock);
2235
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002236 ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
2237 if (ret < 0) {
2238 em28xx_errdev("Call to v4l2_device_register() failed!\n");
2239 goto err;
2240 }
2241
2242 v4l2_ctrl_handler_init(hdl, 8);
2243 dev->v4l2_dev.ctrl_handler = hdl;
2244
2245 /*
2246 * Default format, used for tvp5150 or saa711x output formats
2247 */
2248 dev->vinmode = 0x10;
2249 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2250 EM28XX_VINCTRL_CCIR656_ENABLE;
2251
2252 /* request some modules */
2253
2254 if (dev->board.has_msp34xx)
2255 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2256 "msp3400", 0, msp3400_addrs);
2257
2258 if (dev->board.decoder == EM28XX_SAA711X)
2259 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2260 "saa7115_auto", 0, saa711x_addrs);
2261
2262 if (dev->board.decoder == EM28XX_TVP5150)
2263 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2264 "tvp5150", 0, tvp5150_addrs);
2265
2266 if (dev->board.adecoder == EM28XX_TVAUDIO)
2267 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2268 "tvaudio", dev->board.tvaudio_addr, NULL);
2269
2270 /* Initialize tuner and camera */
2271
2272 if (dev->board.tuner_type != TUNER_ABSENT) {
2273 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2274
2275 if (dev->board.radio.type)
2276 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2277 "tuner", dev->board.radio_addr, NULL);
2278
2279 if (has_demod)
2280 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2281 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2282 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2283 if (dev->tuner_addr == 0) {
2284 enum v4l2_i2c_tuner_type type =
2285 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2286 struct v4l2_subdev *sd;
2287
2288 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2289 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2290 0, v4l2_i2c_tuner_addrs(type));
2291
2292 if (sd)
2293 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2294 } else {
2295 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2296 "tuner", dev->tuner_addr, NULL);
2297 }
2298 }
2299
2300 em28xx_tuner_setup(dev);
Frank Schaeferd86bc652014-01-17 14:45:32 -03002301 if (dev->em28xx_sensor != EM28XX_NOSENSOR)
2302 em28xx_init_camera(dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002303
2304 /* Configure audio */
2305 ret = em28xx_audio_setup(dev);
2306 if (ret < 0) {
2307 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2308 __func__, ret);
2309 goto unregister_dev;
2310 }
2311 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
2312 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2313 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
2314 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2315 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
2316 } else {
2317 /* install the em28xx notify callback */
2318 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
2319 em28xx_ctrl_notify, dev);
2320 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
2321 em28xx_ctrl_notify, dev);
2322 }
2323
2324 /* wake i2c devices */
2325 em28xx_wake_i2c(dev);
2326
2327 /* init video dma queues */
2328 INIT_LIST_HEAD(&dev->vidq.active);
2329 INIT_LIST_HEAD(&dev->vbiq.active);
2330
2331 if (dev->board.has_msp34xx) {
2332 /* Send a reset to other chips via gpio */
2333 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
2334 if (ret < 0) {
2335 em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
2336 __func__, ret);
2337 goto unregister_dev;
2338 }
2339 msleep(3);
2340
2341 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
2342 if (ret < 0) {
2343 em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
2344 __func__, ret);
2345 goto unregister_dev;
2346 }
2347 msleep(3);
2348 }
2349
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002350 /* set default norm */
Hans Verkuild8c95c02012-09-07 07:31:54 -03002351 dev->norm = V4L2_STD_PAL;
Hans Verkuild5906dd2010-09-26 07:45:15 -03002352 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002353 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002354
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002355 /* Analog specific initialization */
2356 dev->format = &format[0];
Sascha Sommer1020d132012-01-08 16:54:28 -03002357
2358 maxw = norm_maxw(dev);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002359 /* MaxPacketSize for em2800 is too small to capture at full resolution
2360 * use half of maxw as the scaler can only scale to 50% */
2361 if (dev->board.is_em2800)
2362 maxw /= 2;
Sascha Sommer1020d132012-01-08 16:54:28 -03002363
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002364 em28xx_set_video_format(dev, format[0].fourcc,
Sascha Sommer1020d132012-01-08 16:54:28 -03002365 maxw, norm_maxh(dev));
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002366
Ezequiel García96371fc2012-03-23 18:09:34 -03002367 video_mux(dev, 0);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002368
2369 /* Audio defaults */
2370 dev->mute = 1;
2371 dev->volume = 0x1f;
2372
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002373/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002374 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2375 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2376 (EM28XX_XCLK_AUDIO_UNMUTE | val));
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002377
2378 em28xx_set_outfmt(dev);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002379 em28xx_compression_disable(dev);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002380
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002381 /* Add image controls */
2382 /* NOTE: at this point, the subdevices are already registered, so bridge
2383 * controls are only added/enabled when no subdevice provides them */
2384 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_CONTRAST))
2385 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2386 V4L2_CID_CONTRAST,
2387 0, 0x1f, 1, CONTRAST_DEFAULT);
2388 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BRIGHTNESS))
2389 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2390 V4L2_CID_BRIGHTNESS,
2391 -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT);
2392 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SATURATION))
2393 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2394 V4L2_CID_SATURATION,
2395 0, 0x1f, 1, SATURATION_DEFAULT);
2396 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BLUE_BALANCE))
2397 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2398 V4L2_CID_BLUE_BALANCE,
2399 -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT);
2400 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RED_BALANCE))
2401 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2402 V4L2_CID_RED_BALANCE,
2403 -0x30, 0x30, 1, RED_BALANCE_DEFAULT);
2404 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SHARPNESS))
2405 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2406 V4L2_CID_SHARPNESS,
2407 0, 0x0f, 1, SHARPNESS_DEFAULT);
2408
2409 /* Reset image controls */
2410 em28xx_colorlevels_set_default(dev);
2411 v4l2_ctrl_handler_setup(&dev->ctrl_handler);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002412 ret = dev->ctrl_handler.error;
2413 if (ret)
2414 goto unregister_dev;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002415
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002416 /* allocate and fill video video_device struct */
2417 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
2418 if (!dev->vdev) {
2419 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002420 ret = -ENODEV;
2421 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002422 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002423 dev->vdev->queue = &dev->vb_vidq;
2424 dev->vdev->queue->lock = &dev->vb_queue_lock;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002425
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002426 /* disable inapplicable ioctls */
2427 if (dev->board.is_webcam) {
2428 v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD);
2429 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD);
2430 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD);
Frank Schaefer3bc85cc2013-02-07 13:39:12 -03002431 } else {
2432 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002433 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002434 if (dev->tuner_type == TUNER_ABSENT) {
2435 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER);
2436 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_TUNER);
2437 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY);
2438 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY);
2439 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002440 if (!dev->audio_mode.has_audio) {
2441 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_AUDIO);
2442 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_AUDIO);
2443 }
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002444
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002445 /* register v4l2 video video_device */
2446 ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
2447 video_nr[dev->devno]);
2448 if (ret) {
2449 em28xx_errdev("unable to register video device (error=%i).\n",
2450 ret);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002451 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002452 }
2453
2454 /* Allocate and fill vbi video_device struct */
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002455 if (em28xx_vbi_supported(dev) == 1) {
2456 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
2457 "vbi");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002458
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002459 dev->vbi_dev->queue = &dev->vb_vbiq;
2460 dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock;
2461
Frank Schaefer66df67b2013-02-07 13:39:10 -03002462 /* disable inapplicable ioctls */
Frank Schaefer83c8bcc2013-02-07 13:39:13 -03002463 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002464 if (dev->tuner_type == TUNER_ABSENT) {
2465 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER);
2466 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER);
2467 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY);
2468 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY);
2469 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002470 if (!dev->audio_mode.has_audio) {
2471 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_AUDIO);
2472 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_AUDIO);
2473 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002474
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002475 /* register v4l2 vbi video_device */
2476 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
2477 vbi_nr[dev->devno]);
2478 if (ret < 0) {
2479 em28xx_errdev("unable to register vbi device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002480 goto unregister_dev;
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002481 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002482 }
2483
2484 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002485 dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
2486 "radio");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002487 if (!dev->radio_dev) {
2488 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002489 ret = -ENODEV;
2490 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002491 }
2492 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
2493 radio_nr[dev->devno]);
2494 if (ret < 0) {
2495 em28xx_errdev("can't register radio device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002496 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002497 }
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002498 em28xx_info("Registered radio device as %s\n",
2499 video_device_node_name(dev->radio_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002500 }
2501
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002502 em28xx_info("V4L2 video device registered as %s\n",
2503 video_device_node_name(dev->vdev));
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002504
2505 if (dev->vbi_dev)
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002506 em28xx_info("V4L2 VBI device registered as %s\n",
2507 video_device_node_name(dev->vbi_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002508
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002509 /* Save some power by putting tuner to sleep */
2510 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2511
2512 /* initialize videobuf2 stuff */
2513 em28xx_vb2_setup(dev);
2514
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002515 em28xx_info("V4L2 extension successfully initialized\n");
2516
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002517 kref_get(&dev->ref);
2518
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002519 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002520 return 0;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002521
2522unregister_dev:
2523 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2524 v4l2_device_unregister(&dev->v4l2_dev);
2525err:
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002526 mutex_unlock(&dev->lock);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002527 return ret;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002528}
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002529
2530static struct em28xx_ops v4l2_ops = {
2531 .id = EM28XX_V4L2,
2532 .name = "Em28xx v4l2 Extension",
2533 .init = em28xx_v4l2_init,
2534 .fini = em28xx_v4l2_fini,
Shuah Khana61f6812014-02-21 21:50:17 -03002535 .suspend = em28xx_v4l2_suspend,
2536 .resume = em28xx_v4l2_resume,
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002537};
2538
2539static int __init em28xx_video_register(void)
2540{
2541 return em28xx_register_extension(&v4l2_ops);
2542}
2543
2544static void __exit em28xx_video_unregister(void)
2545{
2546 em28xx_unregister_extension(&v4l2_ops);
2547}
2548
2549module_init(em28xx_video_register);
2550module_exit(em28xx_video_unregister);