blob: 4f66bd360c3c5bdb92653e3bf6052926b2d8b5e3 [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{
Frank Schaefercba8e9b2014-03-24 16:28:36 -0300277 u8 mode = 0x00;
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300278 /* 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 }
Frank Schaefercba8e9b2014-03-24 16:28:36 -0300296 return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300297}
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
Hans Verkuile37559b2014-04-17 02:47:21 -0300940static void 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);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300964}
965
Hans Verkuile37559b2014-04-17 02:47:21 -0300966void em28xx_stop_vbi_streaming(struct vb2_queue *vq)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300967{
968 struct em28xx *dev = vb2_get_drv_priv(vq);
969 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
970 unsigned long flags = 0;
971
972 em28xx_videodbg("%s\n", __func__);
973
974 res_free(dev, vq->type);
975
976 if (dev->streaming_users-- == 1) {
977 /* Last active user, so shutdown all the URBS */
978 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
979 }
980
981 spin_lock_irqsave(&dev->slock, flags);
982 while (!list_empty(&vbiq->active)) {
983 struct em28xx_buffer *buf;
984 buf = list_entry(vbiq->active.next, struct em28xx_buffer, list);
985 list_del(&buf->list);
986 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
987 }
988 dev->usb_ctl.vbi_buf = NULL;
989 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300990}
991
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300992static void
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300993buffer_queue(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300994{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300995 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
996 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
997 struct em28xx_dmaqueue *vidq = &dev->vidq;
998 unsigned long flags = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300999
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001000 em28xx_videodbg("%s\n", __func__);
1001 buf->mem = vb2_plane_vaddr(vb, 0);
1002 buf->length = vb2_plane_size(vb, 0);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001003
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001004 spin_lock_irqsave(&dev->slock, flags);
1005 list_add_tail(&buf->list, &vidq->active);
1006 spin_unlock_irqrestore(&dev->slock, flags);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001007}
1008
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001009static struct vb2_ops em28xx_video_qops = {
1010 .queue_setup = queue_setup,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001011 .buf_prepare = buffer_prepare,
1012 .buf_queue = buffer_queue,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001013 .start_streaming = em28xx_start_analog_streaming,
1014 .stop_streaming = em28xx_stop_streaming,
1015 .wait_prepare = vb2_ops_wait_prepare,
1016 .wait_finish = vb2_ops_wait_finish,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001017};
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001018
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001019static int em28xx_vb2_setup(struct em28xx *dev)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001020{
1021 int rc;
1022 struct vb2_queue *q;
1023
1024 /* Setup Videobuf2 for Video capture */
1025 q = &dev->vb_vidq;
1026 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Mauro Carvalho Chehabef85cd92013-01-06 00:34:22 -02001027 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
Sakari Ailusade48682014-02-25 19:12:19 -03001028 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001029 q->drv_priv = dev;
1030 q->buf_struct_size = sizeof(struct em28xx_buffer);
1031 q->ops = &em28xx_video_qops;
1032 q->mem_ops = &vb2_vmalloc_memops;
1033
1034 rc = vb2_queue_init(q);
1035 if (rc < 0)
1036 return rc;
1037
1038 /* Setup Videobuf2 for VBI capture */
1039 q = &dev->vb_vbiq;
1040 q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1041 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR;
Sakari Ailusade48682014-02-25 19:12:19 -03001042 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001043 q->drv_priv = dev;
1044 q->buf_struct_size = sizeof(struct em28xx_buffer);
1045 q->ops = &em28xx_vbi_qops;
1046 q->mem_ops = &vb2_vmalloc_memops;
1047
1048 rc = vb2_queue_init(q);
1049 if (rc < 0)
1050 return rc;
1051
1052 return 0;
1053}
1054
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001055/********************* v4l2 interface **************************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001056
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001057static void video_mux(struct em28xx *dev, int index)
1058{
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001059 dev->ctl_input = index;
1060 dev->ctl_ainput = INPUT(index)->amux;
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001061 dev->ctl_aoutput = INPUT(index)->aout;
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001062
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001063 if (!dev->ctl_aoutput)
1064 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
1065
Hans Verkuil5325b422009-04-02 11:26:22 -03001066 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
1067 INPUT(index)->vmux, 0, 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001068
Mauro Carvalho Chehab505b6d02008-11-25 09:39:50 -03001069 if (dev->board.has_msp34xx) {
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001070 if (dev->i2s_speed) {
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001071 v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
1072 s_i2s_clock_freq, dev->i2s_speed);
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001073 }
Hans Verkuil2474ed42006-03-19 12:35:57 -03001074 /* Note: this is msp3400 specific */
Hans Verkuil5325b422009-04-02 11:26:22 -03001075 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1076 dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001077 }
Mauro Carvalho Chehab539c96d2008-01-05 09:53:54 -03001078
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001079 if (dev->board.adecoder != EM28XX_NOADECODER) {
Hans Verkuil5325b422009-04-02 11:26:22 -03001080 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1081 dev->ctl_ainput, dev->ctl_aoutput, 0);
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001082 }
1083
Mauro Carvalho Chehab00b87302008-02-06 18:34:13 -03001084 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001085}
1086
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001087static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001088{
Hans Verkuil081b9452012-09-07 05:43:59 -03001089 struct em28xx *dev = priv;
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001090
Hans Verkuil081b9452012-09-07 05:43:59 -03001091 /*
1092 * In the case of non-AC97 volume controls, we still need
1093 * to do some setups at em28xx, in order to mute/unmute
1094 * and to adjust audio volume. However, the value ranges
1095 * should be checked by the corresponding V4L subdriver.
1096 */
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001097 switch (ctrl->id) {
1098 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil081b9452012-09-07 05:43:59 -03001099 dev->mute = ctrl->val;
1100 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001101 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001102 case V4L2_CID_AUDIO_VOLUME:
Hans Verkuil081b9452012-09-07 05:43:59 -03001103 dev->volume = ctrl->val;
1104 em28xx_audio_analog_set(dev);
1105 break;
1106 }
1107}
1108
1109static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
1110{
1111 struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler);
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001112 int ret = -EINVAL;
Hans Verkuil081b9452012-09-07 05:43:59 -03001113
1114 switch (ctrl->id) {
1115 case V4L2_CID_AUDIO_MUTE:
1116 dev->mute = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001117 ret = em28xx_audio_analog_set(dev);
Hans Verkuil081b9452012-09-07 05:43:59 -03001118 break;
1119 case V4L2_CID_AUDIO_VOLUME:
1120 dev->volume = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001121 ret = em28xx_audio_analog_set(dev);
1122 break;
1123 case V4L2_CID_CONTRAST:
1124 ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val);
1125 break;
1126 case V4L2_CID_BRIGHTNESS:
1127 ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val);
1128 break;
1129 case V4L2_CID_SATURATION:
1130 ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val);
1131 break;
1132 case V4L2_CID_BLUE_BALANCE:
1133 ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val);
1134 break;
1135 case V4L2_CID_RED_BALANCE:
1136 ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val);
1137 break;
1138 case V4L2_CID_SHARPNESS:
1139 ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001140 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001141 }
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001142
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001143 return (ret < 0) ? ret : 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001144}
1145
Fengguang Wu8068eb82014-01-07 12:50:47 -03001146static const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
Hans Verkuil081b9452012-09-07 05:43:59 -03001147 .s_ctrl = em28xx_s_ctrl,
1148};
1149
Frank Schaefer6b09a212013-02-10 16:05:12 -03001150static void size_to_scale(struct em28xx *dev,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001151 unsigned int width, unsigned int height,
1152 unsigned int *hscale, unsigned int *vscale)
1153{
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001154 unsigned int maxw = norm_maxw(dev);
1155 unsigned int maxh = norm_maxh(dev);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001156
1157 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001158 if (*hscale > EM28XX_HVSCALE_MAX)
1159 *hscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001160
1161 *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001162 if (*vscale > EM28XX_HVSCALE_MAX)
1163 *vscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001164}
1165
Frank Schaeferb8374132013-02-10 16:05:13 -03001166static void scale_to_size(struct em28xx *dev,
1167 unsigned int hscale, unsigned int vscale,
1168 unsigned int *width, unsigned int *height)
1169{
1170 unsigned int maxw = norm_maxw(dev);
1171 unsigned int maxh = norm_maxh(dev);
1172
1173 *width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
1174 *height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
1175}
1176
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001177/* ------------------------------------------------------------------
1178 IOCTL vidioc handling
1179 ------------------------------------------------------------------*/
1180
Hans Verkuil78b526a2008-05-28 12:16:41 -03001181static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001182 struct v4l2_format *f)
1183{
1184 struct em28xx_fh *fh = priv;
1185 struct em28xx *dev = fh->dev;
1186
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001187 f->fmt.pix.width = dev->width;
1188 f->fmt.pix.height = dev->height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001189 f->fmt.pix.pixelformat = dev->format->fourcc;
1190 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -03001191 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001192 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1193
1194 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001195 if (dev->progressive)
1196 f->fmt.pix.field = V4L2_FIELD_NONE;
1197 else
1198 f->fmt.pix.field = dev->interlaced ?
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001199 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001200 return 0;
1201}
1202
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001203static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
1204{
1205 unsigned int i;
1206
1207 for (i = 0; i < ARRAY_SIZE(format); i++)
1208 if (format[i].fourcc == fourcc)
1209 return &format[i];
1210
1211 return NULL;
1212}
1213
Hans Verkuil78b526a2008-05-28 12:16:41 -03001214static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001215 struct v4l2_format *f)
1216{
1217 struct em28xx_fh *fh = priv;
1218 struct em28xx *dev = fh->dev;
Trent Piephoccb83402009-05-30 21:45:46 -03001219 unsigned int width = f->fmt.pix.width;
1220 unsigned int height = f->fmt.pix.height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001221 unsigned int maxw = norm_maxw(dev);
1222 unsigned int maxh = norm_maxh(dev);
1223 unsigned int hscale, vscale;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001224 struct em28xx_fmt *fmt;
1225
1226 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1227 if (!fmt) {
1228 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1229 f->fmt.pix.pixelformat);
1230 return -EINVAL;
1231 }
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001232
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001233 if (dev->board.is_em2800) {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001234 /* the em2800 can only scale down to 50% */
Trent Piephoccb83402009-05-30 21:45:46 -03001235 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1236 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001237 /*
1238 * MaxPacketSize for em2800 is too small to capture at full
1239 * resolution use half of maxw as the scaler can only scale
1240 * to 50%
1241 */
Sascha Sommer1020d132012-01-08 16:54:28 -03001242 if (width == maxw && height == maxh)
1243 width /= 2;
Trent Piephoccb83402009-05-30 21:45:46 -03001244 } else {
1245 /* width must even because of the YUYV format
1246 height must be even because of interlacing */
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001247 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1248 1, 0);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001249 }
1250
Frank Schaefer6b09a212013-02-10 16:05:12 -03001251 size_to_scale(dev, width, height, &hscale, &vscale);
Hans Verkuil46f85972013-03-30 05:31:42 -03001252 scale_to_size(dev, hscale, vscale, &width, &height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001253
1254 f->fmt.pix.width = width;
1255 f->fmt.pix.height = height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001256 f->fmt.pix.pixelformat = fmt->fourcc;
Hans Verkuile6066db2013-02-06 08:14:47 -03001257 f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001258 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001259 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001260 if (dev->progressive)
1261 f->fmt.pix.field = V4L2_FIELD_NONE;
1262 else
1263 f->fmt.pix.field = dev->interlaced ?
1264 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Alban Browaeys51dd4d72013-07-16 19:06:46 -03001265 f->fmt.pix.priv = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001266
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001267 return 0;
1268}
1269
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001270static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
1271 unsigned width, unsigned height)
1272{
1273 struct em28xx_fmt *fmt;
1274
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001275 fmt = format_by_fourcc(fourcc);
1276 if (!fmt)
1277 return -EINVAL;
1278
1279 dev->format = fmt;
1280 dev->width = width;
1281 dev->height = height;
1282
1283 /* set new image size */
Frank Schaefer6b09a212013-02-10 16:05:12 -03001284 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001285
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001286 em28xx_resolution_set(dev);
1287
1288 return 0;
1289}
1290
Hans Verkuil78b526a2008-05-28 12:16:41 -03001291static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001292 struct v4l2_format *f)
1293{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001294 struct em28xx *dev = video_drvdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001295
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001296 if (dev->streaming_users > 0)
1297 return -EBUSY;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001298
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001299 vidioc_try_fmt_vid_cap(file, priv, f);
1300
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001301 return em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001302 f->fmt.pix.width, f->fmt.pix.height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001303}
1304
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001305static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1306{
1307 struct em28xx_fh *fh = priv;
1308 struct em28xx *dev = fh->dev;
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001309
1310 *norm = dev->norm;
1311
1312 return 0;
1313}
1314
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001315static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
1316{
1317 struct em28xx_fh *fh = priv;
1318 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001319
1320 v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm);
1321
1322 return 0;
1323}
1324
Hans Verkuil314527a2013-03-15 06:10:40 -03001325static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001326{
1327 struct em28xx_fh *fh = priv;
1328 struct em28xx *dev = fh->dev;
1329 struct v4l2_format f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001330
Hans Verkuil314527a2013-03-15 06:10:40 -03001331 if (norm == dev->norm)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001332 return 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001333
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001334 if (dev->streaming_users > 0)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001335 return -EBUSY;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001336
Hans Verkuil314527a2013-03-15 06:10:40 -03001337 dev->norm = norm;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001338
1339 /* Adjusts width/height, if needed */
Hans Verkuild8c95c02012-09-07 07:31:54 -03001340 f.fmt.pix.width = 720;
Hans Verkuil314527a2013-03-15 06:10:40 -03001341 f.fmt.pix.height = (norm & V4L2_STD_525_60) ? 480 : 576;
Hans Verkuil78b526a2008-05-28 12:16:41 -03001342 vidioc_try_fmt_vid_cap(file, priv, &f);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001343
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001344 /* set new image size */
1345 dev->width = f.fmt.pix.width;
1346 dev->height = f.fmt.pix.height;
Frank Schaefer6b09a212013-02-10 16:05:12 -03001347 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001348
1349 em28xx_resolution_set(dev);
Hans Verkuilf41737e2009-04-01 03:52:39 -03001350 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001351
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001352 return 0;
1353}
1354
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001355static int vidioc_g_parm(struct file *file, void *priv,
1356 struct v4l2_streamparm *p)
1357{
1358 struct em28xx_fh *fh = priv;
1359 struct em28xx *dev = fh->dev;
1360 int rc = 0;
1361
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001362 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001363 if (dev->board.is_webcam)
1364 rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1365 video, g_parm, p);
1366 else
1367 v4l2_video_std_frame_period(dev->norm,
1368 &p->parm.capture.timeperframe);
1369
1370 return rc;
1371}
1372
1373static int vidioc_s_parm(struct file *file, void *priv,
1374 struct v4l2_streamparm *p)
1375{
1376 struct em28xx_fh *fh = priv;
1377 struct em28xx *dev = fh->dev;
1378
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001379 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001380 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
1381}
1382
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001383static const char *iname[] = {
1384 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
1385 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
1386 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
1387 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
1388 [EM28XX_VMUX_SVIDEO] = "S-Video",
1389 [EM28XX_VMUX_TELEVISION] = "Television",
1390 [EM28XX_VMUX_CABLE] = "Cable TV",
1391 [EM28XX_VMUX_DVB] = "DVB",
1392 [EM28XX_VMUX_DEBUG] = "for debug only",
1393};
1394
1395static int vidioc_enum_input(struct file *file, void *priv,
1396 struct v4l2_input *i)
1397{
1398 struct em28xx_fh *fh = priv;
1399 struct em28xx *dev = fh->dev;
1400 unsigned int n;
1401
1402 n = i->index;
1403 if (n >= MAX_EM28XX_INPUT)
1404 return -EINVAL;
1405 if (0 == INPUT(n)->type)
1406 return -EINVAL;
1407
1408 i->index = n;
1409 i->type = V4L2_INPUT_TYPE_CAMERA;
1410
1411 strcpy(i->name, iname[INPUT(n)->type]);
1412
1413 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
1414 (EM28XX_VMUX_CABLE == INPUT(n)->type))
1415 i->type = V4L2_INPUT_TYPE_TUNER;
1416
Mauro Carvalho Chehab7d497f82007-11-11 14:15:34 -03001417 i->std = dev->vdev->tvnorms;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001418 /* webcams do not have the STD API */
1419 if (dev->board.is_webcam)
1420 i->capabilities = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001421
1422 return 0;
1423}
1424
1425static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1426{
1427 struct em28xx_fh *fh = priv;
1428 struct em28xx *dev = fh->dev;
1429
1430 *i = dev->ctl_input;
1431
1432 return 0;
1433}
1434
1435static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1436{
1437 struct em28xx_fh *fh = priv;
1438 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001439
1440 if (i >= MAX_EM28XX_INPUT)
1441 return -EINVAL;
1442 if (0 == INPUT(i)->type)
1443 return -EINVAL;
1444
Ezequiel García96371fc2012-03-23 18:09:34 -03001445 video_mux(dev, i);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001446 return 0;
1447}
1448
1449static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1450{
1451 struct em28xx_fh *fh = priv;
1452 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001453
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001454 switch (a->index) {
1455 case EM28XX_AMUX_VIDEO:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001456 strcpy(a->name, "Television");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001457 break;
1458 case EM28XX_AMUX_LINE_IN:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001459 strcpy(a->name, "Line In");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001460 break;
1461 case EM28XX_AMUX_VIDEO2:
1462 strcpy(a->name, "Television alt");
1463 break;
1464 case EM28XX_AMUX_PHONE:
1465 strcpy(a->name, "Phone");
1466 break;
1467 case EM28XX_AMUX_MIC:
1468 strcpy(a->name, "Mic");
1469 break;
1470 case EM28XX_AMUX_CD:
1471 strcpy(a->name, "CD");
1472 break;
1473 case EM28XX_AMUX_AUX:
1474 strcpy(a->name, "Aux");
1475 break;
1476 case EM28XX_AMUX_PCM_OUT:
1477 strcpy(a->name, "PCM");
1478 break;
1479 default:
1480 return -EINVAL;
1481 }
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001482
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001483 a->index = dev->ctl_ainput;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001484 a->capability = V4L2_AUDCAP_STEREO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001485
1486 return 0;
1487}
1488
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001489static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001490{
1491 struct em28xx_fh *fh = priv;
1492 struct em28xx *dev = fh->dev;
1493
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03001494 if (a->index >= MAX_EM28XX_INPUT)
1495 return -EINVAL;
1496 if (0 == INPUT(a->index)->type)
1497 return -EINVAL;
1498
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001499 dev->ctl_ainput = INPUT(a->index)->amux;
1500 dev->ctl_aoutput = INPUT(a->index)->aout;
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001501
1502 if (!dev->ctl_aoutput)
1503 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001504
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001505 return 0;
1506}
1507
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001508static int vidioc_g_tuner(struct file *file, void *priv,
1509 struct v4l2_tuner *t)
1510{
1511 struct em28xx_fh *fh = priv;
1512 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001513
1514 if (0 != t->index)
1515 return -EINVAL;
1516
1517 strcpy(t->name, "Tuner");
1518
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001519 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001520 return 0;
1521}
1522
1523static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001524 const struct v4l2_tuner *t)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001525{
1526 struct em28xx_fh *fh = priv;
1527 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001528
1529 if (0 != t->index)
1530 return -EINVAL;
1531
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001532 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001533 return 0;
1534}
1535
1536static int vidioc_g_frequency(struct file *file, void *priv,
1537 struct v4l2_frequency *f)
1538{
1539 struct em28xx_fh *fh = priv;
1540 struct em28xx *dev = fh->dev;
1541
Hans Verkuil20deebf2012-09-06 10:07:25 -03001542 if (0 != f->tuner)
1543 return -EINVAL;
1544
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001545 f->frequency = dev->ctl_freq;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001546 return 0;
1547}
1548
1549static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001550 const struct v4l2_frequency *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001551{
Hans Verkuilb530a442013-03-19 04:09:26 -03001552 struct v4l2_frequency new_freq = *f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001553 struct em28xx_fh *fh = priv;
1554 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001555
1556 if (0 != f->tuner)
1557 return -EINVAL;
1558
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001559 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
Hans Verkuilb530a442013-03-19 04:09:26 -03001560 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
1561 dev->ctl_freq = new_freq.frequency;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001562
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001563 return 0;
1564}
1565
Hans Verkuilcd634f12013-03-27 08:04:23 -03001566#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03001567static int vidioc_g_chip_info(struct file *file, void *priv,
1568 struct v4l2_dbg_chip_info *chip)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001569{
1570 struct em28xx_fh *fh = priv;
1571 struct em28xx *dev = fh->dev;
1572
1573 if (chip->match.addr > 1)
1574 return -EINVAL;
1575 if (chip->match.addr == 1)
1576 strlcpy(chip->name, "ac97", sizeof(chip->name));
1577 else
1578 strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
1579 return 0;
1580}
1581
Frank Schaefer35deba32013-02-07 13:39:19 -03001582static int em28xx_reg_len(int reg)
1583{
1584 switch (reg) {
1585 case EM28XX_R40_AC97LSB:
1586 case EM28XX_R30_HSCALELOW:
1587 case EM28XX_R32_VSCALELOW:
1588 return 2;
1589 default:
1590 return 1;
1591 }
1592}
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001593
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001594static int vidioc_g_register(struct file *file, void *priv,
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001595 struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001596{
1597 struct em28xx_fh *fh = priv;
1598 struct em28xx *dev = fh->dev;
1599 int ret;
1600
Hans Verkuilabca2052013-05-29 06:59:35 -03001601 if (reg->match.addr > 1)
1602 return -EINVAL;
1603 if (reg->match.addr) {
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001604 ret = em28xx_read_ac97(dev, reg->reg);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001605 if (ret < 0)
1606 return ret;
1607
1608 reg->val = ret;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001609 reg->size = 1;
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001610 return 0;
1611 }
1612
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001613 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001614 reg->size = em28xx_reg_len(reg->reg);
1615 if (reg->size == 1) {
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001616 ret = em28xx_read_reg(dev, reg->reg);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001617
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001618 if (ret < 0)
1619 return ret;
1620
1621 reg->val = ret;
1622 } else {
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001623 __le16 val = 0;
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001624 ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001625 reg->reg, (char *)&val, 2);
1626 if (ret < 0)
1627 return ret;
1628
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001629 reg->val = le16_to_cpu(val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001630 }
1631
1632 return 0;
1633}
1634
1635static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001636 const struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001637{
1638 struct em28xx_fh *fh = priv;
1639 struct em28xx *dev = fh->dev;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001640 __le16 buf;
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001641
Hans Verkuilabca2052013-05-29 06:59:35 -03001642 if (reg->match.addr > 1)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001643 return -EINVAL;
Hans Verkuilabca2052013-05-29 06:59:35 -03001644 if (reg->match.addr)
1645 return em28xx_write_ac97(dev, reg->reg, reg->val);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001646
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001647 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001648 buf = cpu_to_le16(reg->val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001649
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001650 return em28xx_write_regs(dev, reg->reg, (char *)&buf,
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001651 em28xx_reg_len(reg->reg));
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001652}
1653#endif
1654
1655
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001656static int vidioc_querycap(struct file *file, void *priv,
1657 struct v4l2_capability *cap)
1658{
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001659 struct video_device *vdev = video_devdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001660 struct em28xx_fh *fh = priv;
1661 struct em28xx *dev = fh->dev;
1662
1663 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1664 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
Thierry MERLEcb977162009-01-20 18:01:33 -03001665 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001666
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001667 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1668 cap->device_caps = V4L2_CAP_READWRITE |
1669 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1670 else if (vdev->vfl_type == VFL_TYPE_RADIO)
1671 cap->device_caps = V4L2_CAP_RADIO;
1672 else
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001673 cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
Devin Heitmueller04146142009-09-11 00:08:44 -03001674
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001675 if (dev->audio_mode.has_audio)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001676 cap->device_caps |= V4L2_CAP_AUDIO;
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001677
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -03001678 if (dev->tuner_type != TUNER_ABSENT)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001679 cap->device_caps |= V4L2_CAP_TUNER;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001680
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001681 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1682 V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1683 if (dev->vbi_dev)
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001684 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001685 if (dev->radio_dev)
1686 cap->capabilities |= V4L2_CAP_RADIO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001687 return 0;
1688}
1689
Hans Verkuil78b526a2008-05-28 12:16:41 -03001690static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001691 struct v4l2_fmtdesc *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001692{
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001693 if (unlikely(f->index >= ARRAY_SIZE(format)))
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001694 return -EINVAL;
1695
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001696 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1697 f->pixelformat = format[f->index].fourcc;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001698
1699 return 0;
1700}
1701
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001702static int vidioc_enum_framesizes(struct file *file, void *priv,
1703 struct v4l2_frmsizeenum *fsize)
1704{
1705 struct em28xx_fh *fh = priv;
1706 struct em28xx *dev = fh->dev;
1707 struct em28xx_fmt *fmt;
1708 unsigned int maxw = norm_maxw(dev);
1709 unsigned int maxh = norm_maxh(dev);
1710
1711 fmt = format_by_fourcc(fsize->pixel_format);
1712 if (!fmt) {
1713 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1714 fsize->pixel_format);
1715 return -EINVAL;
1716 }
1717
1718 if (dev->board.is_em2800) {
1719 if (fsize->index > 1)
1720 return -EINVAL;
1721 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1722 fsize->discrete.width = maxw / (1 + fsize->index);
1723 fsize->discrete.height = maxh / (1 + fsize->index);
1724 return 0;
1725 }
1726
1727 if (fsize->index != 0)
1728 return -EINVAL;
1729
1730 /* Report a continuous range */
1731 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
Frank Schaefer6c3598e2013-02-10 16:05:14 -03001732 scale_to_size(dev, EM28XX_HVSCALE_MAX, EM28XX_HVSCALE_MAX,
1733 &fsize->stepwise.min_width, &fsize->stepwise.min_height);
1734 if (fsize->stepwise.min_width < 48)
1735 fsize->stepwise.min_width = 48;
1736 if (fsize->stepwise.min_height < 38)
1737 fsize->stepwise.min_height = 38;
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001738 fsize->stepwise.max_width = maxw;
1739 fsize->stepwise.max_height = maxh;
1740 fsize->stepwise.step_width = 1;
1741 fsize->stepwise.step_height = 1;
1742 return 0;
1743}
1744
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001745/* RAW VBI ioctls */
1746
1747static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1748 struct v4l2_format *format)
1749{
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001750 struct em28xx_fh *fh = priv;
1751 struct em28xx *dev = fh->dev;
1752
1753 format->fmt.vbi.samples_per_line = dev->vbi_width;
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001754 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1755 format->fmt.vbi.offset = 0;
1756 format->fmt.vbi.flags = 0;
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001757 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1758 format->fmt.vbi.count[0] = dev->vbi_height;
1759 format->fmt.vbi.count[1] = dev->vbi_height;
Hans Verkuil2a221d32012-09-07 08:51:32 -03001760 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001761
1762 /* Varies by video standard (NTSC, PAL, etc.) */
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001763 if (dev->norm & V4L2_STD_525_60) {
1764 /* NTSC */
1765 format->fmt.vbi.start[0] = 10;
1766 format->fmt.vbi.start[1] = 273;
1767 } else if (dev->norm & V4L2_STD_625_50) {
1768 /* PAL */
1769 format->fmt.vbi.start[0] = 6;
1770 format->fmt.vbi.start[1] = 318;
1771 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001772
1773 return 0;
1774}
1775
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001776/* ----------------------------------------------------------- */
1777/* RADIO ESPECIFIC IOCTLS */
1778/* ----------------------------------------------------------- */
1779
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001780static int radio_g_tuner(struct file *file, void *priv,
1781 struct v4l2_tuner *t)
1782{
1783 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1784
1785 if (unlikely(t->index > 0))
1786 return -EINVAL;
1787
1788 strcpy(t->name, "Radio");
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001789
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001790 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001791
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001792 return 0;
1793}
1794
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001795static int radio_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001796 const struct v4l2_tuner *t)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001797{
1798 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1799
1800 if (0 != t->index)
1801 return -EINVAL;
1802
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001803 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001804
1805 return 0;
1806}
1807
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001808/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001809 * em28xx_v4l2_open()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001810 * inits the device and starts isoc transfer
1811 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001812static int em28xx_v4l2_open(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001813{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001814 struct video_device *vdev = video_devdata(filp);
1815 struct em28xx *dev = video_drvdata(filp);
1816 enum v4l2_buf_type fh_type = 0;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001817 struct em28xx_fh *fh;
Markus Rechberger9c755412005-11-08 21:37:52 -08001818
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001819 switch (vdev->vfl_type) {
1820 case VFL_TYPE_GRABBER:
1821 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1822 break;
1823 case VFL_TYPE_VBI:
1824 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1825 break;
Frank Schaefer4e170242014-01-12 13:24:18 -03001826 case VFL_TYPE_RADIO:
1827 break;
1828 default:
1829 return -EINVAL;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001830 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03001831
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001832 em28xx_videodbg("open dev=%s type=%s users=%d\n",
1833 video_device_node_name(vdev), v4l2_type_names[fh_type],
1834 dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001835
Hans Verkuil876cb142012-06-23 08:12:47 -03001836 if (mutex_lock_interruptible(&dev->lock))
1837 return -ERESTARTSYS;
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001838 fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001839 if (!fh) {
1840 em28xx_errdev("em28xx-video.c: Out of memory?!\n");
Hans Verkuil876cb142012-06-23 08:12:47 -03001841 mutex_unlock(&dev->lock);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001842 return -ENOMEM;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001843 }
Hans Verkuil69a61642012-09-07 05:52:40 -03001844 v4l2_fh_init(&fh->fh, vdev);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001845 fh->dev = dev;
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001846 fh->type = fh_type;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001847 filp->private_data = fh;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001848
Frank Schaefer4e170242014-01-12 13:24:18 -03001849 if (dev->users == 0) {
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001850 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001851
Frank Schaefer4e170242014-01-12 13:24:18 -03001852 if (vdev->vfl_type != VFL_TYPE_RADIO)
1853 em28xx_resolution_set(dev);
1854
1855 /*
1856 * Needed, since GPIO might have disabled power
1857 * of some i2c devices
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001858 */
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03001859 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001860 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001861
1862 if (vdev->vfl_type == VFL_TYPE_RADIO) {
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001863 em28xx_videodbg("video_open: setting radio device\n");
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001864 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001865 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001866
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001867 kref_get(&dev->ref);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001868 dev->users++;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001869
Hans Verkuil876cb142012-06-23 08:12:47 -03001870 mutex_unlock(&dev->lock);
Hans Verkuil69a61642012-09-07 05:52:40 -03001871 v4l2_fh_add(&fh->fh);
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001872
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001873 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001874}
1875
1876/*
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001877 * em28xx_v4l2_fini()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001878 * unregisters the v4l2,i2c and usb devices
1879 * called when the device gets disconected or at module unload
1880*/
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001881static int em28xx_v4l2_fini(struct em28xx *dev)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001882{
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03001883 if (dev->is_audio_only) {
1884 /* Shouldn't initialize IR for this interface */
1885 return 0;
1886 }
1887
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001888 if (!dev->has_video) {
1889 /* This device does not support the v4l2 extension */
1890 return 0;
1891 }
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001892
Mauro Carvalho Chehabaa929ad2014-01-12 19:22:07 -03001893 em28xx_info("Closing video extension");
1894
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001895 mutex_lock(&dev->lock);
1896
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001897 v4l2_device_disconnect(&dev->v4l2_dev);
1898
Frank Schaefer23e86422014-01-12 13:24:20 -03001899 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
1900
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001901 if (dev->radio_dev) {
Frank Schaefere8470222014-01-12 13:24:25 -03001902 em28xx_info("V4L2 device %s deregistered\n",
1903 video_device_node_name(dev->radio_dev));
1904 video_unregister_device(dev->radio_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001905 }
1906 if (dev->vbi_dev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001907 em28xx_info("V4L2 device %s deregistered\n",
1908 video_device_node_name(dev->vbi_dev));
Frank Schaefere8470222014-01-12 13:24:25 -03001909 video_unregister_device(dev->vbi_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001910 }
1911 if (dev->vdev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001912 em28xx_info("V4L2 device %s deregistered\n",
1913 video_device_node_name(dev->vdev));
Frank Schaefere8470222014-01-12 13:24:25 -03001914 video_unregister_device(dev->vdev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001915 }
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001916
Frank Schaefer103f18a2014-01-17 14:45:30 -03001917 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1918 v4l2_device_unregister(&dev->v4l2_dev);
1919
Frank Schaefer25dd1652014-01-12 13:24:23 -03001920 if (dev->clk) {
1921 v4l2_clk_unregister_fixed(dev->clk);
1922 dev->clk = NULL;
1923 }
1924
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001925 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001926 kref_put(&dev->ref, em28xx_free_device);
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001927
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001928 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001929}
1930
Shuah Khana61f6812014-02-21 21:50:17 -03001931static int em28xx_v4l2_suspend(struct em28xx *dev)
1932{
1933 if (dev->is_audio_only)
1934 return 0;
1935
1936 if (!dev->has_video)
1937 return 0;
1938
1939 em28xx_info("Suspending video extension");
1940 em28xx_stop_urbs(dev);
1941 return 0;
1942}
1943
1944static int em28xx_v4l2_resume(struct em28xx *dev)
1945{
1946 if (dev->is_audio_only)
1947 return 0;
1948
1949 if (!dev->has_video)
1950 return 0;
1951
1952 em28xx_info("Resuming video extension");
1953 /* what do we do here */
1954 return 0;
1955}
1956
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001957/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001958 * em28xx_v4l2_close()
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001959 * stops streaming and deallocates all resources allocated by the v4l2
1960 * calls and ioctls
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001961 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001962static int em28xx_v4l2_close(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001963{
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001964 struct em28xx_fh *fh = filp->private_data;
1965 struct em28xx *dev = fh->dev;
1966 int errCode;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001967
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001968 em28xx_videodbg("users=%d\n", dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001969
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001970 vb2_fop_release(filp);
Ricardo Ribalda98c24dcd2013-11-06 05:39:35 -03001971 mutex_lock(&dev->lock);
Devin Heitmueller8c873d32009-09-03 00:23:27 -03001972
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001973 if (dev->users == 1) {
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001974 /* No sense to try to write to the device */
1975 if (dev->disconnected)
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001976 goto exit;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001977
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03001978 /* Save some power by putting tuner to sleep */
Laurent Pinchart622b8282009-10-05 10:48:17 -03001979 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03001980
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001981 /* do this before setting alternate! */
Mauro Carvalho Chehab2fe3e2e2008-11-27 09:10:40 -03001982 em28xx_set_mode(dev, EM28XX_SUSPEND);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001983
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001984 /* set alternate 0 */
1985 dev->alt = 0;
1986 em28xx_videodbg("setting alternate 0\n");
1987 errCode = usb_set_interface(dev->udev, 0, 0);
1988 if (errCode < 0) {
1989 em28xx_errdev("cannot change alternate number to "
1990 "0 (error=%i)\n", errCode);
1991 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001992 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001993
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001994exit:
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001995 dev->users--;
Hans Verkuil876cb142012-06-23 08:12:47 -03001996 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001997 kref_put(&dev->ref, em28xx_free_device);
1998
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001999 return 0;
2000}
2001
Frank Schaefere8470222014-01-12 13:24:25 -03002002/*
2003 * em28xx_videodevice_release()
2004 * called when the last user of the video device exits and frees the memeory
2005 */
2006static void em28xx_videodevice_release(struct video_device *vdev)
2007{
2008 struct em28xx *dev = video_get_drvdata(vdev);
2009
2010 video_device_release(vdev);
2011 if (vdev == dev->vdev)
2012 dev->vdev = NULL;
2013 else if (vdev == dev->vbi_dev)
2014 dev->vbi_dev = NULL;
2015 else if (vdev == dev->radio_dev)
2016 dev->radio_dev = NULL;
2017}
2018
Hans Verkuilbec43662008-12-30 06:58:20 -03002019static const struct v4l2_file_operations em28xx_v4l_fops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002020 .owner = THIS_MODULE,
2021 .open = em28xx_v4l2_open,
2022 .release = em28xx_v4l2_close,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002023 .read = vb2_fop_read,
2024 .poll = vb2_fop_poll,
2025 .mmap = vb2_fop_mmap,
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002026 .unlocked_ioctl = video_ioctl2,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002027};
2028
Hans Verkuila3998102008-07-21 02:57:38 -03002029static const struct v4l2_ioctl_ops video_ioctl_ops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002030 .vidioc_querycap = vidioc_querycap,
Hans Verkuil78b526a2008-05-28 12:16:41 -03002031 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
2032 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
2033 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
2034 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller28abf0832009-09-01 01:54:54 -03002035 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil2a221d32012-09-07 08:51:32 -03002036 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Frank Schaeferaab34612013-02-07 13:39:16 -03002037 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02002038 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002039 .vidioc_g_audio = vidioc_g_audio,
2040 .vidioc_s_audio = vidioc_s_audio,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002041
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002042 .vidioc_reqbufs = vb2_ioctl_reqbufs,
2043 .vidioc_create_bufs = vb2_ioctl_create_bufs,
2044 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
2045 .vidioc_querybuf = vb2_ioctl_querybuf,
2046 .vidioc_qbuf = vb2_ioctl_qbuf,
2047 .vidioc_dqbuf = vb2_ioctl_dqbuf,
2048
Devin Heitmueller19bf0032009-09-11 00:40:18 -03002049 .vidioc_g_std = vidioc_g_std,
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03002050 .vidioc_querystd = vidioc_querystd,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002051 .vidioc_s_std = vidioc_s_std,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03002052 .vidioc_g_parm = vidioc_g_parm,
2053 .vidioc_s_parm = vidioc_s_parm,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002054 .vidioc_enum_input = vidioc_enum_input,
2055 .vidioc_g_input = vidioc_g_input,
2056 .vidioc_s_input = vidioc_s_input,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002057 .vidioc_streamon = vb2_ioctl_streamon,
2058 .vidioc_streamoff = vb2_ioctl_streamoff,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002059 .vidioc_g_tuner = vidioc_g_tuner,
2060 .vidioc_s_tuner = vidioc_s_tuner,
2061 .vidioc_g_frequency = vidioc_g_frequency,
2062 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002063 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2064 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002065#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03002066 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002067 .vidioc_g_register = vidioc_g_register,
2068 .vidioc_s_register = vidioc_s_register,
2069#endif
Hans Verkuila3998102008-07-21 02:57:38 -03002070};
2071
2072static const struct video_device em28xx_video_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002073 .fops = &em28xx_v4l_fops,
2074 .ioctl_ops = &video_ioctl_ops,
2075 .release = em28xx_videodevice_release,
2076 .tvnorms = V4L2_STD_ALL,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002077};
2078
Hans Verkuilbec43662008-12-30 06:58:20 -03002079static const struct v4l2_file_operations radio_fops = {
Hans Verkuila3998102008-07-21 02:57:38 -03002080 .owner = THIS_MODULE,
2081 .open = em28xx_v4l2_open,
2082 .release = em28xx_v4l2_close,
Hans Verkuil8fd0bda2010-12-18 09:59:51 -03002083 .unlocked_ioctl = video_ioctl2,
Hans Verkuila3998102008-07-21 02:57:38 -03002084};
2085
2086static const struct v4l2_ioctl_ops radio_ioctl_ops = {
Hans Verkuila9d79fe2012-09-06 07:31:04 -03002087 .vidioc_querycap = vidioc_querycap,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002088 .vidioc_g_tuner = radio_g_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002089 .vidioc_s_tuner = radio_s_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002090 .vidioc_g_frequency = vidioc_g_frequency,
2091 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002092 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2093 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002094#ifdef CONFIG_VIDEO_ADV_DEBUG
Michal Marek430c73f2013-04-16 08:06:30 -03002095 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002096 .vidioc_g_register = vidioc_g_register,
2097 .vidioc_s_register = vidioc_s_register,
2098#endif
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002099};
2100
Hans Verkuila3998102008-07-21 02:57:38 -03002101static struct video_device em28xx_radio_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002102 .fops = &radio_fops,
2103 .ioctl_ops = &radio_ioctl_ops,
2104 .release = em28xx_videodevice_release,
Hans Verkuila3998102008-07-21 02:57:38 -03002105};
2106
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002107/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2108static unsigned short saa711x_addrs[] = {
2109 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2110 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2111 I2C_CLIENT_END };
2112
2113static unsigned short tvp5150_addrs[] = {
2114 0xb8 >> 1,
2115 0xba >> 1,
2116 I2C_CLIENT_END
2117};
2118
2119static unsigned short msp3400_addrs[] = {
2120 0x80 >> 1,
2121 0x88 >> 1,
2122 I2C_CLIENT_END
2123};
2124
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002125/******************************** usb interface ******************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002126
Adrian Bunk532fe652008-01-28 22:10:48 -03002127static struct video_device *em28xx_vdev_init(struct em28xx *dev,
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002128 const struct video_device *template,
2129 const char *type_name)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002130{
2131 struct video_device *vfd;
2132
2133 vfd = video_device_alloc();
2134 if (NULL == vfd)
2135 return NULL;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002136
2137 *vfd = *template;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002138 vfd->v4l2_dev = &dev->v4l2_dev;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002139 vfd->debug = video_debug;
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002140 vfd->lock = &dev->lock;
Hans Verkuil69a61642012-09-07 05:52:40 -03002141 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
Hans Verkuild8c95c02012-09-07 07:31:54 -03002142 if (dev->board.is_webcam)
2143 vfd->tvnorms = 0;
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002144
2145 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
2146 dev->name, type_name);
2147
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002148 video_set_drvdata(vfd, dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002149 return vfd;
2150}
2151
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002152static void em28xx_tuner_setup(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002153{
2154 struct tuner_setup tun_setup;
2155 struct v4l2_frequency f;
2156
2157 if (dev->tuner_type == TUNER_ABSENT)
2158 return;
2159
2160 memset(&tun_setup, 0, sizeof(tun_setup));
2161
2162 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2163 tun_setup.tuner_callback = em28xx_tuner_callback;
2164
2165 if (dev->board.radio.type) {
2166 tun_setup.type = dev->board.radio.type;
2167 tun_setup.addr = dev->board.radio_addr;
2168
2169 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2170 }
2171
2172 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2173 tun_setup.type = dev->tuner_type;
2174 tun_setup.addr = dev->tuner_addr;
2175
2176 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2177 }
2178
2179 if (dev->tda9887_conf) {
2180 struct v4l2_priv_tun_config tda9887_cfg;
2181
2182 tda9887_cfg.tuner = TUNER_TDA9887;
2183 tda9887_cfg.priv = &dev->tda9887_conf;
2184
2185 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
2186 }
2187
2188 if (dev->tuner_type == TUNER_XC2028) {
2189 struct v4l2_priv_tun_config xc2028_cfg;
2190 struct xc2028_ctrl ctl;
2191
2192 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2193 memset(&ctl, 0, sizeof(ctl));
2194
2195 em28xx_setup_xc3028(dev, &ctl);
2196
2197 xc2028_cfg.tuner = TUNER_XC2028;
2198 xc2028_cfg.priv = &ctl;
2199
2200 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
2201 }
2202
2203 /* configure tuner */
2204 f.tuner = 0;
2205 f.type = V4L2_TUNER_ANALOG_TV;
2206 f.frequency = 9076; /* just a magic number */
2207 dev->ctl_freq = f.frequency;
2208 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
2209}
2210
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002211static int em28xx_v4l2_init(struct em28xx *dev)
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002212{
Hans Verkuil081b9452012-09-07 05:43:59 -03002213 u8 val;
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002214 int ret;
Sascha Sommer1020d132012-01-08 16:54:28 -03002215 unsigned int maxw;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002216 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2217
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03002218 if (dev->is_audio_only) {
2219 /* Shouldn't initialize IR for this interface */
2220 return 0;
2221 }
2222
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002223 if (!dev->has_video) {
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002224 /* This device does not support the v4l2 extension */
2225 return 0;
2226 }
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002227
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002228 em28xx_info("Registering V4L2 extension\n");
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002229
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002230 mutex_lock(&dev->lock);
2231
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002232 ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
2233 if (ret < 0) {
2234 em28xx_errdev("Call to v4l2_device_register() failed!\n");
2235 goto err;
2236 }
2237
2238 v4l2_ctrl_handler_init(hdl, 8);
2239 dev->v4l2_dev.ctrl_handler = hdl;
2240
2241 /*
2242 * Default format, used for tvp5150 or saa711x output formats
2243 */
2244 dev->vinmode = 0x10;
2245 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2246 EM28XX_VINCTRL_CCIR656_ENABLE;
2247
2248 /* request some modules */
2249
2250 if (dev->board.has_msp34xx)
2251 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2252 "msp3400", 0, msp3400_addrs);
2253
2254 if (dev->board.decoder == EM28XX_SAA711X)
2255 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2256 "saa7115_auto", 0, saa711x_addrs);
2257
2258 if (dev->board.decoder == EM28XX_TVP5150)
2259 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2260 "tvp5150", 0, tvp5150_addrs);
2261
2262 if (dev->board.adecoder == EM28XX_TVAUDIO)
2263 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2264 "tvaudio", dev->board.tvaudio_addr, NULL);
2265
2266 /* Initialize tuner and camera */
2267
2268 if (dev->board.tuner_type != TUNER_ABSENT) {
2269 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2270
2271 if (dev->board.radio.type)
2272 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2273 "tuner", dev->board.radio_addr, NULL);
2274
2275 if (has_demod)
2276 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2277 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2278 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2279 if (dev->tuner_addr == 0) {
2280 enum v4l2_i2c_tuner_type type =
2281 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2282 struct v4l2_subdev *sd;
2283
2284 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2285 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2286 0, v4l2_i2c_tuner_addrs(type));
2287
2288 if (sd)
2289 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2290 } else {
2291 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2292 "tuner", dev->tuner_addr, NULL);
2293 }
2294 }
2295
2296 em28xx_tuner_setup(dev);
Frank Schaeferd86bc652014-01-17 14:45:32 -03002297 if (dev->em28xx_sensor != EM28XX_NOSENSOR)
2298 em28xx_init_camera(dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002299
2300 /* Configure audio */
2301 ret = em28xx_audio_setup(dev);
2302 if (ret < 0) {
2303 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2304 __func__, ret);
2305 goto unregister_dev;
2306 }
2307 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
2308 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2309 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
2310 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2311 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
2312 } else {
2313 /* install the em28xx notify callback */
2314 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
2315 em28xx_ctrl_notify, dev);
2316 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
2317 em28xx_ctrl_notify, dev);
2318 }
2319
2320 /* wake i2c devices */
2321 em28xx_wake_i2c(dev);
2322
2323 /* init video dma queues */
2324 INIT_LIST_HEAD(&dev->vidq.active);
2325 INIT_LIST_HEAD(&dev->vbiq.active);
2326
2327 if (dev->board.has_msp34xx) {
2328 /* Send a reset to other chips via gpio */
2329 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
2330 if (ret < 0) {
2331 em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
2332 __func__, ret);
2333 goto unregister_dev;
2334 }
2335 msleep(3);
2336
2337 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
2338 if (ret < 0) {
2339 em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
2340 __func__, ret);
2341 goto unregister_dev;
2342 }
2343 msleep(3);
2344 }
2345
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002346 /* set default norm */
Hans Verkuild8c95c02012-09-07 07:31:54 -03002347 dev->norm = V4L2_STD_PAL;
Hans Verkuild5906dd2010-09-26 07:45:15 -03002348 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002349 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002350
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002351 /* Analog specific initialization */
2352 dev->format = &format[0];
Sascha Sommer1020d132012-01-08 16:54:28 -03002353
2354 maxw = norm_maxw(dev);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002355 /* MaxPacketSize for em2800 is too small to capture at full resolution
2356 * use half of maxw as the scaler can only scale to 50% */
2357 if (dev->board.is_em2800)
2358 maxw /= 2;
Sascha Sommer1020d132012-01-08 16:54:28 -03002359
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002360 em28xx_set_video_format(dev, format[0].fourcc,
Sascha Sommer1020d132012-01-08 16:54:28 -03002361 maxw, norm_maxh(dev));
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002362
Ezequiel García96371fc2012-03-23 18:09:34 -03002363 video_mux(dev, 0);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002364
2365 /* Audio defaults */
2366 dev->mute = 1;
2367 dev->volume = 0x1f;
2368
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002369/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002370 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2371 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2372 (EM28XX_XCLK_AUDIO_UNMUTE | val));
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002373
2374 em28xx_set_outfmt(dev);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002375
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002376 /* Add image controls */
2377 /* NOTE: at this point, the subdevices are already registered, so bridge
2378 * controls are only added/enabled when no subdevice provides them */
2379 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_CONTRAST))
2380 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2381 V4L2_CID_CONTRAST,
2382 0, 0x1f, 1, CONTRAST_DEFAULT);
2383 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BRIGHTNESS))
2384 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2385 V4L2_CID_BRIGHTNESS,
2386 -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT);
2387 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SATURATION))
2388 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2389 V4L2_CID_SATURATION,
2390 0, 0x1f, 1, SATURATION_DEFAULT);
2391 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BLUE_BALANCE))
2392 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2393 V4L2_CID_BLUE_BALANCE,
2394 -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT);
2395 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RED_BALANCE))
2396 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2397 V4L2_CID_RED_BALANCE,
2398 -0x30, 0x30, 1, RED_BALANCE_DEFAULT);
2399 if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SHARPNESS))
2400 v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
2401 V4L2_CID_SHARPNESS,
2402 0, 0x0f, 1, SHARPNESS_DEFAULT);
2403
2404 /* Reset image controls */
2405 em28xx_colorlevels_set_default(dev);
2406 v4l2_ctrl_handler_setup(&dev->ctrl_handler);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002407 ret = dev->ctrl_handler.error;
2408 if (ret)
2409 goto unregister_dev;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002410
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002411 /* allocate and fill video video_device struct */
2412 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
2413 if (!dev->vdev) {
2414 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002415 ret = -ENODEV;
2416 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002417 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002418 dev->vdev->queue = &dev->vb_vidq;
2419 dev->vdev->queue->lock = &dev->vb_queue_lock;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002420
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002421 /* disable inapplicable ioctls */
2422 if (dev->board.is_webcam) {
2423 v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD);
2424 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD);
2425 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD);
Frank Schaefer3bc85cc2013-02-07 13:39:12 -03002426 } else {
2427 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002428 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002429 if (dev->tuner_type == TUNER_ABSENT) {
2430 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER);
2431 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_TUNER);
2432 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY);
2433 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY);
2434 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002435 if (!dev->audio_mode.has_audio) {
2436 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_AUDIO);
2437 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_AUDIO);
2438 }
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002439
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002440 /* register v4l2 video video_device */
2441 ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
2442 video_nr[dev->devno]);
2443 if (ret) {
2444 em28xx_errdev("unable to register video device (error=%i).\n",
2445 ret);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002446 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002447 }
2448
2449 /* Allocate and fill vbi video_device struct */
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002450 if (em28xx_vbi_supported(dev) == 1) {
2451 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
2452 "vbi");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002453
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002454 dev->vbi_dev->queue = &dev->vb_vbiq;
2455 dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock;
2456
Frank Schaefer66df67b2013-02-07 13:39:10 -03002457 /* disable inapplicable ioctls */
Frank Schaefer83c8bcc2013-02-07 13:39:13 -03002458 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002459 if (dev->tuner_type == TUNER_ABSENT) {
2460 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER);
2461 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER);
2462 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY);
2463 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY);
2464 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002465 if (!dev->audio_mode.has_audio) {
2466 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_AUDIO);
2467 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_AUDIO);
2468 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002469
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002470 /* register v4l2 vbi video_device */
2471 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
2472 vbi_nr[dev->devno]);
2473 if (ret < 0) {
2474 em28xx_errdev("unable to register vbi device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002475 goto unregister_dev;
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002476 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002477 }
2478
2479 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002480 dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
2481 "radio");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002482 if (!dev->radio_dev) {
2483 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002484 ret = -ENODEV;
2485 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002486 }
2487 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
2488 radio_nr[dev->devno]);
2489 if (ret < 0) {
2490 em28xx_errdev("can't register radio device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002491 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002492 }
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002493 em28xx_info("Registered radio device as %s\n",
2494 video_device_node_name(dev->radio_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002495 }
2496
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002497 em28xx_info("V4L2 video device registered as %s\n",
2498 video_device_node_name(dev->vdev));
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002499
2500 if (dev->vbi_dev)
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002501 em28xx_info("V4L2 VBI device registered as %s\n",
2502 video_device_node_name(dev->vbi_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002503
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002504 /* Save some power by putting tuner to sleep */
2505 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2506
2507 /* initialize videobuf2 stuff */
2508 em28xx_vb2_setup(dev);
2509
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002510 em28xx_info("V4L2 extension successfully initialized\n");
2511
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002512 kref_get(&dev->ref);
2513
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002514 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002515 return 0;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002516
2517unregister_dev:
2518 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2519 v4l2_device_unregister(&dev->v4l2_dev);
2520err:
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002521 mutex_unlock(&dev->lock);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002522 return ret;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002523}
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002524
2525static struct em28xx_ops v4l2_ops = {
2526 .id = EM28XX_V4L2,
2527 .name = "Em28xx v4l2 Extension",
2528 .init = em28xx_v4l2_init,
2529 .fini = em28xx_v4l2_fini,
Shuah Khana61f6812014-02-21 21:50:17 -03002530 .suspend = em28xx_v4l2_suspend,
2531 .resume = em28xx_v4l2_resume,
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002532};
2533
2534static int __init em28xx_video_register(void)
2535{
2536 return em28xx_register_extension(&v4l2_ops);
2537}
2538
2539static void __exit em28xx_video_unregister(void)
2540{
2541 em28xx_unregister_extension(&v4l2_ops);
2542}
2543
2544module_init(em28xx_video_register);
2545module_exit(em28xx_video_unregister);