blob: 0e8f73dfe3232bbf8e49d0c16b570847a71590f1 [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
Frank Schaefer25c61e42014-03-22 10:01:03 -0300144/*FIXME: maxw should be dependent of alt mode */
145static inline unsigned int norm_maxw(struct em28xx *dev)
146{
147 if (dev->board.is_webcam)
148 return dev->sensor_xres;
149
150 if (dev->board.max_range_640_480)
151 return 640;
152
153 return 720;
154}
155
156static inline unsigned int norm_maxh(struct em28xx *dev)
157{
158 if (dev->board.is_webcam)
159 return dev->sensor_yres;
160
161 if (dev->board.max_range_640_480)
162 return 480;
163
164 return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
165}
166
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300167static int em28xx_vbi_supported(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300168{
169 /* Modprobe option to manually disable */
170 if (disable_vbi == 1)
171 return 0;
172
173 if (dev->board.is_webcam)
174 return 0;
175
176 /* FIXME: check subdevices for VBI support */
177
178 if (dev->chip_id == CHIP_ID_EM2860 ||
179 dev->chip_id == CHIP_ID_EM2883)
180 return 1;
181
182 /* Version of em28xx that does not support VBI */
183 return 0;
184}
185
186/*
187 * em28xx_wake_i2c()
188 * configure i2c attached devices
189 */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300190static void em28xx_wake_i2c(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300191{
Frank Schaefer95d26082014-03-24 16:33:09 -0300192 struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev;
193 v4l2_device_call_all(v4l2_dev, 0, core, reset, 0);
194 v4l2_device_call_all(v4l2_dev, 0, video, s_routing,
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300195 INPUT(dev->ctl_input)->vmux, 0, 0);
Frank Schaefer95d26082014-03-24 16:33:09 -0300196 v4l2_device_call_all(v4l2_dev, 0, video, s_stream, 0);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300197}
198
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300199static int em28xx_colorlevels_set_default(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300200{
201 em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT);
202 em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT);
203 em28xx_write_reg(dev, EM28XX_R22_UVGAIN, SATURATION_DEFAULT);
204 em28xx_write_reg(dev, EM28XX_R23_UOFFSET, BLUE_BALANCE_DEFAULT);
205 em28xx_write_reg(dev, EM28XX_R24_VOFFSET, RED_BALANCE_DEFAULT);
206 em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, SHARPNESS_DEFAULT);
207
208 em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
209 em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
210 em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
211 em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
212 em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
213 em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
214 return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
215}
216
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300217static int em28xx_set_outfmt(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300218{
219 int ret;
220 u8 fmt, vinctrl;
221
222 fmt = dev->format->reg;
223 if (!dev->is_em25xx)
224 fmt |= 0x20;
225 /*
226 * NOTE: it's not clear if this is really needed !
227 * The datasheets say bit 5 is a reserved bit and devices seem to work
228 * fine without it. But the Windows driver sets it for em2710/50+em28xx
229 * devices and we've always been setting it, too.
230 *
231 * em2765 (em25xx, em276x/7x/8x) devices do NOT work with this bit set,
232 * it's likely used for an additional (compressed ?) format there.
233 */
234 ret = em28xx_write_reg(dev, EM28XX_R27_OUTFMT, fmt);
235 if (ret < 0)
236 return ret;
237
238 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
239 if (ret < 0)
240 return ret;
241
242 vinctrl = dev->vinctl;
243 if (em28xx_vbi_supported(dev) == 1) {
244 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
245 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
246 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
247 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
248 if (dev->norm & V4L2_STD_525_60) {
249 /* NTSC */
250 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
251 } else if (dev->norm & V4L2_STD_625_50) {
252 /* PAL */
253 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
254 }
255 }
256
257 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
258}
259
260static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
261 u8 ymin, u8 ymax)
262{
263 em28xx_videodbg("em28xx Scale: (%d,%d)-(%d,%d)\n",
264 xmin, ymin, xmax, ymax);
265
266 em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1);
267 em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1);
268 em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1);
269 return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1);
270}
271
272static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
273 u16 width, u16 height)
274{
275 u8 cwidth = width >> 2;
276 u8 cheight = height >> 2;
277 u8 overflow = (height >> 9 & 0x02) | (width >> 10 & 0x01);
278 /* NOTE: size limit: 2047x1023 = 2MPix */
279
280 em28xx_videodbg("capture area set to (%d,%d): %dx%d\n",
281 hstart, vstart,
282 ((overflow & 2) << 9 | cwidth << 2),
283 ((overflow & 1) << 10 | cheight << 2));
284
285 em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1);
286 em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1);
287 em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1);
288 em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1);
289 em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1);
290
291 /* FIXME: function/meaning of these registers ? */
292 /* FIXME: align width+height to multiples of 4 ?! */
293 if (dev->is_em25xx) {
294 em28xx_write_reg(dev, 0x34, width >> 4);
295 em28xx_write_reg(dev, 0x35, height >> 4);
296 }
297}
298
299static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
300{
Frank Schaefercba8e9b2014-03-24 16:28:36 -0300301 u8 mode = 0x00;
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300302 /* the em2800 scaler only supports scaling down to 50% */
303
304 if (dev->board.is_em2800) {
305 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
306 } else {
307 u8 buf[2];
308
309 buf[0] = h;
310 buf[1] = h >> 8;
311 em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2);
312
313 buf[0] = v;
314 buf[1] = v >> 8;
315 em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
316 /* it seems that both H and V scalers must be active
317 to work correctly */
318 mode = (h || v) ? 0x30 : 0x00;
319 }
Frank Schaefercba8e9b2014-03-24 16:28:36 -0300320 return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300321}
322
323/* FIXME: this only function read values from dev */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300324static int em28xx_resolution_set(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300325{
326 int width, height;
327 width = norm_maxw(dev);
328 height = norm_maxh(dev);
329
330 /* Properly setup VBI */
331 dev->vbi_width = 720;
332 if (dev->norm & V4L2_STD_525_60)
333 dev->vbi_height = 12;
334 else
335 dev->vbi_height = 18;
336
337 em28xx_set_outfmt(dev);
338
339 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
340
341 /* If we don't set the start position to 2 in VBI mode, we end up
342 with line 20/21 being YUYV encoded instead of being in 8-bit
343 greyscale. The core of the issue is that line 21 (and line 23 for
344 PAL WSS) are inside of active video region, and as a result they
345 get the pixelformatting associated with that area. So by cropping
346 it out, we end up with the same format as the rest of the VBI
347 region */
348 if (em28xx_vbi_supported(dev) == 1)
349 em28xx_capture_area_set(dev, 0, 2, width, height);
350 else
351 em28xx_capture_area_set(dev, 0, 0, width, height);
352
353 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
354}
355
356/* Set USB alternate setting for analog video */
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -0300357static int em28xx_set_alternate(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300358{
359 int errCode;
360 int i;
361 unsigned int min_pkt_size = dev->width * 2 + 4;
362
363 /* NOTE: for isoc transfers, only alt settings > 0 are allowed
364 bulk transfers seem to work only with alt=0 ! */
365 dev->alt = 0;
366 if ((alt > 0) && (alt < dev->num_alt)) {
367 em28xx_videodbg("alternate forced to %d\n", dev->alt);
368 dev->alt = alt;
369 goto set_alt;
370 }
371 if (dev->analog_xfer_bulk)
372 goto set_alt;
373
374 /* When image size is bigger than a certain value,
375 the frame size should be increased, otherwise, only
376 green screen will be received.
377 */
378 if (dev->width * 2 * dev->height > 720 * 240 * 2)
379 min_pkt_size *= 2;
380
381 for (i = 0; i < dev->num_alt; i++) {
382 /* stop when the selected alt setting offers enough bandwidth */
383 if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) {
384 dev->alt = i;
385 break;
386 /* otherwise make sure that we end up with the maximum bandwidth
387 because the min_pkt_size equation might be wrong...
388 */
389 } else if (dev->alt_max_pkt_size_isoc[i] >
390 dev->alt_max_pkt_size_isoc[dev->alt])
391 dev->alt = i;
392 }
393
394set_alt:
395 /* NOTE: for bulk transfers, we need to call usb_set_interface()
396 * even if the previous settings were the same. Otherwise streaming
397 * fails with all urbs having status = -EOVERFLOW ! */
398 if (dev->analog_xfer_bulk) {
399 dev->max_pkt_size = 512; /* USB 2.0 spec */
400 dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
401 } else { /* isoc */
402 em28xx_videodbg("minimum isoc packet size: %u (alt=%d)\n",
403 min_pkt_size, dev->alt);
404 dev->max_pkt_size =
405 dev->alt_max_pkt_size_isoc[dev->alt];
406 dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS;
407 }
408 em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n",
409 dev->alt, dev->max_pkt_size);
Frank Schaefer961717b2014-01-13 19:02:06 -0300410 errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -0300411 if (errCode < 0) {
412 em28xx_errdev("cannot change alternate number to %d (error=%i)\n",
413 dev->alt, errCode);
414 return errCode;
415 }
416 return 0;
417}
418
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300419/* ------------------------------------------------------------------
420 DMA and thread functions
421 ------------------------------------------------------------------*/
422
423/*
Frank Schaefer948a49a2012-12-08 11:31:25 -0300424 * Finish the current buffer
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300425 */
Frank Schaefer948a49a2012-12-08 11:31:25 -0300426static inline void finish_buffer(struct em28xx *dev,
427 struct em28xx_buffer *buf)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300428{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300429 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field);
430
431 buf->vb.v4l2_buf.sequence = dev->field_count++;
432 buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
433 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
434
435 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300436}
437
438/*
Frank Schaefer36016a32012-12-08 11:31:32 -0300439 * Copy picture data from USB buffer to videobuf buffer
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300440 */
441static void em28xx_copy_video(struct em28xx *dev,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300442 struct em28xx_buffer *buf,
Frank Schaefer36016a32012-12-08 11:31:32 -0300443 unsigned char *usb_buf,
Frank Schaefer4078d622012-12-08 11:31:29 -0300444 unsigned long len)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300445{
446 void *fieldstart, *startwrite, *startread;
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300447 int linesdone, currlinedone, offset, lencopy, remain;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300448 int bytesperline = dev->width << 1;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300449
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300450 if (buf->pos + len > buf->length)
451 len = buf->length - buf->pos;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300452
Frank Schaefer36016a32012-12-08 11:31:32 -0300453 startread = usb_buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300454 remain = len;
455
Frank Schaeferc02ec712012-11-08 14:11:33 -0300456 if (dev->progressive || buf->top_field)
Frank Schaefer36016a32012-12-08 11:31:32 -0300457 fieldstart = buf->vb_buf;
Frank Schaeferc02ec712012-11-08 14:11:33 -0300458 else /* interlaced mode, even nr. of lines */
Frank Schaefer36016a32012-12-08 11:31:32 -0300459 fieldstart = buf->vb_buf + bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300460
Frank Schaefer87325332012-12-08 11:31:27 -0300461 linesdone = buf->pos / bytesperline;
462 currlinedone = buf->pos % bytesperline;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -0300463
464 if (dev->progressive)
465 offset = linesdone * bytesperline + currlinedone;
466 else
467 offset = linesdone * bytesperline * 2 + currlinedone;
468
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300469 startwrite = fieldstart + offset;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300470 lencopy = bytesperline - currlinedone;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300471 lencopy = lencopy > remain ? remain : lencopy;
472
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300473 if ((char *)startwrite + lencopy > (char *)buf->vb_buf + buf->length) {
Mauro Carvalho Chehabea8df7e2008-04-13 14:39:29 -0300474 em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
Frank Schaefer36016a32012-12-08 11:31:32 -0300475 ((char *)startwrite + lencopy) -
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300476 ((char *)buf->vb_buf + buf->length));
477 remain = (char *)buf->vb_buf + buf->length -
Frank Schaefer36016a32012-12-08 11:31:32 -0300478 (char *)startwrite;
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -0300479 lencopy = remain;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300480 }
Aidan Thorntone0fadfd342008-04-13 14:56:02 -0300481 if (lencopy <= 0)
482 return;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300483 memcpy(startwrite, startread, lencopy);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300484
485 remain -= lencopy;
486
487 while (remain > 0) {
Frank Schaeferc02ec712012-11-08 14:11:33 -0300488 if (dev->progressive)
489 startwrite += lencopy;
490 else
491 startwrite += lencopy + bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300492 startread += lencopy;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300493 if (bytesperline > remain)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300494 lencopy = remain;
495 else
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -0300496 lencopy = bytesperline;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300497
Frank Schaefer36016a32012-12-08 11:31:32 -0300498 if ((char *)startwrite + lencopy > (char *)buf->vb_buf +
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300499 buf->length) {
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -0300500 em28xx_isocdbg("Overflow of %zi bytes past buffer end"
501 "(2)\n",
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300502 ((char *)startwrite + lencopy) -
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300503 ((char *)buf->vb_buf + buf->length));
504 lencopy = remain = (char *)buf->vb_buf + buf->length -
505 (char *)startwrite;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300506 }
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300507 if (lencopy <= 0)
508 break;
Aidan Thorntond7aa8022008-04-13 14:38:47 -0300509
510 memcpy(startwrite, startread, lencopy);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300511
512 remain -= lencopy;
513 }
514
Frank Schaefer87325332012-12-08 11:31:27 -0300515 buf->pos += len;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300516}
517
Frank Schaefer36016a32012-12-08 11:31:32 -0300518/*
519 * Copy VBI data from USB buffer to videobuf buffer
520 */
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300521static void em28xx_copy_vbi(struct em28xx *dev,
Frank Schaefer87325332012-12-08 11:31:27 -0300522 struct em28xx_buffer *buf,
Frank Schaefer36016a32012-12-08 11:31:32 -0300523 unsigned char *usb_buf,
Frank Schaefer4078d622012-12-08 11:31:29 -0300524 unsigned long len)
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300525{
Frank Schaefer36016a32012-12-08 11:31:32 -0300526 unsigned int offset;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300527
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300528 if (buf->pos + len > buf->length)
529 len = buf->length - buf->pos;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300530
Frank Schaefer87325332012-12-08 11:31:27 -0300531 offset = buf->pos;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300532 /* Make sure the bottom field populates the second half of the frame */
Frank Schaefer36016a32012-12-08 11:31:32 -0300533 if (buf->top_field == 0)
534 offset += dev->vbi_width * dev->vbi_height;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300535
Frank Schaefer36016a32012-12-08 11:31:32 -0300536 memcpy(buf->vb_buf + offset, usb_buf, len);
Frank Schaefer87325332012-12-08 11:31:27 -0300537 buf->pos += len;
Devin Heitmueller28abf0832009-09-01 01:54:54 -0300538}
539
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300540static inline void print_err_status(struct em28xx *dev,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300541 int packet, int status)
542{
543 char *errmsg = "Unknown";
544
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300545 switch (status) {
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300546 case -ENOENT:
547 errmsg = "unlinked synchronuously";
548 break;
549 case -ECONNRESET:
550 errmsg = "unlinked asynchronuously";
551 break;
552 case -ENOSR:
553 errmsg = "Buffer error (overrun)";
554 break;
555 case -EPIPE:
556 errmsg = "Stalled (device not responding)";
557 break;
558 case -EOVERFLOW:
559 errmsg = "Babble (bad cable?)";
560 break;
561 case -EPROTO:
562 errmsg = "Bit-stuff error (bad cable?)";
563 break;
564 case -EILSEQ:
565 errmsg = "CRC/Timeout (could be anything)";
566 break;
567 case -ETIME:
568 errmsg = "Device does not respond";
569 break;
570 }
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300571 if (packet < 0) {
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300572 em28xx_isocdbg("URB status %d [%s].\n", status, errmsg);
573 } else {
574 em28xx_isocdbg("URB packet %d, status %d [%s].\n",
575 packet, status, errmsg);
576 }
577}
578
579/*
Frank Schaefer24a6d842012-12-08 11:31:24 -0300580 * get the next available buffer from dma queue
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300581 */
Frank Schaefer24a6d842012-12-08 11:31:24 -0300582static inline struct em28xx_buffer *get_next_buf(struct em28xx *dev,
583 struct em28xx_dmaqueue *dma_q)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300584{
Frank Schaefer24a6d842012-12-08 11:31:24 -0300585 struct em28xx_buffer *buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300586
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300587 if (list_empty(&dma_q->active)) {
588 em28xx_isocdbg("No active queue to serve\n");
Frank Schaefer24a6d842012-12-08 11:31:24 -0300589 return NULL;
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300590 }
591
Mauro Carvalho Chehabdbecb442008-04-13 15:08:55 -0300592 /* Get the next buffer */
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300593 buf = list_entry(dma_q->active.next, struct em28xx_buffer, list);
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300594 /* Cleans up buffer - Useful for testing for frame/URB loss */
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300595 list_del(&buf->list);
Frank Schaefer87325332012-12-08 11:31:27 -0300596 buf->pos = 0;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300597 buf->vb_buf = buf->mem;
Mauro Carvalho Chehabcb784722008-04-13 15:06:52 -0300598
Frank Schaefer24a6d842012-12-08 11:31:24 -0300599 return buf;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300600}
601
Frank Schaefere04c00d2012-12-08 11:31:30 -0300602/*
603 * Finish the current buffer if completed and prepare for the next field
604 */
605static struct em28xx_buffer *
606finish_field_prepare_next(struct em28xx *dev,
607 struct em28xx_buffer *buf,
608 struct em28xx_dmaqueue *dma_q)
609{
610 if (dev->progressive || dev->top_field) { /* Brand new frame */
611 if (buf != NULL)
612 finish_buffer(dev, buf);
613 buf = get_next_buf(dev, dma_q);
614 }
615 if (buf != NULL) {
616 buf->top_field = dev->top_field;
617 buf->pos = 0;
618 }
619
620 return buf;
621}
622
Frank Schaefer227b7c92012-12-08 11:31:31 -0300623/*
624 * Process data packet according to the em2710/em2750/em28xx frame data format
625 */
626static inline void process_frame_data_em28xx(struct em28xx *dev,
627 unsigned char *data_pkt,
628 unsigned int data_len)
629{
630 struct em28xx_buffer *buf = dev->usb_ctl.vid_buf;
631 struct em28xx_buffer *vbi_buf = dev->usb_ctl.vbi_buf;
632 struct em28xx_dmaqueue *dma_q = &dev->vidq;
633 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
634
635 /* capture type 0 = vbi start
636 capture type 1 = vbi in progress
637 capture type 2 = video start
638 capture type 3 = video in progress */
639 if (data_len >= 4) {
640 /* NOTE: Headers are always 4 bytes and
641 * never split across packets */
642 if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 &&
643 data_pkt[2] == 0x88 && data_pkt[3] == 0x88) {
644 /* Continuation */
645 data_pkt += 4;
646 data_len -= 4;
647 } else if (data_pkt[0] == 0x33 && data_pkt[1] == 0x95) {
648 /* Field start (VBI mode) */
649 dev->capture_type = 0;
650 dev->vbi_read = 0;
651 em28xx_isocdbg("VBI START HEADER !!!\n");
652 dev->top_field = !(data_pkt[2] & 1);
653 data_pkt += 4;
654 data_len -= 4;
655 } else if (data_pkt[0] == 0x22 && data_pkt[1] == 0x5a) {
656 /* Field start (VBI disabled) */
657 dev->capture_type = 2;
658 em28xx_isocdbg("VIDEO START HEADER !!!\n");
659 dev->top_field = !(data_pkt[2] & 1);
660 data_pkt += 4;
661 data_len -= 4;
662 }
663 }
664 /* NOTE: With bulk transfers, intermediate data packets
665 * have no continuation header */
666
667 if (dev->capture_type == 0) {
668 vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q);
669 dev->usb_ctl.vbi_buf = vbi_buf;
670 dev->capture_type = 1;
671 }
672
673 if (dev->capture_type == 1) {
674 int vbi_size = dev->vbi_width * dev->vbi_height;
675 int vbi_data_len = ((dev->vbi_read + data_len) > vbi_size) ?
676 (vbi_size - dev->vbi_read) : data_len;
677
678 /* Copy VBI data */
679 if (vbi_buf != NULL)
680 em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len);
681 dev->vbi_read += vbi_data_len;
682
683 if (vbi_data_len < data_len) {
684 /* Continue with copying video data */
685 dev->capture_type = 2;
686 data_pkt += vbi_data_len;
687 data_len -= vbi_data_len;
688 }
689 }
690
691 if (dev->capture_type == 2) {
692 buf = finish_field_prepare_next(dev, buf, dma_q);
693 dev->usb_ctl.vid_buf = buf;
694 dev->capture_type = 3;
695 }
696
697 if (dev->capture_type == 3 && buf != NULL && data_len > 0)
698 em28xx_copy_video(dev, buf, data_pkt, data_len);
699}
700
Frank Schaefere507e0e2013-03-26 13:38:38 -0300701/*
702 * Process data packet according to the em25xx/em276x/7x/8x frame data format
703 */
704static inline void process_frame_data_em25xx(struct em28xx *dev,
705 unsigned char *data_pkt,
706 unsigned int data_len)
707{
708 struct em28xx_buffer *buf = dev->usb_ctl.vid_buf;
709 struct em28xx_dmaqueue *dmaq = &dev->vidq;
710 bool frame_end = 0;
711
712 /* Check for header */
713 /* NOTE: at least with bulk transfers, only the first packet
714 * has a header and has always set the FRAME_END bit */
715 if (data_len >= 2) { /* em25xx header is only 2 bytes long */
716 if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) &&
717 ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) {
718 dev->top_field = !(data_pkt[1] &
719 EM25XX_FRMDATAHDR_BYTE2_FRAME_ID);
720 frame_end = data_pkt[1] &
721 EM25XX_FRMDATAHDR_BYTE2_FRAME_END;
722 data_pkt += 2;
723 data_len -= 2;
724 }
725
726 /* Finish field and prepare next (BULK only) */
727 if (dev->analog_xfer_bulk && frame_end) {
728 buf = finish_field_prepare_next(dev, buf, dmaq);
729 dev->usb_ctl.vid_buf = buf;
730 }
731 /* NOTE: in ISOC mode when a new frame starts and buf==NULL,
732 * we COULD already prepare a buffer here to avoid skipping the
733 * first frame.
734 */
735 }
736
737 /* Copy data */
738 if (buf != NULL && data_len > 0)
739 em28xx_copy_video(dev, buf, data_pkt, data_len);
740
741 /* Finish frame (ISOC only) => avoids lag of 1 frame */
742 if (!dev->analog_xfer_bulk && frame_end) {
743 buf = finish_field_prepare_next(dev, buf, dmaq);
744 dev->usb_ctl.vid_buf = buf;
745 }
746
747 /* NOTE: Tested with USB bulk transfers only !
748 * The wording in the datasheet suggests that isoc might work different.
749 * The current code assumes that with isoc transfers each packet has a
750 * header like with the other em28xx devices.
751 */
752 /* NOTE: Support for interlaced mode is pure theory. It has not been
753 * tested and it is unknown if these devices actually support it. */
754 /* NOTE: No VBI support yet (these chips likely do not support VBI). */
755}
756
Frank Schaefer960da932012-11-25 06:37:37 -0300757/* Processes and copies the URB data content (video and VBI data) */
Frank Schaefer0fa4a402012-11-08 14:11:45 -0300758static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300759{
Frank Schaefer227b7c92012-12-08 11:31:31 -0300760 int xfer_bulk, num_packets, i;
761 unsigned char *usb_data_pkt;
762 unsigned int usb_data_len;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300763
764 if (!dev)
765 return 0;
766
Frank Schaefer2665c292012-12-27 19:02:43 -0300767 if (dev->disconnected)
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300768 return 0;
769
Frank Schaefer1653cb0c2012-11-08 14:11:44 -0300770 if (urb->status < 0)
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300771 print_err_status(dev, -1, urb->status);
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300772
Frank Schaefer4601cc32012-11-08 14:11:46 -0300773 xfer_bulk = usb_pipebulk(urb->pipe);
774
Frank Schaefer4601cc32012-11-08 14:11:46 -0300775 if (xfer_bulk) /* bulk */
776 num_packets = 1;
777 else /* isoc */
778 num_packets = urb->number_of_packets;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300779
Frank Schaefer4601cc32012-11-08 14:11:46 -0300780 for (i = 0; i < num_packets; i++) {
781 if (xfer_bulk) { /* bulk */
Frank Schaefer227b7c92012-12-08 11:31:31 -0300782 usb_data_len = urb->actual_length;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300783
Frank Schaefer227b7c92012-12-08 11:31:31 -0300784 usb_data_pkt = urb->transfer_buffer;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300785 } else { /* isoc */
786 if (urb->iso_frame_desc[i].status < 0) {
787 print_err_status(dev, i,
788 urb->iso_frame_desc[i].status);
789 if (urb->iso_frame_desc[i].status != -EPROTO)
790 continue;
791 }
792
Frank Schaefer227b7c92012-12-08 11:31:31 -0300793 usb_data_len = urb->iso_frame_desc[i].actual_length;
794 if (usb_data_len > dev->max_pkt_size) {
Frank Schaefer4601cc32012-11-08 14:11:46 -0300795 em28xx_isocdbg("packet bigger than packet size");
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300796 continue;
Frank Schaefer4601cc32012-11-08 14:11:46 -0300797 }
798
Frank Schaefer227b7c92012-12-08 11:31:31 -0300799 usb_data_pkt = urb->transfer_buffer +
800 urb->iso_frame_desc[i].offset;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300801 }
802
Frank Schaefer227b7c92012-12-08 11:31:31 -0300803 if (usb_data_len == 0) {
Frank Schaefer4601cc32012-11-08 14:11:46 -0300804 /* NOTE: happens very often with isoc transfers */
805 /* em28xx_usbdbg("packet %d is empty",i); - spammy */
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300806 continue;
807 }
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300808
Frank Schaefere507e0e2013-03-26 13:38:38 -0300809 if (dev->is_em25xx)
810 process_frame_data_em25xx(dev,
811 usb_data_pkt, usb_data_len);
812 else
813 process_frame_data_em28xx(dev,
814 usb_data_pkt, usb_data_len);
815
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300816 }
Frank Schaefer227b7c92012-12-08 11:31:31 -0300817 return 1;
Devin Heitmuellerda52a552009-09-01 01:19:46 -0300818}
819
820
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300821static int get_ressource(enum v4l2_buf_type f_type)
822{
823 switch (f_type) {
824 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
825 return EM28XX_RESOURCE_VIDEO;
826 case V4L2_BUF_TYPE_VBI_CAPTURE:
827 return EM28XX_RESOURCE_VBI;
828 default:
829 BUG();
830 return 0;
831 }
832}
833
834/* Usage lock check functions */
835static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type)
836{
837 int res_type = get_ressource(f_type);
838
839 /* is it free? */
840 if (dev->resources & res_type) {
841 /* no, someone else uses it */
842 return -EBUSY;
843 }
844
845 /* it's free, grab it */
846 dev->resources |= res_type;
847 em28xx_videodbg("res: get %d\n", res_type);
848 return 0;
849}
850
851static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type)
852{
853 int res_type = get_ressource(f_type);
854
855 dev->resources &= ~res_type;
856 em28xx_videodbg("res: put %d\n", res_type);
857}
858
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300859/* ------------------------------------------------------------------
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300860 Videobuf2 operations
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300861 ------------------------------------------------------------------*/
862
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300863static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
864 unsigned int *nbuffers, unsigned int *nplanes,
865 unsigned int sizes[], void *alloc_ctxs[])
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300866{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300867 struct em28xx *dev = vb2_get_drv_priv(vq);
868 unsigned long size;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300869
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300870 if (fmt)
871 size = fmt->fmt.pix.sizeimage;
872 else
873 size = (dev->width * dev->height * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -0300874
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300875 if (size == 0)
876 return -EINVAL;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300877
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300878 if (0 == *nbuffers)
879 *nbuffers = 32;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300880
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300881 *nplanes = 1;
882 sizes[0] = size;
Mauro Carvalho Chehabd2d9fbf2008-04-17 21:38:53 -0300883
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300884 return 0;
885}
886
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300887static int
888buffer_prepare(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300889{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300890 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
891 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
892 unsigned long size;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300893
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300894 em28xx_videodbg("%s, field=%d\n", __func__, vb->v4l2_buf.field);
Aidan Thornton3b5fa922008-04-13 15:09:36 -0300895
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300896 size = (dev->width * dev->height * dev->format->depth + 7) >> 3;
Aidan Thornton3b5fa922008-04-13 15:09:36 -0300897
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300898 if (vb2_plane_size(vb, 0) < size) {
899 em28xx_videodbg("%s data will not fit into plane (%lu < %lu)\n",
900 __func__, vb2_plane_size(vb, 0), size);
901 return -EINVAL;
902 }
903 vb2_set_plane_payload(&buf->vb, 0, size);
904
905 return 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300906}
907
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300908int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300909{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300910 struct em28xx *dev = vb2_get_drv_priv(vq);
911 struct v4l2_frequency f;
912 int rc = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300913
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300914 em28xx_videodbg("%s\n", __func__);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300915
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300916 /* Make sure streaming is not already in progress for this type
917 of filehandle (e.g. video, vbi) */
918 rc = res_get(dev, vq->type);
919 if (rc)
920 return rc;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300921
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300922 if (dev->streaming_users == 0) {
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300923 /* First active streaming user, so allocate all the URBs */
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300924
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300925 /* Allocate the USB bandwidth */
926 em28xx_set_alternate(dev);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300927
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300928 /* Needed, since GPIO might have disabled power of
929 some i2c device
930 */
931 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300932
Frank Schaefer0455eeb2012-11-25 06:37:34 -0300933 dev->capture_type = -1;
Frank Schaefer960da932012-11-25 06:37:37 -0300934 rc = em28xx_init_usb_xfer(dev, EM28XX_ANALOG_MODE,
935 dev->analog_xfer_bulk,
936 EM28XX_NUM_BUFS,
937 dev->max_pkt_size,
938 dev->packet_multiplier,
939 em28xx_urb_data_copy);
Mauro Carvalho Chehabf245e542008-04-13 14:41:23 -0300940 if (rc < 0)
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300941 return rc;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300942
943 /*
944 * djh: it's not clear whether this code is still needed. I'm
945 * leaving it in here for now entirely out of concern for
946 * backward compatibility (the old code did it)
947 */
948
949 /* Ask tuner to go to analog or radio mode */
950 memset(&f, 0, sizeof(f));
951 f.frequency = dev->ctl_freq;
952 if (vq->owner && vq->owner->vdev->vfl_type == VFL_TYPE_RADIO)
953 f.type = V4L2_TUNER_RADIO;
954 else
955 f.type = V4L2_TUNER_ANALOG_TV;
Frank Schaefer95d26082014-03-24 16:33:09 -0300956 v4l2_device_call_all(&dev->v4l2->v4l2_dev,
957 0, tuner, s_frequency, &f);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300958 }
959
Frank Schaefer032f1dd2013-10-10 15:31:53 -0300960 dev->streaming_users++;
961
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -0300962 return rc;
963}
964
Hans Verkuile37559b2014-04-17 02:47:21 -0300965static void em28xx_stop_streaming(struct vb2_queue *vq)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300966{
967 struct em28xx *dev = vb2_get_drv_priv(vq);
968 struct em28xx_dmaqueue *vidq = &dev->vidq;
969 unsigned long flags = 0;
970
971 em28xx_videodbg("%s\n", __func__);
972
973 res_free(dev, vq->type);
974
975 if (dev->streaming_users-- == 1) {
976 /* Last active user, so shutdown all the URBS */
977 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
978 }
979
980 spin_lock_irqsave(&dev->slock, flags);
981 while (!list_empty(&vidq->active)) {
982 struct em28xx_buffer *buf;
983 buf = list_entry(vidq->active.next, struct em28xx_buffer, list);
984 list_del(&buf->list);
985 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
986 }
987 dev->usb_ctl.vid_buf = NULL;
988 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300989}
990
Hans Verkuile37559b2014-04-17 02:47:21 -0300991void em28xx_stop_vbi_streaming(struct vb2_queue *vq)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -0300992{
993 struct em28xx *dev = vb2_get_drv_priv(vq);
994 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
995 unsigned long flags = 0;
996
997 em28xx_videodbg("%s\n", __func__);
998
999 res_free(dev, vq->type);
1000
1001 if (dev->streaming_users-- == 1) {
1002 /* Last active user, so shutdown all the URBS */
1003 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
1004 }
1005
1006 spin_lock_irqsave(&dev->slock, flags);
1007 while (!list_empty(&vbiq->active)) {
1008 struct em28xx_buffer *buf;
1009 buf = list_entry(vbiq->active.next, struct em28xx_buffer, list);
1010 list_del(&buf->list);
1011 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
1012 }
1013 dev->usb_ctl.vbi_buf = NULL;
1014 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001015}
1016
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001017static void
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001018buffer_queue(struct vb2_buffer *vb)
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001019{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001020 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
1021 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
1022 struct em28xx_dmaqueue *vidq = &dev->vidq;
1023 unsigned long flags = 0;
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001024
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001025 em28xx_videodbg("%s\n", __func__);
1026 buf->mem = vb2_plane_vaddr(vb, 0);
1027 buf->length = vb2_plane_size(vb, 0);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001028
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001029 spin_lock_irqsave(&dev->slock, flags);
1030 list_add_tail(&buf->list, &vidq->active);
1031 spin_unlock_irqrestore(&dev->slock, flags);
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001032}
1033
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001034static struct vb2_ops em28xx_video_qops = {
1035 .queue_setup = queue_setup,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001036 .buf_prepare = buffer_prepare,
1037 .buf_queue = buffer_queue,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001038 .start_streaming = em28xx_start_analog_streaming,
1039 .stop_streaming = em28xx_stop_streaming,
1040 .wait_prepare = vb2_ops_wait_prepare,
1041 .wait_finish = vb2_ops_wait_finish,
Mauro Carvalho Chehabad0ebb92008-04-13 14:37:52 -03001042};
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001043
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001044static int em28xx_vb2_setup(struct em28xx *dev)
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001045{
1046 int rc;
1047 struct vb2_queue *q;
1048
1049 /* Setup Videobuf2 for Video capture */
1050 q = &dev->vb_vidq;
1051 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Mauro Carvalho Chehabef85cd92013-01-06 00:34:22 -02001052 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
Sakari Ailusade48682014-02-25 19:12:19 -03001053 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001054 q->drv_priv = dev;
1055 q->buf_struct_size = sizeof(struct em28xx_buffer);
1056 q->ops = &em28xx_video_qops;
1057 q->mem_ops = &vb2_vmalloc_memops;
1058
1059 rc = vb2_queue_init(q);
1060 if (rc < 0)
1061 return rc;
1062
1063 /* Setup Videobuf2 for VBI capture */
1064 q = &dev->vb_vbiq;
1065 q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1066 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR;
Sakari Ailusade48682014-02-25 19:12:19 -03001067 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001068 q->drv_priv = dev;
1069 q->buf_struct_size = sizeof(struct em28xx_buffer);
1070 q->ops = &em28xx_vbi_qops;
1071 q->mem_ops = &vb2_vmalloc_memops;
1072
1073 rc = vb2_queue_init(q);
1074 if (rc < 0)
1075 return rc;
1076
1077 return 0;
1078}
1079
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001080/********************* v4l2 interface **************************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001081
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001082static void video_mux(struct em28xx *dev, int index)
1083{
Frank Schaefer95d26082014-03-24 16:33:09 -03001084 struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev;
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001085 dev->ctl_input = index;
1086 dev->ctl_ainput = INPUT(index)->amux;
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001087 dev->ctl_aoutput = INPUT(index)->aout;
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001088
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001089 if (!dev->ctl_aoutput)
1090 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
1091
Frank Schaefer95d26082014-03-24 16:33:09 -03001092 v4l2_device_call_all(v4l2_dev, 0, video, s_routing,
Hans Verkuil5325b422009-04-02 11:26:22 -03001093 INPUT(index)->vmux, 0, 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001094
Mauro Carvalho Chehab505b6d02008-11-25 09:39:50 -03001095 if (dev->board.has_msp34xx) {
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001096 if (dev->i2s_speed) {
Frank Schaefer95d26082014-03-24 16:33:09 -03001097 v4l2_device_call_all(v4l2_dev, 0, audio,
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03001098 s_i2s_clock_freq, dev->i2s_speed);
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001099 }
Hans Verkuil2474ed42006-03-19 12:35:57 -03001100 /* Note: this is msp3400 specific */
Frank Schaefer95d26082014-03-24 16:33:09 -03001101 v4l2_device_call_all(v4l2_dev, 0, audio, s_routing,
Hans Verkuil5325b422009-04-02 11:26:22 -03001102 dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001103 }
Mauro Carvalho Chehab539c96d2008-01-05 09:53:54 -03001104
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001105 if (dev->board.adecoder != EM28XX_NOADECODER) {
Frank Schaefer95d26082014-03-24 16:33:09 -03001106 v4l2_device_call_all(v4l2_dev, 0, audio, s_routing,
Hans Verkuil5325b422009-04-02 11:26:22 -03001107 dev->ctl_ainput, dev->ctl_aoutput, 0);
Vitaly Wool2bd1d9e2009-03-04 08:27:52 -03001108 }
1109
Mauro Carvalho Chehab00b87302008-02-06 18:34:13 -03001110 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08001111}
1112
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001113static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001114{
Hans Verkuil081b9452012-09-07 05:43:59 -03001115 struct em28xx *dev = priv;
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001116
Hans Verkuil081b9452012-09-07 05:43:59 -03001117 /*
1118 * In the case of non-AC97 volume controls, we still need
1119 * to do some setups at em28xx, in order to mute/unmute
1120 * and to adjust audio volume. However, the value ranges
1121 * should be checked by the corresponding V4L subdriver.
1122 */
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001123 switch (ctrl->id) {
1124 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil081b9452012-09-07 05:43:59 -03001125 dev->mute = ctrl->val;
1126 em28xx_audio_analog_set(dev);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001127 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001128 case V4L2_CID_AUDIO_VOLUME:
Hans Verkuil081b9452012-09-07 05:43:59 -03001129 dev->volume = ctrl->val;
1130 em28xx_audio_analog_set(dev);
1131 break;
1132 }
1133}
1134
1135static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
1136{
Frank Schaeferabc13082014-03-24 16:33:10 -03001137 struct em28xx_v4l2 *v4l2 =
1138 container_of(ctrl->handler, struct em28xx_v4l2, ctrl_handler);
1139 struct em28xx *dev = v4l2->dev;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001140 int ret = -EINVAL;
Hans Verkuil081b9452012-09-07 05:43:59 -03001141
1142 switch (ctrl->id) {
1143 case V4L2_CID_AUDIO_MUTE:
1144 dev->mute = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001145 ret = em28xx_audio_analog_set(dev);
Hans Verkuil081b9452012-09-07 05:43:59 -03001146 break;
1147 case V4L2_CID_AUDIO_VOLUME:
1148 dev->volume = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001149 ret = em28xx_audio_analog_set(dev);
1150 break;
1151 case V4L2_CID_CONTRAST:
1152 ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val);
1153 break;
1154 case V4L2_CID_BRIGHTNESS:
1155 ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val);
1156 break;
1157 case V4L2_CID_SATURATION:
1158 ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val);
1159 break;
1160 case V4L2_CID_BLUE_BALANCE:
1161 ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val);
1162 break;
1163 case V4L2_CID_RED_BALANCE:
1164 ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val);
1165 break;
1166 case V4L2_CID_SHARPNESS:
1167 ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001168 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001169 }
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001170
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001171 return (ret < 0) ? ret : 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001172}
1173
Fengguang Wu8068eb82014-01-07 12:50:47 -03001174static const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
Hans Verkuil081b9452012-09-07 05:43:59 -03001175 .s_ctrl = em28xx_s_ctrl,
1176};
1177
Frank Schaefer6b09a212013-02-10 16:05:12 -03001178static void size_to_scale(struct em28xx *dev,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001179 unsigned int width, unsigned int height,
1180 unsigned int *hscale, unsigned int *vscale)
1181{
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001182 unsigned int maxw = norm_maxw(dev);
1183 unsigned int maxh = norm_maxh(dev);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001184
1185 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001186 if (*hscale > EM28XX_HVSCALE_MAX)
1187 *hscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001188
1189 *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001190 if (*vscale > EM28XX_HVSCALE_MAX)
1191 *vscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001192}
1193
Frank Schaeferb8374132013-02-10 16:05:13 -03001194static void scale_to_size(struct em28xx *dev,
1195 unsigned int hscale, unsigned int vscale,
1196 unsigned int *width, unsigned int *height)
1197{
1198 unsigned int maxw = norm_maxw(dev);
1199 unsigned int maxh = norm_maxh(dev);
1200
1201 *width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
1202 *height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
1203}
1204
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001205/* ------------------------------------------------------------------
1206 IOCTL vidioc handling
1207 ------------------------------------------------------------------*/
1208
Hans Verkuil78b526a2008-05-28 12:16:41 -03001209static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001210 struct v4l2_format *f)
1211{
1212 struct em28xx_fh *fh = priv;
1213 struct em28xx *dev = fh->dev;
1214
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001215 f->fmt.pix.width = dev->width;
1216 f->fmt.pix.height = dev->height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001217 f->fmt.pix.pixelformat = dev->format->fourcc;
1218 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -03001219 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001220 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1221
1222 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001223 if (dev->progressive)
1224 f->fmt.pix.field = V4L2_FIELD_NONE;
1225 else
1226 f->fmt.pix.field = dev->interlaced ?
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001227 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001228 return 0;
1229}
1230
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001231static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
1232{
1233 unsigned int i;
1234
1235 for (i = 0; i < ARRAY_SIZE(format); i++)
1236 if (format[i].fourcc == fourcc)
1237 return &format[i];
1238
1239 return NULL;
1240}
1241
Hans Verkuil78b526a2008-05-28 12:16:41 -03001242static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001243 struct v4l2_format *f)
1244{
1245 struct em28xx_fh *fh = priv;
1246 struct em28xx *dev = fh->dev;
Trent Piephoccb83402009-05-30 21:45:46 -03001247 unsigned int width = f->fmt.pix.width;
1248 unsigned int height = f->fmt.pix.height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001249 unsigned int maxw = norm_maxw(dev);
1250 unsigned int maxh = norm_maxh(dev);
1251 unsigned int hscale, vscale;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001252 struct em28xx_fmt *fmt;
1253
1254 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1255 if (!fmt) {
1256 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1257 f->fmt.pix.pixelformat);
1258 return -EINVAL;
1259 }
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001260
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001261 if (dev->board.is_em2800) {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001262 /* the em2800 can only scale down to 50% */
Trent Piephoccb83402009-05-30 21:45:46 -03001263 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1264 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001265 /*
1266 * MaxPacketSize for em2800 is too small to capture at full
1267 * resolution use half of maxw as the scaler can only scale
1268 * to 50%
1269 */
Sascha Sommer1020d132012-01-08 16:54:28 -03001270 if (width == maxw && height == maxh)
1271 width /= 2;
Trent Piephoccb83402009-05-30 21:45:46 -03001272 } else {
1273 /* width must even because of the YUYV format
1274 height must be even because of interlacing */
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001275 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1276 1, 0);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001277 }
1278
Frank Schaefer6b09a212013-02-10 16:05:12 -03001279 size_to_scale(dev, width, height, &hscale, &vscale);
Hans Verkuil46f85972013-03-30 05:31:42 -03001280 scale_to_size(dev, hscale, vscale, &width, &height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001281
1282 f->fmt.pix.width = width;
1283 f->fmt.pix.height = height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001284 f->fmt.pix.pixelformat = fmt->fourcc;
Hans Verkuile6066db2013-02-06 08:14:47 -03001285 f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001286 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001287 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001288 if (dev->progressive)
1289 f->fmt.pix.field = V4L2_FIELD_NONE;
1290 else
1291 f->fmt.pix.field = dev->interlaced ?
1292 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Alban Browaeys51dd4d72013-07-16 19:06:46 -03001293 f->fmt.pix.priv = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001294
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001295 return 0;
1296}
1297
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001298static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
1299 unsigned width, unsigned height)
1300{
1301 struct em28xx_fmt *fmt;
1302
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001303 fmt = format_by_fourcc(fourcc);
1304 if (!fmt)
1305 return -EINVAL;
1306
1307 dev->format = fmt;
1308 dev->width = width;
1309 dev->height = height;
1310
1311 /* set new image size */
Frank Schaefer6b09a212013-02-10 16:05:12 -03001312 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001313
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001314 em28xx_resolution_set(dev);
1315
1316 return 0;
1317}
1318
Hans Verkuil78b526a2008-05-28 12:16:41 -03001319static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001320 struct v4l2_format *f)
1321{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001322 struct em28xx *dev = video_drvdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001323
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001324 if (dev->streaming_users > 0)
1325 return -EBUSY;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001326
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001327 vidioc_try_fmt_vid_cap(file, priv, f);
1328
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001329 return em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001330 f->fmt.pix.width, f->fmt.pix.height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001331}
1332
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001333static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1334{
1335 struct em28xx_fh *fh = priv;
1336 struct em28xx *dev = fh->dev;
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001337
1338 *norm = dev->norm;
1339
1340 return 0;
1341}
1342
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001343static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
1344{
1345 struct em28xx_fh *fh = priv;
1346 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001347
Frank Schaefer95d26082014-03-24 16:33:09 -03001348 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, video, querystd, norm);
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001349
1350 return 0;
1351}
1352
Hans Verkuil314527a2013-03-15 06:10:40 -03001353static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001354{
1355 struct em28xx_fh *fh = priv;
1356 struct em28xx *dev = fh->dev;
1357 struct v4l2_format f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001358
Hans Verkuil314527a2013-03-15 06:10:40 -03001359 if (norm == dev->norm)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001360 return 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001361
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001362 if (dev->streaming_users > 0)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001363 return -EBUSY;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001364
Hans Verkuil314527a2013-03-15 06:10:40 -03001365 dev->norm = norm;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001366
1367 /* Adjusts width/height, if needed */
Hans Verkuild8c95c02012-09-07 07:31:54 -03001368 f.fmt.pix.width = 720;
Hans Verkuil314527a2013-03-15 06:10:40 -03001369 f.fmt.pix.height = (norm & V4L2_STD_525_60) ? 480 : 576;
Hans Verkuil78b526a2008-05-28 12:16:41 -03001370 vidioc_try_fmt_vid_cap(file, priv, &f);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001371
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001372 /* set new image size */
1373 dev->width = f.fmt.pix.width;
1374 dev->height = f.fmt.pix.height;
Frank Schaefer6b09a212013-02-10 16:05:12 -03001375 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001376
1377 em28xx_resolution_set(dev);
Frank Schaefer95d26082014-03-24 16:33:09 -03001378 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001379
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001380 return 0;
1381}
1382
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001383static int vidioc_g_parm(struct file *file, void *priv,
1384 struct v4l2_streamparm *p)
1385{
1386 struct em28xx_fh *fh = priv;
1387 struct em28xx *dev = fh->dev;
1388 int rc = 0;
1389
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001390 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001391 if (dev->board.is_webcam)
Frank Schaefer95d26082014-03-24 16:33:09 -03001392 rc = v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, 0,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001393 video, g_parm, p);
1394 else
1395 v4l2_video_std_frame_period(dev->norm,
1396 &p->parm.capture.timeperframe);
1397
1398 return rc;
1399}
1400
1401static int vidioc_s_parm(struct file *file, void *priv,
1402 struct v4l2_streamparm *p)
1403{
1404 struct em28xx_fh *fh = priv;
1405 struct em28xx *dev = fh->dev;
1406
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001407 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Frank Schaefer95d26082014-03-24 16:33:09 -03001408 return v4l2_device_call_until_err(&dev->v4l2->v4l2_dev,
1409 0, video, s_parm, p);
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001410}
1411
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001412static const char *iname[] = {
1413 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
1414 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
1415 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
1416 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
1417 [EM28XX_VMUX_SVIDEO] = "S-Video",
1418 [EM28XX_VMUX_TELEVISION] = "Television",
1419 [EM28XX_VMUX_CABLE] = "Cable TV",
1420 [EM28XX_VMUX_DVB] = "DVB",
1421 [EM28XX_VMUX_DEBUG] = "for debug only",
1422};
1423
1424static int vidioc_enum_input(struct file *file, void *priv,
1425 struct v4l2_input *i)
1426{
1427 struct em28xx_fh *fh = priv;
1428 struct em28xx *dev = fh->dev;
1429 unsigned int n;
1430
1431 n = i->index;
1432 if (n >= MAX_EM28XX_INPUT)
1433 return -EINVAL;
1434 if (0 == INPUT(n)->type)
1435 return -EINVAL;
1436
1437 i->index = n;
1438 i->type = V4L2_INPUT_TYPE_CAMERA;
1439
1440 strcpy(i->name, iname[INPUT(n)->type]);
1441
1442 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
1443 (EM28XX_VMUX_CABLE == INPUT(n)->type))
1444 i->type = V4L2_INPUT_TYPE_TUNER;
1445
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001446 i->std = dev->v4l2->vdev->tvnorms;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001447 /* webcams do not have the STD API */
1448 if (dev->board.is_webcam)
1449 i->capabilities = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001450
1451 return 0;
1452}
1453
1454static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1455{
1456 struct em28xx_fh *fh = priv;
1457 struct em28xx *dev = fh->dev;
1458
1459 *i = dev->ctl_input;
1460
1461 return 0;
1462}
1463
1464static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1465{
1466 struct em28xx_fh *fh = priv;
1467 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001468
1469 if (i >= MAX_EM28XX_INPUT)
1470 return -EINVAL;
1471 if (0 == INPUT(i)->type)
1472 return -EINVAL;
1473
Ezequiel García96371fc2012-03-23 18:09:34 -03001474 video_mux(dev, i);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001475 return 0;
1476}
1477
1478static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1479{
1480 struct em28xx_fh *fh = priv;
1481 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001482
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001483 switch (a->index) {
1484 case EM28XX_AMUX_VIDEO:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001485 strcpy(a->name, "Television");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001486 break;
1487 case EM28XX_AMUX_LINE_IN:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001488 strcpy(a->name, "Line In");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001489 break;
1490 case EM28XX_AMUX_VIDEO2:
1491 strcpy(a->name, "Television alt");
1492 break;
1493 case EM28XX_AMUX_PHONE:
1494 strcpy(a->name, "Phone");
1495 break;
1496 case EM28XX_AMUX_MIC:
1497 strcpy(a->name, "Mic");
1498 break;
1499 case EM28XX_AMUX_CD:
1500 strcpy(a->name, "CD");
1501 break;
1502 case EM28XX_AMUX_AUX:
1503 strcpy(a->name, "Aux");
1504 break;
1505 case EM28XX_AMUX_PCM_OUT:
1506 strcpy(a->name, "PCM");
1507 break;
1508 default:
1509 return -EINVAL;
1510 }
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001511
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001512 a->index = dev->ctl_ainput;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001513 a->capability = V4L2_AUDCAP_STEREO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001514
1515 return 0;
1516}
1517
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001518static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001519{
1520 struct em28xx_fh *fh = priv;
1521 struct em28xx *dev = fh->dev;
1522
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03001523 if (a->index >= MAX_EM28XX_INPUT)
1524 return -EINVAL;
1525 if (0 == INPUT(a->index)->type)
1526 return -EINVAL;
1527
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001528 dev->ctl_ainput = INPUT(a->index)->amux;
1529 dev->ctl_aoutput = INPUT(a->index)->aout;
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001530
1531 if (!dev->ctl_aoutput)
1532 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001533
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001534 return 0;
1535}
1536
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001537static int vidioc_g_tuner(struct file *file, void *priv,
1538 struct v4l2_tuner *t)
1539{
1540 struct em28xx_fh *fh = priv;
1541 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001542
1543 if (0 != t->index)
1544 return -EINVAL;
1545
1546 strcpy(t->name, "Tuner");
1547
Frank Schaefer95d26082014-03-24 16:33:09 -03001548 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001549 return 0;
1550}
1551
1552static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001553 const struct v4l2_tuner *t)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001554{
1555 struct em28xx_fh *fh = priv;
1556 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001557
1558 if (0 != t->index)
1559 return -EINVAL;
1560
Frank Schaefer95d26082014-03-24 16:33:09 -03001561 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001562 return 0;
1563}
1564
1565static int vidioc_g_frequency(struct file *file, void *priv,
1566 struct v4l2_frequency *f)
1567{
1568 struct em28xx_fh *fh = priv;
1569 struct em28xx *dev = fh->dev;
1570
Hans Verkuil20deebf2012-09-06 10:07:25 -03001571 if (0 != f->tuner)
1572 return -EINVAL;
1573
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001574 f->frequency = dev->ctl_freq;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001575 return 0;
1576}
1577
1578static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001579 const struct v4l2_frequency *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001580{
Frank Schaefer95d26082014-03-24 16:33:09 -03001581 struct v4l2_frequency new_freq = *f;
1582 struct em28xx_fh *fh = priv;
1583 struct em28xx *dev = fh->dev;
1584 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001585
1586 if (0 != f->tuner)
1587 return -EINVAL;
1588
Frank Schaefer95d26082014-03-24 16:33:09 -03001589 v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_frequency, f);
1590 v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, g_frequency, &new_freq);
Hans Verkuilb530a442013-03-19 04:09:26 -03001591 dev->ctl_freq = new_freq.frequency;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001592
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001593 return 0;
1594}
1595
Hans Verkuilcd634f12013-03-27 08:04:23 -03001596#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03001597static int vidioc_g_chip_info(struct file *file, void *priv,
1598 struct v4l2_dbg_chip_info *chip)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001599{
1600 struct em28xx_fh *fh = priv;
1601 struct em28xx *dev = fh->dev;
1602
1603 if (chip->match.addr > 1)
1604 return -EINVAL;
1605 if (chip->match.addr == 1)
1606 strlcpy(chip->name, "ac97", sizeof(chip->name));
1607 else
Frank Schaefer95d26082014-03-24 16:33:09 -03001608 strlcpy(chip->name,
1609 dev->v4l2->v4l2_dev.name, sizeof(chip->name));
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001610 return 0;
1611}
1612
Frank Schaefer35deba32013-02-07 13:39:19 -03001613static int em28xx_reg_len(int reg)
1614{
1615 switch (reg) {
1616 case EM28XX_R40_AC97LSB:
1617 case EM28XX_R30_HSCALELOW:
1618 case EM28XX_R32_VSCALELOW:
1619 return 2;
1620 default:
1621 return 1;
1622 }
1623}
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001624
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001625static int vidioc_g_register(struct file *file, void *priv,
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001626 struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001627{
1628 struct em28xx_fh *fh = priv;
1629 struct em28xx *dev = fh->dev;
1630 int ret;
1631
Hans Verkuilabca2052013-05-29 06:59:35 -03001632 if (reg->match.addr > 1)
1633 return -EINVAL;
1634 if (reg->match.addr) {
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001635 ret = em28xx_read_ac97(dev, reg->reg);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001636 if (ret < 0)
1637 return ret;
1638
1639 reg->val = ret;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001640 reg->size = 1;
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001641 return 0;
1642 }
1643
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001644 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001645 reg->size = em28xx_reg_len(reg->reg);
1646 if (reg->size == 1) {
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001647 ret = em28xx_read_reg(dev, reg->reg);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001648
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001649 if (ret < 0)
1650 return ret;
1651
1652 reg->val = ret;
1653 } else {
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001654 __le16 val = 0;
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001655 ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001656 reg->reg, (char *)&val, 2);
1657 if (ret < 0)
1658 return ret;
1659
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001660 reg->val = le16_to_cpu(val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001661 }
1662
1663 return 0;
1664}
1665
1666static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001667 const struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001668{
1669 struct em28xx_fh *fh = priv;
1670 struct em28xx *dev = fh->dev;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001671 __le16 buf;
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001672
Hans Verkuilabca2052013-05-29 06:59:35 -03001673 if (reg->match.addr > 1)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001674 return -EINVAL;
Hans Verkuilabca2052013-05-29 06:59:35 -03001675 if (reg->match.addr)
1676 return em28xx_write_ac97(dev, reg->reg, reg->val);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001677
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001678 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001679 buf = cpu_to_le16(reg->val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001680
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001681 return em28xx_write_regs(dev, reg->reg, (char *)&buf,
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001682 em28xx_reg_len(reg->reg));
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001683}
1684#endif
1685
1686
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001687static int vidioc_querycap(struct file *file, void *priv,
1688 struct v4l2_capability *cap)
1689{
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001690 struct video_device *vdev = video_devdata(file);
1691 struct em28xx_fh *fh = priv;
1692 struct em28xx *dev = fh->dev;
1693 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001694
1695 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1696 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
Thierry MERLEcb977162009-01-20 18:01:33 -03001697 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001698
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001699 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1700 cap->device_caps = V4L2_CAP_READWRITE |
1701 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1702 else if (vdev->vfl_type == VFL_TYPE_RADIO)
1703 cap->device_caps = V4L2_CAP_RADIO;
1704 else
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001705 cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
Devin Heitmueller04146142009-09-11 00:08:44 -03001706
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001707 if (dev->audio_mode.has_audio)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001708 cap->device_caps |= V4L2_CAP_AUDIO;
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001709
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -03001710 if (dev->tuner_type != TUNER_ABSENT)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001711 cap->device_caps |= V4L2_CAP_TUNER;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001712
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001713 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1714 V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001715 if (v4l2->vbi_dev)
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001716 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001717 if (v4l2->radio_dev)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001718 cap->capabilities |= V4L2_CAP_RADIO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001719 return 0;
1720}
1721
Hans Verkuil78b526a2008-05-28 12:16:41 -03001722static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001723 struct v4l2_fmtdesc *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001724{
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001725 if (unlikely(f->index >= ARRAY_SIZE(format)))
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001726 return -EINVAL;
1727
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001728 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1729 f->pixelformat = format[f->index].fourcc;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001730
1731 return 0;
1732}
1733
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001734static int vidioc_enum_framesizes(struct file *file, void *priv,
1735 struct v4l2_frmsizeenum *fsize)
1736{
1737 struct em28xx_fh *fh = priv;
1738 struct em28xx *dev = fh->dev;
1739 struct em28xx_fmt *fmt;
1740 unsigned int maxw = norm_maxw(dev);
1741 unsigned int maxh = norm_maxh(dev);
1742
1743 fmt = format_by_fourcc(fsize->pixel_format);
1744 if (!fmt) {
1745 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1746 fsize->pixel_format);
1747 return -EINVAL;
1748 }
1749
1750 if (dev->board.is_em2800) {
1751 if (fsize->index > 1)
1752 return -EINVAL;
1753 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1754 fsize->discrete.width = maxw / (1 + fsize->index);
1755 fsize->discrete.height = maxh / (1 + fsize->index);
1756 return 0;
1757 }
1758
1759 if (fsize->index != 0)
1760 return -EINVAL;
1761
1762 /* Report a continuous range */
1763 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
Frank Schaefer6c3598e2013-02-10 16:05:14 -03001764 scale_to_size(dev, EM28XX_HVSCALE_MAX, EM28XX_HVSCALE_MAX,
1765 &fsize->stepwise.min_width, &fsize->stepwise.min_height);
1766 if (fsize->stepwise.min_width < 48)
1767 fsize->stepwise.min_width = 48;
1768 if (fsize->stepwise.min_height < 38)
1769 fsize->stepwise.min_height = 38;
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001770 fsize->stepwise.max_width = maxw;
1771 fsize->stepwise.max_height = maxh;
1772 fsize->stepwise.step_width = 1;
1773 fsize->stepwise.step_height = 1;
1774 return 0;
1775}
1776
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001777/* RAW VBI ioctls */
1778
1779static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1780 struct v4l2_format *format)
1781{
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001782 struct em28xx_fh *fh = priv;
1783 struct em28xx *dev = fh->dev;
1784
1785 format->fmt.vbi.samples_per_line = dev->vbi_width;
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001786 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1787 format->fmt.vbi.offset = 0;
1788 format->fmt.vbi.flags = 0;
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001789 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1790 format->fmt.vbi.count[0] = dev->vbi_height;
1791 format->fmt.vbi.count[1] = dev->vbi_height;
Hans Verkuil2a221d32012-09-07 08:51:32 -03001792 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001793
1794 /* Varies by video standard (NTSC, PAL, etc.) */
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001795 if (dev->norm & V4L2_STD_525_60) {
1796 /* NTSC */
1797 format->fmt.vbi.start[0] = 10;
1798 format->fmt.vbi.start[1] = 273;
1799 } else if (dev->norm & V4L2_STD_625_50) {
1800 /* PAL */
1801 format->fmt.vbi.start[0] = 6;
1802 format->fmt.vbi.start[1] = 318;
1803 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001804
1805 return 0;
1806}
1807
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001808/* ----------------------------------------------------------- */
1809/* RADIO ESPECIFIC IOCTLS */
1810/* ----------------------------------------------------------- */
1811
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001812static int radio_g_tuner(struct file *file, void *priv,
1813 struct v4l2_tuner *t)
1814{
1815 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1816
1817 if (unlikely(t->index > 0))
1818 return -EINVAL;
1819
1820 strcpy(t->name, "Radio");
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001821
Frank Schaefer95d26082014-03-24 16:33:09 -03001822 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001823
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001824 return 0;
1825}
1826
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001827static int radio_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001828 const struct v4l2_tuner *t)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001829{
1830 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1831
1832 if (0 != t->index)
1833 return -EINVAL;
1834
Frank Schaefer95d26082014-03-24 16:33:09 -03001835 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001836
1837 return 0;
1838}
1839
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001840/*
Frank Schaefer95d26082014-03-24 16:33:09 -03001841 * em28xx_free_v4l2() - Free struct em28xx_v4l2
1842 *
1843 * @ref: struct kref for struct em28xx_v4l2
1844 *
1845 * Called when all users of struct em28xx_v4l2 are gone
1846 */
1847void em28xx_free_v4l2(struct kref *ref)
1848{
1849 struct em28xx_v4l2 *v4l2 = container_of(ref, struct em28xx_v4l2, ref);
1850
Frank Schaeferabc13082014-03-24 16:33:10 -03001851 v4l2->dev->v4l2 = NULL;
Frank Schaefer95d26082014-03-24 16:33:09 -03001852 kfree(v4l2);
1853}
1854
1855/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001856 * em28xx_v4l2_open()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001857 * inits the device and starts isoc transfer
1858 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001859static int em28xx_v4l2_open(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001860{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001861 struct video_device *vdev = video_devdata(filp);
1862 struct em28xx *dev = video_drvdata(filp);
Frank Schaefer95d26082014-03-24 16:33:09 -03001863 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001864 enum v4l2_buf_type fh_type = 0;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001865 struct em28xx_fh *fh;
Markus Rechberger9c755412005-11-08 21:37:52 -08001866
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001867 switch (vdev->vfl_type) {
1868 case VFL_TYPE_GRABBER:
1869 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1870 break;
1871 case VFL_TYPE_VBI:
1872 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1873 break;
Frank Schaefer4e170242014-01-12 13:24:18 -03001874 case VFL_TYPE_RADIO:
1875 break;
1876 default:
1877 return -EINVAL;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001878 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03001879
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001880 em28xx_videodbg("open dev=%s type=%s users=%d\n",
1881 video_device_node_name(vdev), v4l2_type_names[fh_type],
1882 dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001883
Hans Verkuil876cb142012-06-23 08:12:47 -03001884 if (mutex_lock_interruptible(&dev->lock))
1885 return -ERESTARTSYS;
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001886 fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001887 if (!fh) {
1888 em28xx_errdev("em28xx-video.c: Out of memory?!\n");
Hans Verkuil876cb142012-06-23 08:12:47 -03001889 mutex_unlock(&dev->lock);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001890 return -ENOMEM;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001891 }
Hans Verkuil69a61642012-09-07 05:52:40 -03001892 v4l2_fh_init(&fh->fh, vdev);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001893 fh->dev = dev;
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001894 fh->type = fh_type;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001895 filp->private_data = fh;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001896
Frank Schaefer4e170242014-01-12 13:24:18 -03001897 if (dev->users == 0) {
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001898 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001899
Frank Schaefer4e170242014-01-12 13:24:18 -03001900 if (vdev->vfl_type != VFL_TYPE_RADIO)
1901 em28xx_resolution_set(dev);
1902
1903 /*
1904 * Needed, since GPIO might have disabled power
1905 * of some i2c devices
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001906 */
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03001907 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001908 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001909
1910 if (vdev->vfl_type == VFL_TYPE_RADIO) {
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001911 em28xx_videodbg("video_open: setting radio device\n");
Frank Schaefer95d26082014-03-24 16:33:09 -03001912 v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_radio);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001913 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001914
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001915 kref_get(&dev->ref);
Frank Schaefer95d26082014-03-24 16:33:09 -03001916 kref_get(&v4l2->ref);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001917 dev->users++;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001918
Hans Verkuil876cb142012-06-23 08:12:47 -03001919 mutex_unlock(&dev->lock);
Hans Verkuil69a61642012-09-07 05:52:40 -03001920 v4l2_fh_add(&fh->fh);
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001921
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001922 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001923}
1924
1925/*
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001926 * em28xx_v4l2_fini()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001927 * unregisters the v4l2,i2c and usb devices
1928 * called when the device gets disconected or at module unload
1929*/
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001930static int em28xx_v4l2_fini(struct em28xx *dev)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001931{
Frank Schaefer95d26082014-03-24 16:33:09 -03001932 struct em28xx_v4l2 *v4l2 = dev->v4l2;
1933
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03001934 if (dev->is_audio_only) {
1935 /* Shouldn't initialize IR for this interface */
1936 return 0;
1937 }
1938
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001939 if (!dev->has_video) {
1940 /* This device does not support the v4l2 extension */
1941 return 0;
1942 }
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001943
Frank Schaefer95d26082014-03-24 16:33:09 -03001944 if (v4l2 == NULL)
1945 return 0;
1946
Mauro Carvalho Chehabaa929ad2014-01-12 19:22:07 -03001947 em28xx_info("Closing video extension");
1948
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001949 mutex_lock(&dev->lock);
1950
Frank Schaefer95d26082014-03-24 16:33:09 -03001951 v4l2_device_disconnect(&v4l2->v4l2_dev);
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001952
Frank Schaefer23e86422014-01-12 13:24:20 -03001953 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
1954
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001955 if (v4l2->radio_dev) {
Frank Schaefere8470222014-01-12 13:24:25 -03001956 em28xx_info("V4L2 device %s deregistered\n",
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001957 video_device_node_name(v4l2->radio_dev));
1958 video_unregister_device(v4l2->radio_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001959 }
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001960 if (v4l2->vbi_dev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001961 em28xx_info("V4L2 device %s deregistered\n",
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001962 video_device_node_name(v4l2->vbi_dev));
1963 video_unregister_device(v4l2->vbi_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001964 }
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001965 if (v4l2->vdev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001966 em28xx_info("V4L2 device %s deregistered\n",
Frank Schaeferef74a0b2014-03-24 16:33:12 -03001967 video_device_node_name(v4l2->vdev));
1968 video_unregister_device(v4l2->vdev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001969 }
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001970
Frank Schaeferabc13082014-03-24 16:33:10 -03001971 v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
Frank Schaefer95d26082014-03-24 16:33:09 -03001972 v4l2_device_unregister(&v4l2->v4l2_dev);
Frank Schaefer103f18a2014-01-17 14:45:30 -03001973
Frank Schaefer2c52a2f2014-03-24 16:33:11 -03001974 if (v4l2->clk) {
1975 v4l2_clk_unregister_fixed(v4l2->clk);
1976 v4l2->clk = NULL;
Frank Schaefer25dd1652014-01-12 13:24:23 -03001977 }
1978
Frank Schaefer95d26082014-03-24 16:33:09 -03001979 kref_put(&v4l2->ref, em28xx_free_v4l2);
1980
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001981 mutex_unlock(&dev->lock);
Frank Schaefer95d26082014-03-24 16:33:09 -03001982
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001983 kref_put(&dev->ref, em28xx_free_device);
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001984
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001985 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001986}
1987
Shuah Khana61f6812014-02-21 21:50:17 -03001988static int em28xx_v4l2_suspend(struct em28xx *dev)
1989{
1990 if (dev->is_audio_only)
1991 return 0;
1992
1993 if (!dev->has_video)
1994 return 0;
1995
1996 em28xx_info("Suspending video extension");
1997 em28xx_stop_urbs(dev);
1998 return 0;
1999}
2000
2001static int em28xx_v4l2_resume(struct em28xx *dev)
2002{
2003 if (dev->is_audio_only)
2004 return 0;
2005
2006 if (!dev->has_video)
2007 return 0;
2008
2009 em28xx_info("Resuming video extension");
2010 /* what do we do here */
2011 return 0;
2012}
2013
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002014/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08002015 * em28xx_v4l2_close()
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002016 * stops streaming and deallocates all resources allocated by the v4l2
2017 * calls and ioctls
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002018 */
Hans Verkuilbec43662008-12-30 06:58:20 -03002019static int em28xx_v4l2_close(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002020{
Frank Schaefer95d26082014-03-24 16:33:09 -03002021 struct em28xx_fh *fh = filp->private_data;
2022 struct em28xx *dev = fh->dev;
2023 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03002024 int errCode;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002025
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08002026 em28xx_videodbg("users=%d\n", dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002027
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002028 vb2_fop_release(filp);
Ricardo Ribalda98c24dcd2013-11-06 05:39:35 -03002029 mutex_lock(&dev->lock);
Devin Heitmueller8c873d32009-09-03 00:23:27 -03002030
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03002031 if (dev->users == 1) {
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002032 /* No sense to try to write to the device */
2033 if (dev->disconnected)
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002034 goto exit;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03002035
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03002036 /* Save some power by putting tuner to sleep */
Frank Schaefer95d26082014-03-24 16:33:09 -03002037 v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03002038
Aidan Thorntond7aa8022008-04-13 14:38:47 -03002039 /* do this before setting alternate! */
Mauro Carvalho Chehab2fe3e2e2008-11-27 09:10:40 -03002040 em28xx_set_mode(dev, EM28XX_SUSPEND);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03002041
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03002042 /* set alternate 0 */
2043 dev->alt = 0;
2044 em28xx_videodbg("setting alternate 0\n");
2045 errCode = usb_set_interface(dev->udev, 0, 0);
2046 if (errCode < 0) {
2047 em28xx_errdev("cannot change alternate number to "
2048 "0 (error=%i)\n", errCode);
2049 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002050 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03002051
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002052exit:
Frank Schaefer95d26082014-03-24 16:33:09 -03002053 kref_put(&v4l2->ref, em28xx_free_v4l2);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002054 dev->users--;
Hans Verkuil876cb142012-06-23 08:12:47 -03002055 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002056 kref_put(&dev->ref, em28xx_free_device);
2057
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002058 return 0;
2059}
2060
Hans Verkuilbec43662008-12-30 06:58:20 -03002061static const struct v4l2_file_operations em28xx_v4l_fops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002062 .owner = THIS_MODULE,
2063 .open = em28xx_v4l2_open,
2064 .release = em28xx_v4l2_close,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002065 .read = vb2_fop_read,
2066 .poll = vb2_fop_poll,
2067 .mmap = vb2_fop_mmap,
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002068 .unlocked_ioctl = video_ioctl2,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002069};
2070
Hans Verkuila3998102008-07-21 02:57:38 -03002071static const struct v4l2_ioctl_ops video_ioctl_ops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002072 .vidioc_querycap = vidioc_querycap,
Hans Verkuil78b526a2008-05-28 12:16:41 -03002073 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
2074 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
2075 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
2076 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller28abf0832009-09-01 01:54:54 -03002077 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil2a221d32012-09-07 08:51:32 -03002078 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Frank Schaeferaab34612013-02-07 13:39:16 -03002079 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02002080 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002081 .vidioc_g_audio = vidioc_g_audio,
2082 .vidioc_s_audio = vidioc_s_audio,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002083
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002084 .vidioc_reqbufs = vb2_ioctl_reqbufs,
2085 .vidioc_create_bufs = vb2_ioctl_create_bufs,
2086 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
2087 .vidioc_querybuf = vb2_ioctl_querybuf,
2088 .vidioc_qbuf = vb2_ioctl_qbuf,
2089 .vidioc_dqbuf = vb2_ioctl_dqbuf,
2090
Devin Heitmueller19bf0032009-09-11 00:40:18 -03002091 .vidioc_g_std = vidioc_g_std,
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03002092 .vidioc_querystd = vidioc_querystd,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002093 .vidioc_s_std = vidioc_s_std,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03002094 .vidioc_g_parm = vidioc_g_parm,
2095 .vidioc_s_parm = vidioc_s_parm,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002096 .vidioc_enum_input = vidioc_enum_input,
2097 .vidioc_g_input = vidioc_g_input,
2098 .vidioc_s_input = vidioc_s_input,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002099 .vidioc_streamon = vb2_ioctl_streamon,
2100 .vidioc_streamoff = vb2_ioctl_streamoff,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002101 .vidioc_g_tuner = vidioc_g_tuner,
2102 .vidioc_s_tuner = vidioc_s_tuner,
2103 .vidioc_g_frequency = vidioc_g_frequency,
2104 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002105 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2106 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002107#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03002108 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002109 .vidioc_g_register = vidioc_g_register,
2110 .vidioc_s_register = vidioc_s_register,
2111#endif
Hans Verkuila3998102008-07-21 02:57:38 -03002112};
2113
2114static const struct video_device em28xx_video_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002115 .fops = &em28xx_v4l_fops,
2116 .ioctl_ops = &video_ioctl_ops,
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002117 .release = video_device_release,
Frank Schaefere8470222014-01-12 13:24:25 -03002118 .tvnorms = V4L2_STD_ALL,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002119};
2120
Hans Verkuilbec43662008-12-30 06:58:20 -03002121static const struct v4l2_file_operations radio_fops = {
Hans Verkuila3998102008-07-21 02:57:38 -03002122 .owner = THIS_MODULE,
2123 .open = em28xx_v4l2_open,
2124 .release = em28xx_v4l2_close,
Hans Verkuil8fd0bda2010-12-18 09:59:51 -03002125 .unlocked_ioctl = video_ioctl2,
Hans Verkuila3998102008-07-21 02:57:38 -03002126};
2127
2128static const struct v4l2_ioctl_ops radio_ioctl_ops = {
Hans Verkuila9d79fe2012-09-06 07:31:04 -03002129 .vidioc_querycap = vidioc_querycap,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002130 .vidioc_g_tuner = radio_g_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002131 .vidioc_s_tuner = radio_s_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002132 .vidioc_g_frequency = vidioc_g_frequency,
2133 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002134 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2135 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002136#ifdef CONFIG_VIDEO_ADV_DEBUG
Michal Marek430c73f2013-04-16 08:06:30 -03002137 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002138 .vidioc_g_register = vidioc_g_register,
2139 .vidioc_s_register = vidioc_s_register,
2140#endif
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002141};
2142
Hans Verkuila3998102008-07-21 02:57:38 -03002143static struct video_device em28xx_radio_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002144 .fops = &radio_fops,
2145 .ioctl_ops = &radio_ioctl_ops,
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002146 .release = video_device_release,
Hans Verkuila3998102008-07-21 02:57:38 -03002147};
2148
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002149/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2150static unsigned short saa711x_addrs[] = {
2151 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2152 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2153 I2C_CLIENT_END };
2154
2155static unsigned short tvp5150_addrs[] = {
2156 0xb8 >> 1,
2157 0xba >> 1,
2158 I2C_CLIENT_END
2159};
2160
2161static unsigned short msp3400_addrs[] = {
2162 0x80 >> 1,
2163 0x88 >> 1,
2164 I2C_CLIENT_END
2165};
2166
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002167/******************************** usb interface ******************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002168
Adrian Bunk532fe652008-01-28 22:10:48 -03002169static struct video_device *em28xx_vdev_init(struct em28xx *dev,
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002170 const struct video_device *template,
2171 const char *type_name)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002172{
2173 struct video_device *vfd;
2174
2175 vfd = video_device_alloc();
2176 if (NULL == vfd)
2177 return NULL;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002178
2179 *vfd = *template;
Frank Schaefer95d26082014-03-24 16:33:09 -03002180 vfd->v4l2_dev = &dev->v4l2->v4l2_dev;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002181 vfd->debug = video_debug;
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002182 vfd->lock = &dev->lock;
Hans Verkuil69a61642012-09-07 05:52:40 -03002183 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
Hans Verkuild8c95c02012-09-07 07:31:54 -03002184 if (dev->board.is_webcam)
2185 vfd->tvnorms = 0;
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002186
2187 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
2188 dev->name, type_name);
2189
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002190 video_set_drvdata(vfd, dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002191 return vfd;
2192}
2193
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002194static void em28xx_tuner_setup(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002195{
Frank Schaefer95d26082014-03-24 16:33:09 -03002196 struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev;
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002197 struct tuner_setup tun_setup;
2198 struct v4l2_frequency f;
2199
2200 if (dev->tuner_type == TUNER_ABSENT)
2201 return;
2202
2203 memset(&tun_setup, 0, sizeof(tun_setup));
2204
2205 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2206 tun_setup.tuner_callback = em28xx_tuner_callback;
2207
2208 if (dev->board.radio.type) {
2209 tun_setup.type = dev->board.radio.type;
2210 tun_setup.addr = dev->board.radio_addr;
2211
Frank Schaefer95d26082014-03-24 16:33:09 -03002212 v4l2_device_call_all(v4l2_dev,
2213 0, tuner, s_type_addr, &tun_setup);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002214 }
2215
2216 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2217 tun_setup.type = dev->tuner_type;
2218 tun_setup.addr = dev->tuner_addr;
2219
Frank Schaefer95d26082014-03-24 16:33:09 -03002220 v4l2_device_call_all(v4l2_dev,
2221 0, tuner, s_type_addr, &tun_setup);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002222 }
2223
2224 if (dev->tda9887_conf) {
2225 struct v4l2_priv_tun_config tda9887_cfg;
2226
2227 tda9887_cfg.tuner = TUNER_TDA9887;
2228 tda9887_cfg.priv = &dev->tda9887_conf;
2229
Frank Schaefer95d26082014-03-24 16:33:09 -03002230 v4l2_device_call_all(v4l2_dev,
2231 0, tuner, s_config, &tda9887_cfg);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002232 }
2233
2234 if (dev->tuner_type == TUNER_XC2028) {
2235 struct v4l2_priv_tun_config xc2028_cfg;
2236 struct xc2028_ctrl ctl;
2237
2238 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2239 memset(&ctl, 0, sizeof(ctl));
2240
2241 em28xx_setup_xc3028(dev, &ctl);
2242
2243 xc2028_cfg.tuner = TUNER_XC2028;
2244 xc2028_cfg.priv = &ctl;
2245
Frank Schaefer95d26082014-03-24 16:33:09 -03002246 v4l2_device_call_all(v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002247 }
2248
2249 /* configure tuner */
2250 f.tuner = 0;
2251 f.type = V4L2_TUNER_ANALOG_TV;
2252 f.frequency = 9076; /* just a magic number */
2253 dev->ctl_freq = f.frequency;
Frank Schaefer95d26082014-03-24 16:33:09 -03002254 v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency, &f);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002255}
2256
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002257static int em28xx_v4l2_init(struct em28xx *dev)
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002258{
Hans Verkuil081b9452012-09-07 05:43:59 -03002259 u8 val;
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002260 int ret;
Sascha Sommer1020d132012-01-08 16:54:28 -03002261 unsigned int maxw;
Frank Schaeferabc13082014-03-24 16:33:10 -03002262 struct v4l2_ctrl_handler *hdl;
Frank Schaefer95d26082014-03-24 16:33:09 -03002263 struct em28xx_v4l2 *v4l2;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002264
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03002265 if (dev->is_audio_only) {
2266 /* Shouldn't initialize IR for this interface */
2267 return 0;
2268 }
2269
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002270 if (!dev->has_video) {
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002271 /* This device does not support the v4l2 extension */
2272 return 0;
2273 }
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002274
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002275 em28xx_info("Registering V4L2 extension\n");
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002276
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002277 mutex_lock(&dev->lock);
2278
Frank Schaefer95d26082014-03-24 16:33:09 -03002279 v4l2 = kzalloc(sizeof(struct em28xx_v4l2), GFP_KERNEL);
2280 if (v4l2 == NULL) {
2281 em28xx_info("em28xx_v4l: memory allocation failed\n");
2282 mutex_unlock(&dev->lock);
2283 return -ENOMEM;
2284 }
2285 kref_init(&v4l2->ref);
Frank Schaeferabc13082014-03-24 16:33:10 -03002286 v4l2->dev = dev;
Frank Schaefer95d26082014-03-24 16:33:09 -03002287 dev->v4l2 = v4l2;
2288
2289 ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002290 if (ret < 0) {
2291 em28xx_errdev("Call to v4l2_device_register() failed!\n");
2292 goto err;
2293 }
2294
Frank Schaeferabc13082014-03-24 16:33:10 -03002295 hdl = &v4l2->ctrl_handler;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002296 v4l2_ctrl_handler_init(hdl, 8);
Frank Schaefer95d26082014-03-24 16:33:09 -03002297 v4l2->v4l2_dev.ctrl_handler = hdl;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002298
2299 /*
2300 * Default format, used for tvp5150 or saa711x output formats
2301 */
2302 dev->vinmode = 0x10;
2303 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2304 EM28XX_VINCTRL_CCIR656_ENABLE;
2305
2306 /* request some modules */
2307
2308 if (dev->board.has_msp34xx)
Frank Schaefer95d26082014-03-24 16:33:09 -03002309 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2310 &dev->i2c_adap[dev->def_i2c_bus],
2311 "msp3400", 0, msp3400_addrs);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002312
2313 if (dev->board.decoder == EM28XX_SAA711X)
Frank Schaefer95d26082014-03-24 16:33:09 -03002314 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2315 &dev->i2c_adap[dev->def_i2c_bus],
2316 "saa7115_auto", 0, saa711x_addrs);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002317
2318 if (dev->board.decoder == EM28XX_TVP5150)
Frank Schaefer95d26082014-03-24 16:33:09 -03002319 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2320 &dev->i2c_adap[dev->def_i2c_bus],
2321 "tvp5150", 0, tvp5150_addrs);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002322
2323 if (dev->board.adecoder == EM28XX_TVAUDIO)
Frank Schaefer95d26082014-03-24 16:33:09 -03002324 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2325 &dev->i2c_adap[dev->def_i2c_bus],
2326 "tvaudio", dev->board.tvaudio_addr, NULL);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002327
2328 /* Initialize tuner and camera */
2329
2330 if (dev->board.tuner_type != TUNER_ABSENT) {
2331 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2332
2333 if (dev->board.radio.type)
Frank Schaefer95d26082014-03-24 16:33:09 -03002334 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2335 &dev->i2c_adap[dev->def_i2c_bus],
2336 "tuner", dev->board.radio_addr, NULL);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002337
2338 if (has_demod)
Frank Schaefer95d26082014-03-24 16:33:09 -03002339 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002340 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2341 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2342 if (dev->tuner_addr == 0) {
2343 enum v4l2_i2c_tuner_type type =
2344 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2345 struct v4l2_subdev *sd;
2346
Frank Schaefer95d26082014-03-24 16:33:09 -03002347 sd = v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002348 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2349 0, v4l2_i2c_tuner_addrs(type));
2350
2351 if (sd)
2352 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2353 } else {
Frank Schaefer95d26082014-03-24 16:33:09 -03002354 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2355 &dev->i2c_adap[dev->def_i2c_bus],
2356 "tuner", dev->tuner_addr, NULL);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002357 }
2358 }
2359
2360 em28xx_tuner_setup(dev);
Frank Schaeferd86bc652014-01-17 14:45:32 -03002361 if (dev->em28xx_sensor != EM28XX_NOSENSOR)
2362 em28xx_init_camera(dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002363
2364 /* Configure audio */
2365 ret = em28xx_audio_setup(dev);
2366 if (ret < 0) {
2367 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2368 __func__, ret);
2369 goto unregister_dev;
2370 }
2371 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
2372 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2373 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
2374 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2375 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
2376 } else {
2377 /* install the em28xx notify callback */
2378 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
2379 em28xx_ctrl_notify, dev);
2380 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
2381 em28xx_ctrl_notify, dev);
2382 }
2383
2384 /* wake i2c devices */
2385 em28xx_wake_i2c(dev);
2386
2387 /* init video dma queues */
2388 INIT_LIST_HEAD(&dev->vidq.active);
2389 INIT_LIST_HEAD(&dev->vbiq.active);
2390
2391 if (dev->board.has_msp34xx) {
2392 /* Send a reset to other chips via gpio */
2393 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
2394 if (ret < 0) {
2395 em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
2396 __func__, ret);
2397 goto unregister_dev;
2398 }
2399 msleep(3);
2400
2401 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
2402 if (ret < 0) {
2403 em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
2404 __func__, ret);
2405 goto unregister_dev;
2406 }
2407 msleep(3);
2408 }
2409
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002410 /* set default norm */
Hans Verkuild8c95c02012-09-07 07:31:54 -03002411 dev->norm = V4L2_STD_PAL;
Frank Schaefer95d26082014-03-24 16:33:09 -03002412 v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002413 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002414
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002415 /* Analog specific initialization */
2416 dev->format = &format[0];
Sascha Sommer1020d132012-01-08 16:54:28 -03002417
2418 maxw = norm_maxw(dev);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002419 /* MaxPacketSize for em2800 is too small to capture at full resolution
2420 * use half of maxw as the scaler can only scale to 50% */
2421 if (dev->board.is_em2800)
2422 maxw /= 2;
Sascha Sommer1020d132012-01-08 16:54:28 -03002423
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002424 em28xx_set_video_format(dev, format[0].fourcc,
Sascha Sommer1020d132012-01-08 16:54:28 -03002425 maxw, norm_maxh(dev));
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002426
Ezequiel García96371fc2012-03-23 18:09:34 -03002427 video_mux(dev, 0);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002428
2429 /* Audio defaults */
2430 dev->mute = 1;
2431 dev->volume = 0x1f;
2432
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002433/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002434 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2435 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2436 (EM28XX_XCLK_AUDIO_UNMUTE | val));
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002437
2438 em28xx_set_outfmt(dev);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002439
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002440 /* Add image controls */
2441 /* NOTE: at this point, the subdevices are already registered, so bridge
2442 * controls are only added/enabled when no subdevice provides them */
Frank Schaeferad298052014-03-24 16:33:08 -03002443 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST))
2444 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002445 V4L2_CID_CONTRAST,
2446 0, 0x1f, 1, CONTRAST_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002447 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS))
2448 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002449 V4L2_CID_BRIGHTNESS,
2450 -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002451 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SATURATION))
2452 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002453 V4L2_CID_SATURATION,
2454 0, 0x1f, 1, SATURATION_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002455 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE))
2456 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002457 V4L2_CID_BLUE_BALANCE,
2458 -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002459 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE))
2460 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002461 V4L2_CID_RED_BALANCE,
2462 -0x30, 0x30, 1, RED_BALANCE_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002463 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS))
2464 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002465 V4L2_CID_SHARPNESS,
2466 0, 0x0f, 1, SHARPNESS_DEFAULT);
2467
2468 /* Reset image controls */
2469 em28xx_colorlevels_set_default(dev);
Frank Schaeferad298052014-03-24 16:33:08 -03002470 v4l2_ctrl_handler_setup(hdl);
2471 ret = hdl->error;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002472 if (ret)
2473 goto unregister_dev;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002474
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002475 /* allocate and fill video video_device struct */
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002476 v4l2->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
2477 if (!v4l2->vdev) {
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002478 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002479 ret = -ENODEV;
2480 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002481 }
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002482 v4l2->vdev->queue = &dev->vb_vidq;
2483 v4l2->vdev->queue->lock = &dev->vb_queue_lock;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002484
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002485 /* disable inapplicable ioctls */
2486 if (dev->board.is_webcam) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002487 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_QUERYSTD);
2488 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_STD);
2489 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_STD);
Frank Schaefer3bc85cc2013-02-07 13:39:12 -03002490 } else {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002491 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_PARM);
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002492 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002493 if (dev->tuner_type == TUNER_ABSENT) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002494 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_TUNER);
2495 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_TUNER);
2496 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_FREQUENCY);
2497 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_FREQUENCY);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002498 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002499 if (!dev->audio_mode.has_audio) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002500 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_AUDIO);
2501 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_AUDIO);
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002502 }
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002503
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002504 /* register v4l2 video video_device */
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002505 ret = video_register_device(v4l2->vdev, VFL_TYPE_GRABBER,
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002506 video_nr[dev->devno]);
2507 if (ret) {
2508 em28xx_errdev("unable to register video device (error=%i).\n",
2509 ret);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002510 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002511 }
2512
2513 /* Allocate and fill vbi video_device struct */
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002514 if (em28xx_vbi_supported(dev) == 1) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002515 v4l2->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002516 "vbi");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002517
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002518 v4l2->vbi_dev->queue = &dev->vb_vbiq;
2519 v4l2->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002520
Frank Schaefer66df67b2013-02-07 13:39:10 -03002521 /* disable inapplicable ioctls */
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002522 v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_PARM);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002523 if (dev->tuner_type == TUNER_ABSENT) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002524 v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_TUNER);
2525 v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_TUNER);
2526 v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_FREQUENCY);
2527 v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_FREQUENCY);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002528 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002529 if (!dev->audio_mode.has_audio) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002530 v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_AUDIO);
2531 v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_AUDIO);
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002532 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002533
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002534 /* register v4l2 vbi video_device */
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002535 ret = video_register_device(v4l2->vbi_dev, VFL_TYPE_VBI,
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002536 vbi_nr[dev->devno]);
2537 if (ret < 0) {
2538 em28xx_errdev("unable to register vbi device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002539 goto unregister_dev;
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002540 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002541 }
2542
2543 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002544 v4l2->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
2545 "radio");
2546 if (!v4l2->radio_dev) {
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002547 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002548 ret = -ENODEV;
2549 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002550 }
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002551 ret = video_register_device(v4l2->radio_dev, VFL_TYPE_RADIO,
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002552 radio_nr[dev->devno]);
2553 if (ret < 0) {
2554 em28xx_errdev("can't register radio device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002555 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002556 }
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002557 em28xx_info("Registered radio device as %s\n",
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002558 video_device_node_name(v4l2->radio_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002559 }
2560
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002561 em28xx_info("V4L2 video device registered as %s\n",
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002562 video_device_node_name(v4l2->vdev));
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002563
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002564 if (v4l2->vbi_dev)
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002565 em28xx_info("V4L2 VBI device registered as %s\n",
Frank Schaeferef74a0b2014-03-24 16:33:12 -03002566 video_device_node_name(v4l2->vbi_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002567
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002568 /* Save some power by putting tuner to sleep */
Frank Schaefer95d26082014-03-24 16:33:09 -03002569 v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002570
2571 /* initialize videobuf2 stuff */
2572 em28xx_vb2_setup(dev);
2573
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002574 em28xx_info("V4L2 extension successfully initialized\n");
2575
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002576 kref_get(&dev->ref);
2577
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002578 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002579 return 0;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002580
2581unregister_dev:
Frank Schaeferabc13082014-03-24 16:33:10 -03002582 v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
Frank Schaefer95d26082014-03-24 16:33:09 -03002583 v4l2_device_unregister(&v4l2->v4l2_dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002584err:
Frank Schaefer95d26082014-03-24 16:33:09 -03002585 dev->v4l2 = NULL;
2586 kref_put(&v4l2->ref, em28xx_free_v4l2);
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002587 mutex_unlock(&dev->lock);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002588 return ret;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002589}
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002590
2591static struct em28xx_ops v4l2_ops = {
2592 .id = EM28XX_V4L2,
2593 .name = "Em28xx v4l2 Extension",
2594 .init = em28xx_v4l2_init,
2595 .fini = em28xx_v4l2_fini,
Shuah Khana61f6812014-02-21 21:50:17 -03002596 .suspend = em28xx_v4l2_suspend,
2597 .resume = em28xx_v4l2_resume,
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002598};
2599
2600static int __init em28xx_video_register(void)
2601{
2602 return em28xx_register_extension(&v4l2_ops);
2603}
2604
2605static void __exit em28xx_video_unregister(void)
2606{
2607 em28xx_unregister_extension(&v4l2_ops);
2608}
2609
2610module_init(em28xx_video_register);
2611module_exit(em28xx_video_unregister);