blob: 814403dee0438377c72b61bf0a72bc29706b87ec [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{
1137 struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler);
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001138 int ret = -EINVAL;
Hans Verkuil081b9452012-09-07 05:43:59 -03001139
1140 switch (ctrl->id) {
1141 case V4L2_CID_AUDIO_MUTE:
1142 dev->mute = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001143 ret = em28xx_audio_analog_set(dev);
Hans Verkuil081b9452012-09-07 05:43:59 -03001144 break;
1145 case V4L2_CID_AUDIO_VOLUME:
1146 dev->volume = ctrl->val;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001147 ret = em28xx_audio_analog_set(dev);
1148 break;
1149 case V4L2_CID_CONTRAST:
1150 ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val);
1151 break;
1152 case V4L2_CID_BRIGHTNESS:
1153 ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val);
1154 break;
1155 case V4L2_CID_SATURATION:
1156 ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val);
1157 break;
1158 case V4L2_CID_BLUE_BALANCE:
1159 ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val);
1160 break;
1161 case V4L2_CID_RED_BALANCE:
1162 ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val);
1163 break;
1164 case V4L2_CID_SHARPNESS:
1165 ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val);
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001166 break;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001167 }
Mauro Carvalho Chehaba98f6af2009-07-19 10:45:49 -03001168
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03001169 return (ret < 0) ? ret : 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001170}
1171
Fengguang Wu8068eb82014-01-07 12:50:47 -03001172static const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
Hans Verkuil081b9452012-09-07 05:43:59 -03001173 .s_ctrl = em28xx_s_ctrl,
1174};
1175
Frank Schaefer6b09a212013-02-10 16:05:12 -03001176static void size_to_scale(struct em28xx *dev,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001177 unsigned int width, unsigned int height,
1178 unsigned int *hscale, unsigned int *vscale)
1179{
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001180 unsigned int maxw = norm_maxw(dev);
1181 unsigned int maxh = norm_maxh(dev);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001182
1183 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001184 if (*hscale > EM28XX_HVSCALE_MAX)
1185 *hscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001186
1187 *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
Frank Schaefer81685322013-02-10 16:05:11 -03001188 if (*vscale > EM28XX_HVSCALE_MAX)
1189 *vscale = EM28XX_HVSCALE_MAX;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001190}
1191
Frank Schaeferb8374132013-02-10 16:05:13 -03001192static void scale_to_size(struct em28xx *dev,
1193 unsigned int hscale, unsigned int vscale,
1194 unsigned int *width, unsigned int *height)
1195{
1196 unsigned int maxw = norm_maxw(dev);
1197 unsigned int maxh = norm_maxh(dev);
1198
1199 *width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
1200 *height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
1201}
1202
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001203/* ------------------------------------------------------------------
1204 IOCTL vidioc handling
1205 ------------------------------------------------------------------*/
1206
Hans Verkuil78b526a2008-05-28 12:16:41 -03001207static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001208 struct v4l2_format *f)
1209{
1210 struct em28xx_fh *fh = priv;
1211 struct em28xx *dev = fh->dev;
1212
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001213 f->fmt.pix.width = dev->width;
1214 f->fmt.pix.height = dev->height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001215 f->fmt.pix.pixelformat = dev->format->fourcc;
1216 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
Mauro Carvalho Chehab44dc7332008-04-13 15:11:08 -03001217 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001218 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1219
1220 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001221 if (dev->progressive)
1222 f->fmt.pix.field = V4L2_FIELD_NONE;
1223 else
1224 f->fmt.pix.field = dev->interlaced ?
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001225 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001226 return 0;
1227}
1228
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001229static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
1230{
1231 unsigned int i;
1232
1233 for (i = 0; i < ARRAY_SIZE(format); i++)
1234 if (format[i].fourcc == fourcc)
1235 return &format[i];
1236
1237 return NULL;
1238}
1239
Hans Verkuil78b526a2008-05-28 12:16:41 -03001240static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001241 struct v4l2_format *f)
1242{
1243 struct em28xx_fh *fh = priv;
1244 struct em28xx *dev = fh->dev;
Trent Piephoccb83402009-05-30 21:45:46 -03001245 unsigned int width = f->fmt.pix.width;
1246 unsigned int height = f->fmt.pix.height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001247 unsigned int maxw = norm_maxw(dev);
1248 unsigned int maxh = norm_maxh(dev);
1249 unsigned int hscale, vscale;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001250 struct em28xx_fmt *fmt;
1251
1252 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1253 if (!fmt) {
1254 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1255 f->fmt.pix.pixelformat);
1256 return -EINVAL;
1257 }
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001258
Mauro Carvalho Chehab55699962009-07-13 20:15:02 -03001259 if (dev->board.is_em2800) {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001260 /* the em2800 can only scale down to 50% */
Trent Piephoccb83402009-05-30 21:45:46 -03001261 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1262 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001263 /*
1264 * MaxPacketSize for em2800 is too small to capture at full
1265 * resolution use half of maxw as the scaler can only scale
1266 * to 50%
1267 */
Sascha Sommer1020d132012-01-08 16:54:28 -03001268 if (width == maxw && height == maxh)
1269 width /= 2;
Trent Piephoccb83402009-05-30 21:45:46 -03001270 } else {
1271 /* width must even because of the YUYV format
1272 height must be even because of interlacing */
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03001273 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1274 1, 0);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001275 }
1276
Frank Schaefer6b09a212013-02-10 16:05:12 -03001277 size_to_scale(dev, width, height, &hscale, &vscale);
Hans Verkuil46f85972013-03-30 05:31:42 -03001278 scale_to_size(dev, hscale, vscale, &width, &height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001279
1280 f->fmt.pix.width = width;
1281 f->fmt.pix.height = height;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001282 f->fmt.pix.pixelformat = fmt->fourcc;
Hans Verkuile6066db2013-02-06 08:14:47 -03001283 f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3;
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001284 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001285 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
Mauro Carvalho Chehabc2a6b542009-08-08 03:14:55 -03001286 if (dev->progressive)
1287 f->fmt.pix.field = V4L2_FIELD_NONE;
1288 else
1289 f->fmt.pix.field = dev->interlaced ?
1290 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
Alban Browaeys51dd4d72013-07-16 19:06:46 -03001291 f->fmt.pix.priv = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001292
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001293 return 0;
1294}
1295
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001296static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
1297 unsigned width, unsigned height)
1298{
1299 struct em28xx_fmt *fmt;
1300
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001301 fmt = format_by_fourcc(fourcc);
1302 if (!fmt)
1303 return -EINVAL;
1304
1305 dev->format = fmt;
1306 dev->width = width;
1307 dev->height = height;
1308
1309 /* set new image size */
Frank Schaefer6b09a212013-02-10 16:05:12 -03001310 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001311
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001312 em28xx_resolution_set(dev);
1313
1314 return 0;
1315}
1316
Hans Verkuil78b526a2008-05-28 12:16:41 -03001317static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001318 struct v4l2_format *f)
1319{
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001320 struct em28xx *dev = video_drvdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001321
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001322 if (dev->streaming_users > 0)
1323 return -EBUSY;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001324
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001325 vidioc_try_fmt_vid_cap(file, priv, f);
1326
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001327 return em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03001328 f->fmt.pix.width, f->fmt.pix.height);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001329}
1330
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001331static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1332{
1333 struct em28xx_fh *fh = priv;
1334 struct em28xx *dev = fh->dev;
Devin Heitmueller19bf0032009-09-11 00:40:18 -03001335
1336 *norm = dev->norm;
1337
1338 return 0;
1339}
1340
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001341static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
1342{
1343 struct em28xx_fh *fh = priv;
1344 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001345
Frank Schaefer95d26082014-03-24 16:33:09 -03001346 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, video, querystd, norm);
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03001347
1348 return 0;
1349}
1350
Hans Verkuil314527a2013-03-15 06:10:40 -03001351static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001352{
1353 struct em28xx_fh *fh = priv;
1354 struct em28xx *dev = fh->dev;
1355 struct v4l2_format f;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001356
Hans Verkuil314527a2013-03-15 06:10:40 -03001357 if (norm == dev->norm)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001358 return 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001359
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001360 if (dev->streaming_users > 0)
Hans Verkuild8c95c02012-09-07 07:31:54 -03001361 return -EBUSY;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001362
Hans Verkuil314527a2013-03-15 06:10:40 -03001363 dev->norm = norm;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001364
1365 /* Adjusts width/height, if needed */
Hans Verkuild8c95c02012-09-07 07:31:54 -03001366 f.fmt.pix.width = 720;
Hans Verkuil314527a2013-03-15 06:10:40 -03001367 f.fmt.pix.height = (norm & V4L2_STD_525_60) ? 480 : 576;
Hans Verkuil78b526a2008-05-28 12:16:41 -03001368 vidioc_try_fmt_vid_cap(file, priv, &f);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001369
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001370 /* set new image size */
1371 dev->width = f.fmt.pix.width;
1372 dev->height = f.fmt.pix.height;
Frank Schaefer6b09a212013-02-10 16:05:12 -03001373 size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001374
1375 em28xx_resolution_set(dev);
Frank Schaefer95d26082014-03-24 16:33:09 -03001376 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001377
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001378 return 0;
1379}
1380
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001381static int vidioc_g_parm(struct file *file, void *priv,
1382 struct v4l2_streamparm *p)
1383{
1384 struct em28xx_fh *fh = priv;
1385 struct em28xx *dev = fh->dev;
1386 int rc = 0;
1387
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001388 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001389 if (dev->board.is_webcam)
Frank Schaefer95d26082014-03-24 16:33:09 -03001390 rc = v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, 0,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001391 video, g_parm, p);
1392 else
1393 v4l2_video_std_frame_period(dev->norm,
1394 &p->parm.capture.timeperframe);
1395
1396 return rc;
1397}
1398
1399static int vidioc_s_parm(struct file *file, void *priv,
1400 struct v4l2_streamparm *p)
1401{
1402 struct em28xx_fh *fh = priv;
1403 struct em28xx *dev = fh->dev;
1404
Hans Verkuil86ff7f12012-09-07 06:16:03 -03001405 p->parm.capture.readbuffers = EM28XX_MIN_BUF;
Frank Schaefer95d26082014-03-24 16:33:09 -03001406 return v4l2_device_call_until_err(&dev->v4l2->v4l2_dev,
1407 0, video, s_parm, p);
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03001408}
1409
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001410static const char *iname[] = {
1411 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
1412 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
1413 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
1414 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
1415 [EM28XX_VMUX_SVIDEO] = "S-Video",
1416 [EM28XX_VMUX_TELEVISION] = "Television",
1417 [EM28XX_VMUX_CABLE] = "Cable TV",
1418 [EM28XX_VMUX_DVB] = "DVB",
1419 [EM28XX_VMUX_DEBUG] = "for debug only",
1420};
1421
1422static int vidioc_enum_input(struct file *file, void *priv,
1423 struct v4l2_input *i)
1424{
1425 struct em28xx_fh *fh = priv;
1426 struct em28xx *dev = fh->dev;
1427 unsigned int n;
1428
1429 n = i->index;
1430 if (n >= MAX_EM28XX_INPUT)
1431 return -EINVAL;
1432 if (0 == INPUT(n)->type)
1433 return -EINVAL;
1434
1435 i->index = n;
1436 i->type = V4L2_INPUT_TYPE_CAMERA;
1437
1438 strcpy(i->name, iname[INPUT(n)->type]);
1439
1440 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
1441 (EM28XX_VMUX_CABLE == INPUT(n)->type))
1442 i->type = V4L2_INPUT_TYPE_TUNER;
1443
Mauro Carvalho Chehab7d497f82007-11-11 14:15:34 -03001444 i->std = dev->vdev->tvnorms;
Hans Verkuild8c95c02012-09-07 07:31:54 -03001445 /* webcams do not have the STD API */
1446 if (dev->board.is_webcam)
1447 i->capabilities = 0;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001448
1449 return 0;
1450}
1451
1452static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1453{
1454 struct em28xx_fh *fh = priv;
1455 struct em28xx *dev = fh->dev;
1456
1457 *i = dev->ctl_input;
1458
1459 return 0;
1460}
1461
1462static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1463{
1464 struct em28xx_fh *fh = priv;
1465 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001466
1467 if (i >= MAX_EM28XX_INPUT)
1468 return -EINVAL;
1469 if (0 == INPUT(i)->type)
1470 return -EINVAL;
1471
Ezequiel García96371fc2012-03-23 18:09:34 -03001472 video_mux(dev, i);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001473 return 0;
1474}
1475
1476static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1477{
1478 struct em28xx_fh *fh = priv;
1479 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001480
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001481 switch (a->index) {
1482 case EM28XX_AMUX_VIDEO:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001483 strcpy(a->name, "Television");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001484 break;
1485 case EM28XX_AMUX_LINE_IN:
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001486 strcpy(a->name, "Line In");
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001487 break;
1488 case EM28XX_AMUX_VIDEO2:
1489 strcpy(a->name, "Television alt");
1490 break;
1491 case EM28XX_AMUX_PHONE:
1492 strcpy(a->name, "Phone");
1493 break;
1494 case EM28XX_AMUX_MIC:
1495 strcpy(a->name, "Mic");
1496 break;
1497 case EM28XX_AMUX_CD:
1498 strcpy(a->name, "CD");
1499 break;
1500 case EM28XX_AMUX_AUX:
1501 strcpy(a->name, "Aux");
1502 break;
1503 case EM28XX_AMUX_PCM_OUT:
1504 strcpy(a->name, "PCM");
1505 break;
1506 default:
1507 return -EINVAL;
1508 }
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03001509
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001510 a->index = dev->ctl_ainput;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001511 a->capability = V4L2_AUDCAP_STEREO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001512
1513 return 0;
1514}
1515
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001516static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001517{
1518 struct em28xx_fh *fh = priv;
1519 struct em28xx *dev = fh->dev;
1520
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03001521 if (a->index >= MAX_EM28XX_INPUT)
1522 return -EINVAL;
1523 if (0 == INPUT(a->index)->type)
1524 return -EINVAL;
1525
Mauro Carvalho Chehab35ae6f02008-11-20 12:40:51 -03001526 dev->ctl_ainput = INPUT(a->index)->amux;
1527 dev->ctl_aoutput = INPUT(a->index)->aout;
Mauro Carvalho Chehabe879b8e2008-11-20 13:39:39 -03001528
1529 if (!dev->ctl_aoutput)
1530 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001531
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001532 return 0;
1533}
1534
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001535static int vidioc_g_tuner(struct file *file, void *priv,
1536 struct v4l2_tuner *t)
1537{
1538 struct em28xx_fh *fh = priv;
1539 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001540
1541 if (0 != t->index)
1542 return -EINVAL;
1543
1544 strcpy(t->name, "Tuner");
1545
Frank Schaefer95d26082014-03-24 16:33:09 -03001546 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001547 return 0;
1548}
1549
1550static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001551 const struct v4l2_tuner *t)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001552{
1553 struct em28xx_fh *fh = priv;
1554 struct em28xx *dev = fh->dev;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001555
1556 if (0 != t->index)
1557 return -EINVAL;
1558
Frank Schaefer95d26082014-03-24 16:33:09 -03001559 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001560 return 0;
1561}
1562
1563static int vidioc_g_frequency(struct file *file, void *priv,
1564 struct v4l2_frequency *f)
1565{
1566 struct em28xx_fh *fh = priv;
1567 struct em28xx *dev = fh->dev;
1568
Hans Verkuil20deebf2012-09-06 10:07:25 -03001569 if (0 != f->tuner)
1570 return -EINVAL;
1571
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001572 f->frequency = dev->ctl_freq;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001573 return 0;
1574}
1575
1576static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001577 const struct v4l2_frequency *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001578{
Frank Schaefer95d26082014-03-24 16:33:09 -03001579 struct v4l2_frequency new_freq = *f;
1580 struct em28xx_fh *fh = priv;
1581 struct em28xx *dev = fh->dev;
1582 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001583
1584 if (0 != f->tuner)
1585 return -EINVAL;
1586
Frank Schaefer95d26082014-03-24 16:33:09 -03001587 v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_frequency, f);
1588 v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, g_frequency, &new_freq);
Hans Verkuilb530a442013-03-19 04:09:26 -03001589 dev->ctl_freq = new_freq.frequency;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001590
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001591 return 0;
1592}
1593
Hans Verkuilcd634f12013-03-27 08:04:23 -03001594#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03001595static int vidioc_g_chip_info(struct file *file, void *priv,
1596 struct v4l2_dbg_chip_info *chip)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001597{
1598 struct em28xx_fh *fh = priv;
1599 struct em28xx *dev = fh->dev;
1600
1601 if (chip->match.addr > 1)
1602 return -EINVAL;
1603 if (chip->match.addr == 1)
1604 strlcpy(chip->name, "ac97", sizeof(chip->name));
1605 else
Frank Schaefer95d26082014-03-24 16:33:09 -03001606 strlcpy(chip->name,
1607 dev->v4l2->v4l2_dev.name, sizeof(chip->name));
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001608 return 0;
1609}
1610
Frank Schaefer35deba32013-02-07 13:39:19 -03001611static int em28xx_reg_len(int reg)
1612{
1613 switch (reg) {
1614 case EM28XX_R40_AC97LSB:
1615 case EM28XX_R30_HSCALELOW:
1616 case EM28XX_R32_VSCALELOW:
1617 return 2;
1618 default:
1619 return 1;
1620 }
1621}
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001622
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001623static int vidioc_g_register(struct file *file, void *priv,
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001624 struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001625{
1626 struct em28xx_fh *fh = priv;
1627 struct em28xx *dev = fh->dev;
1628 int ret;
1629
Hans Verkuilabca2052013-05-29 06:59:35 -03001630 if (reg->match.addr > 1)
1631 return -EINVAL;
1632 if (reg->match.addr) {
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001633 ret = em28xx_read_ac97(dev, reg->reg);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001634 if (ret < 0)
1635 return ret;
1636
1637 reg->val = ret;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001638 reg->size = 1;
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001639 return 0;
1640 }
1641
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001642 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001643 reg->size = em28xx_reg_len(reg->reg);
1644 if (reg->size == 1) {
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001645 ret = em28xx_read_reg(dev, reg->reg);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001646
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001647 if (ret < 0)
1648 return ret;
1649
1650 reg->val = ret;
1651 } else {
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001652 __le16 val = 0;
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001653 ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001654 reg->reg, (char *)&val, 2);
1655 if (ret < 0)
1656 return ret;
1657
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001658 reg->val = le16_to_cpu(val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001659 }
1660
1661 return 0;
1662}
1663
1664static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001665 const struct v4l2_dbg_register *reg)
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001666{
1667 struct em28xx_fh *fh = priv;
1668 struct em28xx *dev = fh->dev;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001669 __le16 buf;
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001670
Hans Verkuilabca2052013-05-29 06:59:35 -03001671 if (reg->match.addr > 1)
Hans Verkuil3b2d17b2013-03-18 12:21:53 -03001672 return -EINVAL;
Hans Verkuilabca2052013-05-29 06:59:35 -03001673 if (reg->match.addr)
1674 return em28xx_write_ac97(dev, reg->reg, reg->val);
Mauro Carvalho Chehab531c98e2008-12-22 13:18:27 -03001675
Mauro Carvalho Chehab14983d82008-12-22 20:58:41 -03001676 /* Match host */
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001677 buf = cpu_to_le16(reg->val);
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001678
Hans Verkuil0499a5a2010-09-26 07:34:45 -03001679 return em28xx_write_regs(dev, reg->reg, (char *)&buf,
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001680 em28xx_reg_len(reg->reg));
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03001681}
1682#endif
1683
1684
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001685static int vidioc_querycap(struct file *file, void *priv,
1686 struct v4l2_capability *cap)
1687{
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001688 struct video_device *vdev = video_devdata(file);
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001689 struct em28xx_fh *fh = priv;
1690 struct em28xx *dev = fh->dev;
1691
1692 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1693 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
Thierry MERLEcb977162009-01-20 18:01:33 -03001694 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001695
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001696 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1697 cap->device_caps = V4L2_CAP_READWRITE |
1698 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1699 else if (vdev->vfl_type == VFL_TYPE_RADIO)
1700 cap->device_caps = V4L2_CAP_RADIO;
1701 else
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001702 cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
Devin Heitmueller04146142009-09-11 00:08:44 -03001703
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001704 if (dev->audio_mode.has_audio)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001705 cap->device_caps |= V4L2_CAP_AUDIO;
Mauro Carvalho Chehab6c428b52009-08-04 19:52:37 -03001706
Mauro Carvalho Chehabed086312008-01-24 06:59:20 -03001707 if (dev->tuner_type != TUNER_ABSENT)
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001708 cap->device_caps |= V4L2_CAP_TUNER;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001709
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001710 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1711 V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1712 if (dev->vbi_dev)
Hans Verkuil1d179ee2012-09-07 08:45:10 -03001713 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
Hans Verkuila9d79fe2012-09-06 07:31:04 -03001714 if (dev->radio_dev)
1715 cap->capabilities |= V4L2_CAP_RADIO;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001716 return 0;
1717}
1718
Hans Verkuil78b526a2008-05-28 12:16:41 -03001719static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001720 struct v4l2_fmtdesc *f)
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001721{
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001722 if (unlikely(f->index >= ARRAY_SIZE(format)))
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001723 return -EINVAL;
1724
Mauro Carvalho Chehabbddcf632008-12-20 09:06:37 -03001725 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1726 f->pixelformat = format[f->index].fourcc;
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001727
1728 return 0;
1729}
1730
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001731static int vidioc_enum_framesizes(struct file *file, void *priv,
1732 struct v4l2_frmsizeenum *fsize)
1733{
1734 struct em28xx_fh *fh = priv;
1735 struct em28xx *dev = fh->dev;
1736 struct em28xx_fmt *fmt;
1737 unsigned int maxw = norm_maxw(dev);
1738 unsigned int maxh = norm_maxh(dev);
1739
1740 fmt = format_by_fourcc(fsize->pixel_format);
1741 if (!fmt) {
1742 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
1743 fsize->pixel_format);
1744 return -EINVAL;
1745 }
1746
1747 if (dev->board.is_em2800) {
1748 if (fsize->index > 1)
1749 return -EINVAL;
1750 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1751 fsize->discrete.width = maxw / (1 + fsize->index);
1752 fsize->discrete.height = maxh / (1 + fsize->index);
1753 return 0;
1754 }
1755
1756 if (fsize->index != 0)
1757 return -EINVAL;
1758
1759 /* Report a continuous range */
1760 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
Frank Schaefer6c3598e2013-02-10 16:05:14 -03001761 scale_to_size(dev, EM28XX_HVSCALE_MAX, EM28XX_HVSCALE_MAX,
1762 &fsize->stepwise.min_width, &fsize->stepwise.min_height);
1763 if (fsize->stepwise.min_width < 48)
1764 fsize->stepwise.min_width = 48;
1765 if (fsize->stepwise.min_height < 38)
1766 fsize->stepwise.min_height = 38;
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02001767 fsize->stepwise.max_width = maxw;
1768 fsize->stepwise.max_height = maxh;
1769 fsize->stepwise.step_width = 1;
1770 fsize->stepwise.step_height = 1;
1771 return 0;
1772}
1773
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001774/* RAW VBI ioctls */
1775
1776static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1777 struct v4l2_format *format)
1778{
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001779 struct em28xx_fh *fh = priv;
1780 struct em28xx *dev = fh->dev;
1781
1782 format->fmt.vbi.samples_per_line = dev->vbi_width;
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001783 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1784 format->fmt.vbi.offset = 0;
1785 format->fmt.vbi.flags = 0;
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001786 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1787 format->fmt.vbi.count[0] = dev->vbi_height;
1788 format->fmt.vbi.count[1] = dev->vbi_height;
Hans Verkuil2a221d32012-09-07 08:51:32 -03001789 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001790
1791 /* Varies by video standard (NTSC, PAL, etc.) */
Devin Heitmueller66d9cba2009-11-24 23:17:25 -03001792 if (dev->norm & V4L2_STD_525_60) {
1793 /* NTSC */
1794 format->fmt.vbi.start[0] = 10;
1795 format->fmt.vbi.start[1] = 273;
1796 } else if (dev->norm & V4L2_STD_625_50) {
1797 /* PAL */
1798 format->fmt.vbi.start[0] = 6;
1799 format->fmt.vbi.start[1] = 318;
1800 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03001801
1802 return 0;
1803}
1804
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001805/* ----------------------------------------------------------- */
1806/* RADIO ESPECIFIC IOCTLS */
1807/* ----------------------------------------------------------- */
1808
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001809static int radio_g_tuner(struct file *file, void *priv,
1810 struct v4l2_tuner *t)
1811{
1812 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1813
1814 if (unlikely(t->index > 0))
1815 return -EINVAL;
1816
1817 strcpy(t->name, "Radio");
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001818
Frank Schaefer95d26082014-03-24 16:33:09 -03001819 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t);
Mauro Carvalho Chehabefc52a92008-12-16 22:04:56 -03001820
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001821 return 0;
1822}
1823
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001824static int radio_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001825 const struct v4l2_tuner *t)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001826{
1827 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1828
1829 if (0 != t->index)
1830 return -EINVAL;
1831
Frank Schaefer95d26082014-03-24 16:33:09 -03001832 v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001833
1834 return 0;
1835}
1836
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03001837/*
Frank Schaefer95d26082014-03-24 16:33:09 -03001838 * em28xx_free_v4l2() - Free struct em28xx_v4l2
1839 *
1840 * @ref: struct kref for struct em28xx_v4l2
1841 *
1842 * Called when all users of struct em28xx_v4l2 are gone
1843 */
1844void em28xx_free_v4l2(struct kref *ref)
1845{
1846 struct em28xx_v4l2 *v4l2 = container_of(ref, struct em28xx_v4l2, ref);
1847
1848 kfree(v4l2);
1849}
1850
1851/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001852 * em28xx_v4l2_open()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001853 * inits the device and starts isoc transfer
1854 */
Hans Verkuilbec43662008-12-30 06:58:20 -03001855static int em28xx_v4l2_open(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001856{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001857 struct video_device *vdev = video_devdata(filp);
1858 struct em28xx *dev = video_drvdata(filp);
Frank Schaefer95d26082014-03-24 16:33:09 -03001859 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001860 enum v4l2_buf_type fh_type = 0;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001861 struct em28xx_fh *fh;
Markus Rechberger9c755412005-11-08 21:37:52 -08001862
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001863 switch (vdev->vfl_type) {
1864 case VFL_TYPE_GRABBER:
1865 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1866 break;
1867 case VFL_TYPE_VBI:
1868 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1869 break;
Frank Schaefer4e170242014-01-12 13:24:18 -03001870 case VFL_TYPE_RADIO:
1871 break;
1872 default:
1873 return -EINVAL;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001874 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03001875
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001876 em28xx_videodbg("open dev=%s type=%s users=%d\n",
1877 video_device_node_name(vdev), v4l2_type_names[fh_type],
1878 dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001879
Hans Verkuil876cb142012-06-23 08:12:47 -03001880 if (mutex_lock_interruptible(&dev->lock))
1881 return -ERESTARTSYS;
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001882 fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001883 if (!fh) {
1884 em28xx_errdev("em28xx-video.c: Out of memory?!\n");
Hans Verkuil876cb142012-06-23 08:12:47 -03001885 mutex_unlock(&dev->lock);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001886 return -ENOMEM;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001887 }
Hans Verkuil69a61642012-09-07 05:52:40 -03001888 v4l2_fh_init(&fh->fh, vdev);
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001889 fh->dev = dev;
Aidan Thorntond7aa8022008-04-13 14:38:47 -03001890 fh->type = fh_type;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03001891 filp->private_data = fh;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001892
Frank Schaefer4e170242014-01-12 13:24:18 -03001893 if (dev->users == 0) {
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001894 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001895
Frank Schaefer4e170242014-01-12 13:24:18 -03001896 if (vdev->vfl_type != VFL_TYPE_RADIO)
1897 em28xx_resolution_set(dev);
1898
1899 /*
1900 * Needed, since GPIO might have disabled power
1901 * of some i2c devices
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001902 */
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03001903 em28xx_wake_i2c(dev);
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001904 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001905
1906 if (vdev->vfl_type == VFL_TYPE_RADIO) {
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001907 em28xx_videodbg("video_open: setting radio device\n");
Frank Schaefer95d26082014-03-24 16:33:09 -03001908 v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_radio);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001909 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001910
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001911 kref_get(&dev->ref);
Frank Schaefer95d26082014-03-24 16:33:09 -03001912 kref_get(&v4l2->ref);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001913 dev->users++;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001914
Hans Verkuil876cb142012-06-23 08:12:47 -03001915 mutex_unlock(&dev->lock);
Hans Verkuil69a61642012-09-07 05:52:40 -03001916 v4l2_fh_add(&fh->fh);
Mauro Carvalho Chehabc67ec532008-04-17 21:48:00 -03001917
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03001918 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001919}
1920
1921/*
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001922 * em28xx_v4l2_fini()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001923 * unregisters the v4l2,i2c and usb devices
1924 * called when the device gets disconected or at module unload
1925*/
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001926static int em28xx_v4l2_fini(struct em28xx *dev)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001927{
Frank Schaefer95d26082014-03-24 16:33:09 -03001928 struct em28xx_v4l2 *v4l2 = dev->v4l2;
1929
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03001930 if (dev->is_audio_only) {
1931 /* Shouldn't initialize IR for this interface */
1932 return 0;
1933 }
1934
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001935 if (!dev->has_video) {
1936 /* This device does not support the v4l2 extension */
1937 return 0;
1938 }
Mauro Carvalho Chehabe5589be2006-01-23 17:11:08 -02001939
Frank Schaefer95d26082014-03-24 16:33:09 -03001940 if (v4l2 == NULL)
1941 return 0;
1942
Mauro Carvalho Chehabaa929ad2014-01-12 19:22:07 -03001943 em28xx_info("Closing video extension");
1944
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001945 mutex_lock(&dev->lock);
1946
Frank Schaefer95d26082014-03-24 16:33:09 -03001947 v4l2_device_disconnect(&v4l2->v4l2_dev);
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001948
Frank Schaefer23e86422014-01-12 13:24:20 -03001949 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
1950
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001951 if (dev->radio_dev) {
Frank Schaefere8470222014-01-12 13:24:25 -03001952 em28xx_info("V4L2 device %s deregistered\n",
1953 video_device_node_name(dev->radio_dev));
1954 video_unregister_device(dev->radio_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001955 }
1956 if (dev->vbi_dev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001957 em28xx_info("V4L2 device %s deregistered\n",
1958 video_device_node_name(dev->vbi_dev));
Frank Schaefere8470222014-01-12 13:24:25 -03001959 video_unregister_device(dev->vbi_dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001960 }
1961 if (dev->vdev) {
Laurent Pinchart38c7c032009-11-27 13:57:15 -03001962 em28xx_info("V4L2 device %s deregistered\n",
1963 video_device_node_name(dev->vdev));
Frank Schaefere8470222014-01-12 13:24:25 -03001964 video_unregister_device(dev->vdev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03001965 }
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001966
Frank Schaefer103f18a2014-01-17 14:45:30 -03001967 v4l2_ctrl_handler_free(&dev->ctrl_handler);
Frank Schaefer95d26082014-03-24 16:33:09 -03001968 v4l2_device_unregister(&v4l2->v4l2_dev);
Frank Schaefer103f18a2014-01-17 14:45:30 -03001969
Frank Schaefer25dd1652014-01-12 13:24:23 -03001970 if (dev->clk) {
1971 v4l2_clk_unregister_fixed(dev->clk);
1972 dev->clk = NULL;
1973 }
1974
Frank Schaefer95d26082014-03-24 16:33:09 -03001975 kref_put(&v4l2->ref, em28xx_free_v4l2);
1976
Mauro Carvalho Chehabebbfbc22014-01-13 02:53:44 -03001977 mutex_unlock(&dev->lock);
Frank Schaefer95d26082014-03-24 16:33:09 -03001978
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03001979 kref_put(&dev->ref, em28xx_free_device);
Frank Schaefer5ad10de2014-01-12 13:24:21 -03001980
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03001981 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001982}
1983
Shuah Khana61f6812014-02-21 21:50:17 -03001984static int em28xx_v4l2_suspend(struct em28xx *dev)
1985{
1986 if (dev->is_audio_only)
1987 return 0;
1988
1989 if (!dev->has_video)
1990 return 0;
1991
1992 em28xx_info("Suspending video extension");
1993 em28xx_stop_urbs(dev);
1994 return 0;
1995}
1996
1997static int em28xx_v4l2_resume(struct em28xx *dev)
1998{
1999 if (dev->is_audio_only)
2000 return 0;
2001
2002 if (!dev->has_video)
2003 return 0;
2004
2005 em28xx_info("Resuming video extension");
2006 /* what do we do here */
2007 return 0;
2008}
2009
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002010/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08002011 * em28xx_v4l2_close()
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002012 * stops streaming and deallocates all resources allocated by the v4l2
2013 * calls and ioctls
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002014 */
Hans Verkuilbec43662008-12-30 06:58:20 -03002015static int em28xx_v4l2_close(struct file *filp)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002016{
Frank Schaefer95d26082014-03-24 16:33:09 -03002017 struct em28xx_fh *fh = filp->private_data;
2018 struct em28xx *dev = fh->dev;
2019 struct em28xx_v4l2 *v4l2 = dev->v4l2;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03002020 int errCode;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002021
Mauro Carvalho Chehabeac94352005-11-08 21:38:43 -08002022 em28xx_videodbg("users=%d\n", dev->users);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002023
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002024 vb2_fop_release(filp);
Ricardo Ribalda98c24dcd2013-11-06 05:39:35 -03002025 mutex_lock(&dev->lock);
Devin Heitmueller8c873d32009-09-03 00:23:27 -03002026
Devin Heitmuellere3ba4d32009-09-15 00:18:06 -03002027 if (dev->users == 1) {
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002028 /* No sense to try to write to the device */
2029 if (dev->disconnected)
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002030 goto exit;
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03002031
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03002032 /* Save some power by putting tuner to sleep */
Frank Schaefer95d26082014-03-24 16:33:09 -03002033 v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabeb6c9632008-12-05 10:39:12 -03002034
Aidan Thorntond7aa8022008-04-13 14:38:47 -03002035 /* do this before setting alternate! */
Mauro Carvalho Chehab2fe3e2e2008-11-27 09:10:40 -03002036 em28xx_set_mode(dev, EM28XX_SUSPEND);
Aidan Thorntond7aa8022008-04-13 14:38:47 -03002037
Mauro Carvalho Chehaba3a048c2007-11-10 22:21:01 -03002038 /* set alternate 0 */
2039 dev->alt = 0;
2040 em28xx_videodbg("setting alternate 0\n");
2041 errCode = usb_set_interface(dev->udev, 0, 0);
2042 if (errCode < 0) {
2043 em28xx_errdev("cannot change alternate number to "
2044 "0 (error=%i)\n", errCode);
2045 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002046 }
Devin Heitmueller28abf0832009-09-01 01:54:54 -03002047
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002048exit:
Frank Schaefer95d26082014-03-24 16:33:09 -03002049 kref_put(&v4l2->ref, em28xx_free_v4l2);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002050 dev->users--;
Hans Verkuil876cb142012-06-23 08:12:47 -03002051 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002052 kref_put(&dev->ref, em28xx_free_device);
2053
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002054 return 0;
2055}
2056
Frank Schaefere8470222014-01-12 13:24:25 -03002057/*
2058 * em28xx_videodevice_release()
2059 * called when the last user of the video device exits and frees the memeory
2060 */
2061static void em28xx_videodevice_release(struct video_device *vdev)
2062{
2063 struct em28xx *dev = video_get_drvdata(vdev);
2064
2065 video_device_release(vdev);
2066 if (vdev == dev->vdev)
2067 dev->vdev = NULL;
2068 else if (vdev == dev->vbi_dev)
2069 dev->vbi_dev = NULL;
2070 else if (vdev == dev->radio_dev)
2071 dev->radio_dev = NULL;
2072}
2073
Hans Verkuilbec43662008-12-30 06:58:20 -03002074static const struct v4l2_file_operations em28xx_v4l_fops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002075 .owner = THIS_MODULE,
2076 .open = em28xx_v4l2_open,
2077 .release = em28xx_v4l2_close,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002078 .read = vb2_fop_read,
2079 .poll = vb2_fop_poll,
2080 .mmap = vb2_fop_mmap,
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002081 .unlocked_ioctl = video_ioctl2,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002082};
2083
Hans Verkuila3998102008-07-21 02:57:38 -03002084static const struct v4l2_ioctl_ops video_ioctl_ops = {
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002085 .vidioc_querycap = vidioc_querycap,
Hans Verkuil78b526a2008-05-28 12:16:41 -03002086 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
2087 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
2088 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
2089 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller28abf0832009-09-01 01:54:54 -03002090 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil2a221d32012-09-07 08:51:32 -03002091 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Frank Schaeferaab34612013-02-07 13:39:16 -03002092 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Mauro Carvalho Chehab1c5c50682011-10-16 13:52:43 -02002093 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002094 .vidioc_g_audio = vidioc_g_audio,
2095 .vidioc_s_audio = vidioc_s_audio,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002096
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002097 .vidioc_reqbufs = vb2_ioctl_reqbufs,
2098 .vidioc_create_bufs = vb2_ioctl_create_bufs,
2099 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
2100 .vidioc_querybuf = vb2_ioctl_querybuf,
2101 .vidioc_qbuf = vb2_ioctl_qbuf,
2102 .vidioc_dqbuf = vb2_ioctl_dqbuf,
2103
Devin Heitmueller19bf0032009-09-11 00:40:18 -03002104 .vidioc_g_std = vidioc_g_std,
Mauro Carvalho Chehabd56ae6f2011-10-04 09:53:00 -03002105 .vidioc_querystd = vidioc_querystd,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002106 .vidioc_s_std = vidioc_s_std,
Mauro Carvalho Chehabd96ecda2009-08-06 21:53:59 -03002107 .vidioc_g_parm = vidioc_g_parm,
2108 .vidioc_s_parm = vidioc_s_parm,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002109 .vidioc_enum_input = vidioc_enum_input,
2110 .vidioc_g_input = vidioc_g_input,
2111 .vidioc_s_input = vidioc_s_input,
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002112 .vidioc_streamon = vb2_ioctl_streamon,
2113 .vidioc_streamoff = vb2_ioctl_streamoff,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002114 .vidioc_g_tuner = vidioc_g_tuner,
2115 .vidioc_s_tuner = vidioc_s_tuner,
2116 .vidioc_g_frequency = vidioc_g_frequency,
2117 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002118 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2119 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002120#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuil96b03d22013-04-06 06:16:58 -03002121 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002122 .vidioc_g_register = vidioc_g_register,
2123 .vidioc_s_register = vidioc_s_register,
2124#endif
Hans Verkuila3998102008-07-21 02:57:38 -03002125};
2126
2127static const struct video_device em28xx_video_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002128 .fops = &em28xx_v4l_fops,
2129 .ioctl_ops = &video_ioctl_ops,
2130 .release = em28xx_videodevice_release,
2131 .tvnorms = V4L2_STD_ALL,
Mauro Carvalho Chehab195a4ef2007-11-11 13:17:17 -03002132};
2133
Hans Verkuilbec43662008-12-30 06:58:20 -03002134static const struct v4l2_file_operations radio_fops = {
Hans Verkuila3998102008-07-21 02:57:38 -03002135 .owner = THIS_MODULE,
2136 .open = em28xx_v4l2_open,
2137 .release = em28xx_v4l2_close,
Hans Verkuil8fd0bda2010-12-18 09:59:51 -03002138 .unlocked_ioctl = video_ioctl2,
Hans Verkuila3998102008-07-21 02:57:38 -03002139};
2140
2141static const struct v4l2_ioctl_ops radio_ioctl_ops = {
Hans Verkuila9d79fe2012-09-06 07:31:04 -03002142 .vidioc_querycap = vidioc_querycap,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002143 .vidioc_g_tuner = radio_g_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002144 .vidioc_s_tuner = radio_s_tuner,
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002145 .vidioc_g_frequency = vidioc_g_frequency,
2146 .vidioc_s_frequency = vidioc_s_frequency,
Hans Verkuil50fdf402012-09-07 06:10:12 -03002147 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2148 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002149#ifdef CONFIG_VIDEO_ADV_DEBUG
Michal Marek430c73f2013-04-16 08:06:30 -03002150 .vidioc_g_chip_info = vidioc_g_chip_info,
Mauro Carvalho Chehab1e7ad562008-02-06 09:00:41 -03002151 .vidioc_g_register = vidioc_g_register,
2152 .vidioc_s_register = vidioc_s_register,
2153#endif
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002154};
2155
Hans Verkuila3998102008-07-21 02:57:38 -03002156static struct video_device em28xx_radio_template = {
Frank Schaefere8470222014-01-12 13:24:25 -03002157 .fops = &radio_fops,
2158 .ioctl_ops = &radio_ioctl_ops,
2159 .release = em28xx_videodevice_release,
Hans Verkuila3998102008-07-21 02:57:38 -03002160};
2161
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002162/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2163static unsigned short saa711x_addrs[] = {
2164 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2165 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2166 I2C_CLIENT_END };
2167
2168static unsigned short tvp5150_addrs[] = {
2169 0xb8 >> 1,
2170 0xba >> 1,
2171 I2C_CLIENT_END
2172};
2173
2174static unsigned short msp3400_addrs[] = {
2175 0x80 >> 1,
2176 0x88 >> 1,
2177 I2C_CLIENT_END
2178};
2179
Douglas Schilling Landgraf6ea54d92008-04-17 21:41:10 -03002180/******************************** usb interface ******************************/
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08002181
Adrian Bunk532fe652008-01-28 22:10:48 -03002182static struct video_device *em28xx_vdev_init(struct em28xx *dev,
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002183 const struct video_device *template,
2184 const char *type_name)
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002185{
2186 struct video_device *vfd;
2187
2188 vfd = video_device_alloc();
2189 if (NULL == vfd)
2190 return NULL;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002191
2192 *vfd = *template;
Frank Schaefer95d26082014-03-24 16:33:09 -03002193 vfd->v4l2_dev = &dev->v4l2->v4l2_dev;
Douglas Schilling Landgraff2cf2502009-03-31 17:10:58 -03002194 vfd->debug = video_debug;
Hans Verkuil0499a5a2010-09-26 07:34:45 -03002195 vfd->lock = &dev->lock;
Hans Verkuil69a61642012-09-07 05:52:40 -03002196 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
Hans Verkuild8c95c02012-09-07 07:31:54 -03002197 if (dev->board.is_webcam)
2198 vfd->tvnorms = 0;
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002199
2200 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
2201 dev->name, type_name);
2202
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002203 video_set_drvdata(vfd, dev);
Mauro Carvalho Chehab0be43752008-01-05 17:22:01 -03002204 return vfd;
2205}
2206
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002207static void em28xx_tuner_setup(struct em28xx *dev)
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002208{
Frank Schaefer95d26082014-03-24 16:33:09 -03002209 struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev;
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002210 struct tuner_setup tun_setup;
2211 struct v4l2_frequency f;
2212
2213 if (dev->tuner_type == TUNER_ABSENT)
2214 return;
2215
2216 memset(&tun_setup, 0, sizeof(tun_setup));
2217
2218 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2219 tun_setup.tuner_callback = em28xx_tuner_callback;
2220
2221 if (dev->board.radio.type) {
2222 tun_setup.type = dev->board.radio.type;
2223 tun_setup.addr = dev->board.radio_addr;
2224
Frank Schaefer95d26082014-03-24 16:33:09 -03002225 v4l2_device_call_all(v4l2_dev,
2226 0, tuner, s_type_addr, &tun_setup);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002227 }
2228
2229 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2230 tun_setup.type = dev->tuner_type;
2231 tun_setup.addr = dev->tuner_addr;
2232
Frank Schaefer95d26082014-03-24 16:33:09 -03002233 v4l2_device_call_all(v4l2_dev,
2234 0, tuner, s_type_addr, &tun_setup);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002235 }
2236
2237 if (dev->tda9887_conf) {
2238 struct v4l2_priv_tun_config tda9887_cfg;
2239
2240 tda9887_cfg.tuner = TUNER_TDA9887;
2241 tda9887_cfg.priv = &dev->tda9887_conf;
2242
Frank Schaefer95d26082014-03-24 16:33:09 -03002243 v4l2_device_call_all(v4l2_dev,
2244 0, tuner, s_config, &tda9887_cfg);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002245 }
2246
2247 if (dev->tuner_type == TUNER_XC2028) {
2248 struct v4l2_priv_tun_config xc2028_cfg;
2249 struct xc2028_ctrl ctl;
2250
2251 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2252 memset(&ctl, 0, sizeof(ctl));
2253
2254 em28xx_setup_xc3028(dev, &ctl);
2255
2256 xc2028_cfg.tuner = TUNER_XC2028;
2257 xc2028_cfg.priv = &ctl;
2258
Frank Schaefer95d26082014-03-24 16:33:09 -03002259 v4l2_device_call_all(v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002260 }
2261
2262 /* configure tuner */
2263 f.tuner = 0;
2264 f.type = V4L2_TUNER_ANALOG_TV;
2265 f.frequency = 9076; /* just a magic number */
2266 dev->ctl_freq = f.frequency;
Frank Schaefer95d26082014-03-24 16:33:09 -03002267 v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency, &f);
Mauro Carvalho Chehab0560f332013-12-22 15:28:26 -03002268}
2269
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002270static int em28xx_v4l2_init(struct em28xx *dev)
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002271{
Hans Verkuil081b9452012-09-07 05:43:59 -03002272 u8 val;
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002273 int ret;
Sascha Sommer1020d132012-01-08 16:54:28 -03002274 unsigned int maxw;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002275 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
Frank Schaefer95d26082014-03-24 16:33:09 -03002276 struct em28xx_v4l2 *v4l2;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002277
Mauro Carvalho Chehab822b8de2014-01-06 05:27:47 -03002278 if (dev->is_audio_only) {
2279 /* Shouldn't initialize IR for this interface */
2280 return 0;
2281 }
2282
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002283 if (!dev->has_video) {
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002284 /* This device does not support the v4l2 extension */
2285 return 0;
2286 }
Mauro Carvalho Chehab2e5ef2d2008-12-28 22:26:36 -03002287
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002288 em28xx_info("Registering V4L2 extension\n");
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002289
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002290 mutex_lock(&dev->lock);
2291
Frank Schaefer95d26082014-03-24 16:33:09 -03002292 v4l2 = kzalloc(sizeof(struct em28xx_v4l2), GFP_KERNEL);
2293 if (v4l2 == NULL) {
2294 em28xx_info("em28xx_v4l: memory allocation failed\n");
2295 mutex_unlock(&dev->lock);
2296 return -ENOMEM;
2297 }
2298 kref_init(&v4l2->ref);
2299 dev->v4l2 = v4l2;
2300
2301 ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002302 if (ret < 0) {
2303 em28xx_errdev("Call to v4l2_device_register() failed!\n");
2304 goto err;
2305 }
2306
2307 v4l2_ctrl_handler_init(hdl, 8);
Frank Schaefer95d26082014-03-24 16:33:09 -03002308 v4l2->v4l2_dev.ctrl_handler = hdl;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002309
2310 /*
2311 * Default format, used for tvp5150 or saa711x output formats
2312 */
2313 dev->vinmode = 0x10;
2314 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2315 EM28XX_VINCTRL_CCIR656_ENABLE;
2316
2317 /* request some modules */
2318
2319 if (dev->board.has_msp34xx)
Frank Schaefer95d26082014-03-24 16:33:09 -03002320 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2321 &dev->i2c_adap[dev->def_i2c_bus],
2322 "msp3400", 0, msp3400_addrs);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002323
2324 if (dev->board.decoder == EM28XX_SAA711X)
Frank Schaefer95d26082014-03-24 16:33:09 -03002325 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2326 &dev->i2c_adap[dev->def_i2c_bus],
2327 "saa7115_auto", 0, saa711x_addrs);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002328
2329 if (dev->board.decoder == EM28XX_TVP5150)
Frank Schaefer95d26082014-03-24 16:33:09 -03002330 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2331 &dev->i2c_adap[dev->def_i2c_bus],
2332 "tvp5150", 0, tvp5150_addrs);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002333
2334 if (dev->board.adecoder == EM28XX_TVAUDIO)
Frank Schaefer95d26082014-03-24 16:33:09 -03002335 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2336 &dev->i2c_adap[dev->def_i2c_bus],
2337 "tvaudio", dev->board.tvaudio_addr, NULL);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002338
2339 /* Initialize tuner and camera */
2340
2341 if (dev->board.tuner_type != TUNER_ABSENT) {
2342 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2343
2344 if (dev->board.radio.type)
Frank Schaefer95d26082014-03-24 16:33:09 -03002345 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2346 &dev->i2c_adap[dev->def_i2c_bus],
2347 "tuner", dev->board.radio_addr, NULL);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002348
2349 if (has_demod)
Frank Schaefer95d26082014-03-24 16:33:09 -03002350 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002351 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2352 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2353 if (dev->tuner_addr == 0) {
2354 enum v4l2_i2c_tuner_type type =
2355 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2356 struct v4l2_subdev *sd;
2357
Frank Schaefer95d26082014-03-24 16:33:09 -03002358 sd = v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002359 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2360 0, v4l2_i2c_tuner_addrs(type));
2361
2362 if (sd)
2363 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2364 } else {
Frank Schaefer95d26082014-03-24 16:33:09 -03002365 v4l2_i2c_new_subdev(&v4l2->v4l2_dev,
2366 &dev->i2c_adap[dev->def_i2c_bus],
2367 "tuner", dev->tuner_addr, NULL);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002368 }
2369 }
2370
2371 em28xx_tuner_setup(dev);
Frank Schaeferd86bc652014-01-17 14:45:32 -03002372 if (dev->em28xx_sensor != EM28XX_NOSENSOR)
2373 em28xx_init_camera(dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002374
2375 /* Configure audio */
2376 ret = em28xx_audio_setup(dev);
2377 if (ret < 0) {
2378 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2379 __func__, ret);
2380 goto unregister_dev;
2381 }
2382 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
2383 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2384 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
2385 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2386 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
2387 } else {
2388 /* install the em28xx notify callback */
2389 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
2390 em28xx_ctrl_notify, dev);
2391 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
2392 em28xx_ctrl_notify, dev);
2393 }
2394
2395 /* wake i2c devices */
2396 em28xx_wake_i2c(dev);
2397
2398 /* init video dma queues */
2399 INIT_LIST_HEAD(&dev->vidq.active);
2400 INIT_LIST_HEAD(&dev->vbiq.active);
2401
2402 if (dev->board.has_msp34xx) {
2403 /* Send a reset to other chips via gpio */
2404 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
2405 if (ret < 0) {
2406 em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
2407 __func__, ret);
2408 goto unregister_dev;
2409 }
2410 msleep(3);
2411
2412 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
2413 if (ret < 0) {
2414 em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
2415 __func__, ret);
2416 goto unregister_dev;
2417 }
2418 msleep(3);
2419 }
2420
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002421 /* set default norm */
Hans Verkuild8c95c02012-09-07 07:31:54 -03002422 dev->norm = V4L2_STD_PAL;
Frank Schaefer95d26082014-03-24 16:33:09 -03002423 v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_std, dev->norm);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002424 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002425
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002426 /* Analog specific initialization */
2427 dev->format = &format[0];
Sascha Sommer1020d132012-01-08 16:54:28 -03002428
2429 maxw = norm_maxw(dev);
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002430 /* MaxPacketSize for em2800 is too small to capture at full resolution
2431 * use half of maxw as the scaler can only scale to 50% */
2432 if (dev->board.is_em2800)
2433 maxw /= 2;
Sascha Sommer1020d132012-01-08 16:54:28 -03002434
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002435 em28xx_set_video_format(dev, format[0].fourcc,
Sascha Sommer1020d132012-01-08 16:54:28 -03002436 maxw, norm_maxh(dev));
Mauro Carvalho Chehabed5f1432009-07-02 17:34:04 -03002437
Ezequiel García96371fc2012-03-23 18:09:34 -03002438 video_mux(dev, 0);
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002439
2440 /* Audio defaults */
2441 dev->mute = 1;
2442 dev->volume = 0x1f;
2443
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002444/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002445 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2446 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2447 (EM28XX_XCLK_AUDIO_UNMUTE | val));
Mauro Carvalho Chehab24c3c412009-01-07 22:49:25 -03002448
2449 em28xx_set_outfmt(dev);
Mauro Carvalho Chehab1a23f812008-12-28 22:18:14 -03002450
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002451 /* Add image controls */
2452 /* NOTE: at this point, the subdevices are already registered, so bridge
2453 * controls are only added/enabled when no subdevice provides them */
Frank Schaeferad298052014-03-24 16:33:08 -03002454 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST))
2455 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002456 V4L2_CID_CONTRAST,
2457 0, 0x1f, 1, CONTRAST_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002458 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS))
2459 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002460 V4L2_CID_BRIGHTNESS,
2461 -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002462 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SATURATION))
2463 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002464 V4L2_CID_SATURATION,
2465 0, 0x1f, 1, SATURATION_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002466 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE))
2467 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002468 V4L2_CID_BLUE_BALANCE,
2469 -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002470 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE))
2471 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002472 V4L2_CID_RED_BALANCE,
2473 -0x30, 0x30, 1, RED_BALANCE_DEFAULT);
Frank Schaeferad298052014-03-24 16:33:08 -03002474 if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS))
2475 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002476 V4L2_CID_SHARPNESS,
2477 0, 0x0f, 1, SHARPNESS_DEFAULT);
2478
2479 /* Reset image controls */
2480 em28xx_colorlevels_set_default(dev);
Frank Schaeferad298052014-03-24 16:33:08 -03002481 v4l2_ctrl_handler_setup(hdl);
2482 ret = hdl->error;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002483 if (ret)
2484 goto unregister_dev;
Frank Schaefer8f8b113a2013-02-15 14:38:32 -03002485
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002486 /* allocate and fill video video_device struct */
2487 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
2488 if (!dev->vdev) {
2489 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002490 ret = -ENODEV;
2491 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002492 }
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002493 dev->vdev->queue = &dev->vb_vidq;
2494 dev->vdev->queue->lock = &dev->vb_queue_lock;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002495
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002496 /* disable inapplicable ioctls */
2497 if (dev->board.is_webcam) {
2498 v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD);
2499 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD);
2500 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD);
Frank Schaefer3bc85cc2013-02-07 13:39:12 -03002501 } else {
2502 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002503 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002504 if (dev->tuner_type == TUNER_ABSENT) {
2505 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER);
2506 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_TUNER);
2507 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY);
2508 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY);
2509 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002510 if (!dev->audio_mode.has_audio) {
2511 v4l2_disable_ioctl(dev->vdev, VIDIOC_G_AUDIO);
2512 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_AUDIO);
2513 }
Frank Schaefer6e46dab2013-02-07 13:39:09 -03002514
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002515 /* register v4l2 video video_device */
2516 ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
2517 video_nr[dev->devno]);
2518 if (ret) {
2519 em28xx_errdev("unable to register video device (error=%i).\n",
2520 ret);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002521 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002522 }
2523
2524 /* Allocate and fill vbi video_device struct */
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002525 if (em28xx_vbi_supported(dev) == 1) {
2526 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
2527 "vbi");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002528
Devin Heitmuellerd3829fa2013-01-04 16:16:24 -03002529 dev->vbi_dev->queue = &dev->vb_vbiq;
2530 dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock;
2531
Frank Schaefer66df67b2013-02-07 13:39:10 -03002532 /* disable inapplicable ioctls */
Frank Schaefer83c8bcc2013-02-07 13:39:13 -03002533 v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM);
Frank Schaefer66df67b2013-02-07 13:39:10 -03002534 if (dev->tuner_type == TUNER_ABSENT) {
2535 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER);
2536 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER);
2537 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY);
2538 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY);
2539 }
Frank Schaeferc2dcef82013-02-07 13:39:11 -03002540 if (!dev->audio_mode.has_audio) {
2541 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_AUDIO);
2542 v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_AUDIO);
2543 }
Frank Schaefer66df67b2013-02-07 13:39:10 -03002544
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002545 /* register v4l2 vbi video_device */
2546 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
2547 vbi_nr[dev->devno]);
2548 if (ret < 0) {
2549 em28xx_errdev("unable to register vbi device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002550 goto unregister_dev;
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002551 }
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002552 }
2553
2554 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
Nicola Soranzoa1a6ee72009-02-10 23:28:24 -03002555 dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
2556 "radio");
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002557 if (!dev->radio_dev) {
2558 em28xx_errdev("cannot allocate video_device.\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002559 ret = -ENODEV;
2560 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002561 }
2562 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
2563 radio_nr[dev->devno]);
2564 if (ret < 0) {
2565 em28xx_errdev("can't register radio device\n");
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002566 goto unregister_dev;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002567 }
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002568 em28xx_info("Registered radio device as %s\n",
2569 video_device_node_name(dev->radio_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002570 }
2571
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002572 em28xx_info("V4L2 video device registered as %s\n",
2573 video_device_node_name(dev->vdev));
Devin Heitmueller290c0cf2009-09-11 00:01:06 -03002574
2575 if (dev->vbi_dev)
Laurent Pinchart38c7c032009-11-27 13:57:15 -03002576 em28xx_info("V4L2 VBI device registered as %s\n",
2577 video_device_node_name(dev->vbi_dev));
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002578
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002579 /* Save some power by putting tuner to sleep */
Frank Schaefer95d26082014-03-24 16:33:09 -03002580 v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002581
2582 /* initialize videobuf2 stuff */
2583 em28xx_vb2_setup(dev);
2584
Mauro Carvalho Chehab96346142013-12-26 12:41:03 -03002585 em28xx_info("V4L2 extension successfully initialized\n");
2586
Mauro Carvalho Chehab47677e52014-03-05 11:21:07 -03002587 kref_get(&dev->ref);
2588
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002589 mutex_unlock(&dev->lock);
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002590 return 0;
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002591
2592unregister_dev:
2593 v4l2_ctrl_handler_free(&dev->ctrl_handler);
Frank Schaefer95d26082014-03-24 16:33:09 -03002594 v4l2_device_unregister(&v4l2->v4l2_dev);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002595err:
Frank Schaefer95d26082014-03-24 16:33:09 -03002596 dev->v4l2 = NULL;
2597 kref_put(&v4l2->ref, em28xx_free_v4l2);
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002598 mutex_unlock(&dev->lock);
Mauro Carvalho Chehabb64f8e92013-12-22 13:16:49 -03002599 return ret;
Mauro Carvalho Chehab818a5572008-11-20 10:30:26 -03002600}
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002601
2602static struct em28xx_ops v4l2_ops = {
2603 .id = EM28XX_V4L2,
2604 .name = "Em28xx v4l2 Extension",
2605 .init = em28xx_v4l2_init,
2606 .fini = em28xx_v4l2_fini,
Shuah Khana61f6812014-02-21 21:50:17 -03002607 .suspend = em28xx_v4l2_suspend,
2608 .resume = em28xx_v4l2_resume,
Mauro Carvalho Chehab01c28192013-12-22 13:27:02 -03002609};
2610
2611static int __init em28xx_video_register(void)
2612{
2613 return em28xx_register_extension(&v4l2_ops);
2614}
2615
2616static void __exit em28xx_video_unregister(void)
2617{
2618 em28xx_unregister_extension(&v4l2_ops);
2619}
2620
2621module_init(em28xx_video_register);
2622module_exit(em28xx_video_unregister);