blob: 923d59a321f8a9e150685447ecc12fc54044ca24 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03007 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
Martin Samuelssonfbe60da2006-04-27 10:17:00 -030030#include <linux/delay.h>
31
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/types.h>
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/vmalloc.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090037#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39#include <linux/proc_fs.h>
40#include <linux/i2c.h>
41#include <linux/i2c-algo-bit.h>
Hans Verkuil7f6adea2009-02-19 17:31:17 -030042#include <linux/videodev2.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/spinlock.h>
44#include <linux/sem.h>
45#include <linux/kmod.h>
46#include <linux/wait.h>
47
48#include <linux/pci.h>
49#include <linux/interrupt.h>
Ingo Molnar384c3682006-03-22 03:54:16 -030050#include <linux/mutex.h>
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -030051#include <linux/io.h>
52#include <media/v4l2-common.h>
53#include <media/bt819.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55#include "videocodec.h"
56#include "zoran.h"
57#include "zoran_card.h"
58#include "zoran_device.h"
59#include "zoran_procfs.h"
60
Linus Torvalds1da177e2005-04-16 15:20:36 -070061extern const struct zoran_format zoran_formats[];
62
Trent Piepho45bdcef2009-01-12 13:09:46 -030063static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
Trent Piepho60e3cac2007-07-17 18:29:42 -030064module_param_array(card, int, NULL, 0444);
Trent Piepho45bdcef2009-01-12 13:09:46 -030065MODULE_PARM_DESC(card, "Card type");
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Linus Torvalds1da177e2005-04-16 15:20:36 -070067/*
68 The video mem address of the video card.
69 The driver has a little database for some videocards
70 to determine it from there. If your video card is not in there
71 you have either to give it to the driver as a parameter
72 or set in in a VIDIOCSFBUF ioctl
73 */
74
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030075static unsigned long vidmem; /* default = 0 - Video memory base address */
Trent Piepho60e3cac2007-07-17 18:29:42 -030076module_param(vidmem, ulong, 0444);
77MODULE_PARM_DESC(vidmem, "Default video memory base address");
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
79/*
80 Default input and video norm at startup of the driver.
81*/
82
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030083static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */
Trent Piepho60e3cac2007-07-17 18:29:42 -030084module_param(default_input, uint, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070085MODULE_PARM_DESC(default_input,
86 "Default input (0=Composite, 1=S-Video, 2=Internal)");
87
Martin Samuelssonfbe60da2006-04-27 10:17:00 -030088static int default_mux = 1; /* 6 Eyes input selection */
Trent Piepho60e3cac2007-07-17 18:29:42 -030089module_param(default_mux, int, 0644);
Martin Samuelssonfbe60da2006-04-27 10:17:00 -030090MODULE_PARM_DESC(default_mux,
91 "Default 6 Eyes mux setting (Input selection)");
92
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030093static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */
Trent Piepho60e3cac2007-07-17 18:29:42 -030094module_param(default_norm, int, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
96
Trent Piepho60e3cac2007-07-17 18:29:42 -030097/* /dev/videoN, -1 for autodetect */
Trent Piepho45bdcef2009-01-12 13:09:46 -030098static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
Trent Piepho60e3cac2007-07-17 18:29:42 -030099module_param_array(video_nr, int, NULL, 0444);
Trent Piepho45bdcef2009-01-12 13:09:46 -0300100MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Hans Verkuil497d7d02009-02-18 18:33:35 -0300102int v4l_nbufs = 4;
Hans Verkuile686e732009-02-20 15:06:59 -0300103int v4l_bufsize = 864; /* Everybody should be able to work with this setting */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300104module_param(v4l_nbufs, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
Trent Piepho60e3cac2007-07-17 18:29:42 -0300106module_param(v4l_bufsize, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
108
109int jpg_nbufs = 32;
110int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300111module_param(jpg_nbufs, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
Trent Piepho60e3cac2007-07-17 18:29:42 -0300113module_param(jpg_bufsize, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
115
116int pass_through = 0; /* 1=Pass through TV signal when device is not used */
117 /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300118module_param(pass_through, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119MODULE_PARM_DESC(pass_through,
120 "Pass TV signal through to TV-out when idling");
121
Jean Delvare18b548c2007-07-17 18:29:41 -0300122int zr36067_debug = 1;
123module_param_named(debug, zr36067_debug, int, 0644);
124MODULE_PARM_DESC(debug, "Debug level (0-5)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -0300126#define ZORAN_VERSION "0.10.1"
127
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
129MODULE_AUTHOR("Serguei Miridonov");
130MODULE_LICENSE("GPL");
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -0300131MODULE_VERSION(ZORAN_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
Trent Piepho17faeb22009-01-12 13:09:46 -0300133#define ZR_DEVICE(subven, subdev, data) { \
134 .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
135 .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
136
Mauro Carvalho Chehabdbdf03b2009-01-08 23:27:32 -0300137static struct pci_device_id zr36067_pci_tbl[] = {
Trent Piepho17faeb22009-01-12 13:09:46 -0300138 ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
139 ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
140 ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
141 ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
142 ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
Mauro Carvalho Chehabdbdf03b2009-01-08 23:27:32 -0300143 {0}
144};
145MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
Trent Piepho601139e2009-01-12 13:09:46 -0300147static unsigned int zoran_num; /* number of cards found */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
149/* videocodec bus functions ZR36060 */
150static u32
151zr36060_read (struct videocodec *codec,
152 u16 reg)
153{
154 struct zoran *zr = (struct zoran *) codec->master_data->data;
155 __u32 data;
156
157 if (post_office_wait(zr)
158 || post_office_write(zr, 0, 1, reg >> 8)
159 || post_office_write(zr, 0, 2, reg & 0xff)) {
160 return -1;
161 }
162
163 data = post_office_read(zr, 0, 3) & 0xff;
164 return data;
165}
166
167static void
168zr36060_write (struct videocodec *codec,
169 u16 reg,
170 u32 val)
171{
172 struct zoran *zr = (struct zoran *) codec->master_data->data;
173
174 if (post_office_wait(zr)
175 || post_office_write(zr, 0, 1, reg >> 8)
176 || post_office_write(zr, 0, 2, reg & 0xff)) {
177 return;
178 }
179
180 post_office_write(zr, 0, 3, val & 0xff);
181}
182
183/* videocodec bus functions ZR36050 */
184static u32
185zr36050_read (struct videocodec *codec,
186 u16 reg)
187{
188 struct zoran *zr = (struct zoran *) codec->master_data->data;
189 __u32 data;
190
191 if (post_office_wait(zr)
192 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
193 return -1;
194 }
195
196 data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read
197 return data;
198}
199
200static void
201zr36050_write (struct videocodec *codec,
202 u16 reg,
203 u32 val)
204{
205 struct zoran *zr = (struct zoran *) codec->master_data->data;
206
207 if (post_office_wait(zr)
208 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
209 return;
210 }
211
212 post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data
213}
214
215/* videocodec bus functions ZR36016 */
216static u32
217zr36016_read (struct videocodec *codec,
218 u16 reg)
219{
220 struct zoran *zr = (struct zoran *) codec->master_data->data;
221 __u32 data;
222
223 if (post_office_wait(zr)) {
224 return -1;
225 }
226
227 data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read
228 return data;
229}
230
231/* hack for in zoran_device.c */
232void
233zr36016_write (struct videocodec *codec,
234 u16 reg,
235 u32 val)
236{
237 struct zoran *zr = (struct zoran *) codec->master_data->data;
238
239 if (post_office_wait(zr)) {
240 return;
241 }
242
243 post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data
244}
245
246/*
247 * Board specific information
248 */
249
250static void
251dc10_init (struct zoran *zr)
252{
Trent Piephoc61402b2009-03-10 23:28:33 -0300253 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254
255 /* Pixel clock selection */
256 GPIO(zr, 4, 0);
257 GPIO(zr, 5, 1);
258 /* Enable the video bus sync signals */
259 GPIO(zr, 7, 0);
260}
261
262static void
263dc10plus_init (struct zoran *zr)
264{
Trent Piephoc61402b2009-03-10 23:28:33 -0300265 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266}
267
268static void
269buz_init (struct zoran *zr)
270{
Trent Piephoc61402b2009-03-10 23:28:33 -0300271 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
273 /* some stuff from Iomega */
274 pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
275 pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
276 pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
277}
278
279static void
280lml33_init (struct zoran *zr)
281{
Trent Piephoc61402b2009-03-10 23:28:33 -0300282 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283
284 GPIO(zr, 2, 1); // Set Composite input/output
285}
286
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300287static void
288avs6eyes_init (struct zoran *zr)
289{
290 // AverMedia 6-Eyes original driver by Christer Weinigel
291
292 // Lifted straight from Christer's old driver and
293 // modified slightly by Martin Samuelsson.
294
295 int mux = default_mux; /* 1 = BT866, 7 = VID1 */
296
297 GPIO(zr, 4, 1); /* Bt866 SLEEP on */
298 udelay(2);
299
300 GPIO(zr, 0, 1); /* ZR36060 /RESET on */
301 GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
302 GPIO(zr, 2, mux & 1); /* MUX S0 */
303 GPIO(zr, 3, 0); /* /FRAME on */
304 GPIO(zr, 4, 0); /* Bt866 SLEEP off */
305 GPIO(zr, 5, mux & 2); /* MUX S1 */
306 GPIO(zr, 6, 0); /* ? */
307 GPIO(zr, 7, mux & 4); /* MUX S2 */
308
309}
310
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311static char *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312codecid_to_modulename (u16 codecid)
313{
314 char *name = NULL;
315
316 switch (codecid) {
317 case CODEC_TYPE_ZR36060:
318 name = "zr36060";
319 break;
320 case CODEC_TYPE_ZR36050:
321 name = "zr36050";
322 break;
323 case CODEC_TYPE_ZR36016:
324 name = "zr36016";
325 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 }
327
328 return name;
329}
330
331// struct tvnorm {
332// u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
333// };
334
335static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
336static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
337static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
338static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
339
340static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 };
341static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 };
342
343/* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */
344static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
345static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
346
347/* FIXME: I cannot swap U and V in saa7114, so i do one
348 * pixel left shift in zoran (75 -> 74)
349 * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */
350static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
351static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
352
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300353/* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I
354 * copy Maxim's left shift hack for the 6 Eyes.
355 *
356 * Christer's driver used the unshifted norms, though...
357 * /Sam */
358static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
359static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
360
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300361static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
362static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
363static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
364static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
365static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
366static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
367static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
368static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
369static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
370static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
371
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -0800372static struct card_info zoran_cards[NUM_CARDS] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 {
374 .type = DC10_old,
375 .name = "DC10(old)",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300376 .i2c_decoder = "vpx3220a",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300377 .addrs_decoder = vpx3220_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 .video_codec = CODEC_TYPE_ZR36050,
379 .video_vfe = CODEC_TYPE_ZR36016,
380
381 .inputs = 3,
382 .input = {
383 { 1, "Composite" },
384 { 2, "S-Video" },
385 { 0, "Internal/comp" }
386 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300387 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 .tvn = {
389 &f50sqpixel_dc10,
390 &f60sqpixel_dc10,
391 &f50sqpixel_dc10
392 },
393 .jpeg_int = 0,
394 .vsync_int = ZR36057_ISR_GIRQ1,
395 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
396 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
397 .gpcs = { -1, 0 },
398 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
399 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300400 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 .init = &dc10_init,
402 }, {
403 .type = DC10_new,
404 .name = "DC10(new)",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300405 .i2c_decoder = "saa7110",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300406 .addrs_decoder = saa7110_addrs,
407 .i2c_encoder = "adv7175",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300408 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 .video_codec = CODEC_TYPE_ZR36060,
410
411 .inputs = 3,
412 .input = {
413 { 0, "Composite" },
414 { 7, "S-Video" },
415 { 5, "Internal/comp" }
416 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300417 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 .tvn = {
419 &f50sqpixel,
420 &f60sqpixel,
421 &f50sqpixel},
422 .jpeg_int = ZR36057_ISR_GIRQ0,
423 .vsync_int = ZR36057_ISR_GIRQ1,
424 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
425 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
426 .gpcs = { -1, 1},
427 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
428 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300429 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 .init = &dc10plus_init,
431 }, {
432 .type = DC10plus,
433 .name = "DC10plus",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300434 .i2c_decoder = "saa7110",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300435 .addrs_decoder = saa7110_addrs,
436 .i2c_encoder = "adv7175",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300437 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 .video_codec = CODEC_TYPE_ZR36060,
439
440 .inputs = 3,
441 .input = {
442 { 0, "Composite" },
443 { 7, "S-Video" },
444 { 5, "Internal/comp" }
445 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300446 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 .tvn = {
448 &f50sqpixel,
449 &f60sqpixel,
450 &f50sqpixel
451 },
452 .jpeg_int = ZR36057_ISR_GIRQ0,
453 .vsync_int = ZR36057_ISR_GIRQ1,
454 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
455 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
456 .gpcs = { -1, 1 },
457 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
458 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300459 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 .init = &dc10plus_init,
461 }, {
462 .type = DC30,
463 .name = "DC30",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300464 .i2c_decoder = "vpx3220a",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300465 .addrs_decoder = vpx3220_addrs,
466 .i2c_encoder = "adv7175",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300467 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 .video_codec = CODEC_TYPE_ZR36050,
469 .video_vfe = CODEC_TYPE_ZR36016,
470
471 .inputs = 3,
472 .input = {
473 { 1, "Composite" },
474 { 2, "S-Video" },
475 { 0, "Internal/comp" }
476 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300477 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 .tvn = {
479 &f50sqpixel_dc10,
480 &f60sqpixel_dc10,
481 &f50sqpixel_dc10
482 },
483 .jpeg_int = 0,
484 .vsync_int = ZR36057_ISR_GIRQ1,
485 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
486 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
487 .gpcs = { -1, 0 },
488 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
489 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300490 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 .init = &dc10_init,
492 }, {
493 .type = DC30plus,
494 .name = "DC30plus",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300495 .i2c_decoder = "vpx3220a",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300496 .addrs_decoder = vpx3220_addrs,
497 .i2c_encoder = "adv7175",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300498 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 .video_codec = CODEC_TYPE_ZR36050,
500 .video_vfe = CODEC_TYPE_ZR36016,
501
502 .inputs = 3,
503 .input = {
504 { 1, "Composite" },
505 { 2, "S-Video" },
506 { 0, "Internal/comp" }
507 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300508 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 .tvn = {
510 &f50sqpixel_dc10,
511 &f60sqpixel_dc10,
512 &f50sqpixel_dc10
513 },
514 .jpeg_int = 0,
515 .vsync_int = ZR36057_ISR_GIRQ1,
516 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
517 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
518 .gpcs = { -1, 0 },
519 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
520 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300521 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 .init = &dc10_init,
523 }, {
524 .type = LML33,
525 .name = "LML33",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300526 .i2c_decoder = "bt819a",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300527 .addrs_decoder = bt819_addrs,
528 .i2c_encoder = "bt856",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300529 .addrs_encoder = bt856_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 .video_codec = CODEC_TYPE_ZR36060,
531
532 .inputs = 2,
533 .input = {
534 { 0, "Composite" },
535 { 7, "S-Video" }
536 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300537 .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 .tvn = {
539 &f50ccir601_lml33,
540 &f60ccir601_lml33,
541 NULL
542 },
543 .jpeg_int = ZR36057_ISR_GIRQ1,
544 .vsync_int = ZR36057_ISR_GIRQ0,
545 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
546 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
547 .gpcs = { 3, 1 },
548 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
549 .gws_not_connected = 1,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300550 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 .init = &lml33_init,
552 }, {
553 .type = LML33R10,
554 .name = "LML33R10",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300555 .i2c_decoder = "saa7114",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300556 .addrs_decoder = saa7114_addrs,
557 .i2c_encoder = "adv7170",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300558 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 .video_codec = CODEC_TYPE_ZR36060,
560
561 .inputs = 2,
562 .input = {
563 { 0, "Composite" },
564 { 7, "S-Video" }
565 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300566 .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 .tvn = {
568 &f50ccir601_lm33r10,
569 &f60ccir601_lm33r10,
570 NULL
571 },
572 .jpeg_int = ZR36057_ISR_GIRQ1,
573 .vsync_int = ZR36057_ISR_GIRQ0,
574 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
575 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
576 .gpcs = { 3, 1 },
577 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
578 .gws_not_connected = 1,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300579 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 .init = &lml33_init,
581 }, {
582 .type = BUZ,
583 .name = "Buz",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300584 .i2c_decoder = "saa7111",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300585 .addrs_decoder = saa7111_addrs,
586 .i2c_encoder = "saa7185",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300587 .addrs_encoder = saa7185_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 .video_codec = CODEC_TYPE_ZR36060,
589
590 .inputs = 2,
591 .input = {
592 { 3, "Composite" },
593 { 7, "S-Video" }
594 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300595 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 .tvn = {
597 &f50ccir601,
598 &f60ccir601,
599 &f50ccir601
600 },
601 .jpeg_int = ZR36057_ISR_GIRQ1,
602 .vsync_int = ZR36057_ISR_GIRQ0,
603 .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
604 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
605 .gpcs = { 3, 1 },
606 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
607 .gws_not_connected = 1,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300608 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 .init = &buz_init,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300610 }, {
611 .type = AVS6EYES,
612 .name = "6-Eyes",
613 /* AverMedia chose not to brand the 6-Eyes. Thus it
614 can't be autodetected, and requires card=x. */
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300615 .i2c_decoder = "ks0127",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300616 .addrs_decoder = ks0127_addrs,
617 .i2c_encoder = "bt866",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300618 .addrs_encoder = bt866_addrs,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300619 .video_codec = CODEC_TYPE_ZR36060,
620
621 .inputs = 10,
622 .input = {
623 { 0, "Composite 1" },
624 { 1, "Composite 2" },
625 { 2, "Composite 3" },
626 { 4, "Composite 4" },
627 { 5, "Composite 5" },
628 { 6, "Composite 6" },
629 { 8, "S-Video 1" },
630 { 9, "S-Video 2" },
631 {10, "S-Video 3" },
632 {15, "YCbCr" }
633 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300634 .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300635 .tvn = {
636 &f50ccir601_avs6eyes,
637 &f60ccir601_avs6eyes,
638 NULL
639 },
640 .jpeg_int = ZR36057_ISR_GIRQ1,
641 .vsync_int = ZR36057_ISR_GIRQ0,
642 .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
643 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
644 .gpcs = { 3, 1 }, // Validity unknown /Sam
645 .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam
646 .gws_not_connected = 1,
647 .input_mux = 1,
648 .init = &avs6eyes_init,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 }
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651};
652
653/*
654 * I2C functions
655 */
656/* software I2C functions */
657static int
658zoran_i2c_getsda (void *data)
659{
660 struct zoran *zr = (struct zoran *) data;
661
662 return (btread(ZR36057_I2CBR) >> 1) & 1;
663}
664
665static int
666zoran_i2c_getscl (void *data)
667{
668 struct zoran *zr = (struct zoran *) data;
669
670 return btread(ZR36057_I2CBR) & 1;
671}
672
673static void
674zoran_i2c_setsda (void *data,
675 int state)
676{
677 struct zoran *zr = (struct zoran *) data;
678
679 if (state)
680 zr->i2cbr |= 2;
681 else
682 zr->i2cbr &= ~2;
683 btwrite(zr->i2cbr, ZR36057_I2CBR);
684}
685
686static void
687zoran_i2c_setscl (void *data,
688 int state)
689{
690 struct zoran *zr = (struct zoran *) data;
691
692 if (state)
693 zr->i2cbr |= 1;
694 else
695 zr->i2cbr &= ~1;
696 btwrite(zr->i2cbr, ZR36057_I2CBR);
697}
698
Jean Delvare62751632008-06-12 13:20:46 -0300699static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 .setsda = zoran_i2c_setsda,
701 .setscl = zoran_i2c_setscl,
702 .getsda = zoran_i2c_getsda,
703 .getscl = zoran_i2c_getscl,
704 .udelay = 10,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 .timeout = 100,
706};
707
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708static int
709zoran_register_i2c (struct zoran *zr)
710{
Ezequiel Garcia37320d72012-10-23 15:57:12 -0300711 zr->i2c_algo = zoran_i2c_bit_data_template;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 zr->i2c_algo.data = zr;
Jean Delvare62751632008-06-12 13:20:46 -0300713 strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
714 sizeof(zr->i2c_adapter.name));
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300715 i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 zr->i2c_adapter.algo_data = &zr->i2c_algo;
Jean Delvare12a917f2007-02-13 22:09:03 +0100717 zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 return i2c_bit_add_bus(&zr->i2c_adapter);
719}
720
721static void
722zoran_unregister_i2c (struct zoran *zr)
723{
Jean Delvare32697112006-12-10 21:21:33 +0100724 i2c_del_adapter(&zr->i2c_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725}
726
727/* Check a zoran_params struct for correctness, insert default params */
728
729int
730zoran_check_jpg_settings (struct zoran *zr,
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300731 struct zoran_jpg_settings *settings,
732 int try)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733{
734 int err = 0, err0 = 0;
735
736 dprintk(4,
737 KERN_DEBUG
Trent Piephoc61402b2009-03-10 23:28:33 -0300738 "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
739 ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 settings->VerDcm, settings->TmpDcm);
741 dprintk(4,
742 KERN_DEBUG
Trent Piephoc61402b2009-03-10 23:28:33 -0300743 "%s: %s - x: %d, y: %d, w: %d, y: %d\n",
744 ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 settings->img_width, settings->img_height);
746 /* Check decimation, set default values for decimation = 1, 2, 4 */
747 switch (settings->decimation) {
748 case 1:
749
750 settings->HorDcm = 1;
751 settings->VerDcm = 1;
752 settings->TmpDcm = 1;
753 settings->field_per_buff = 2;
754 settings->img_x = 0;
755 settings->img_y = 0;
756 settings->img_width = BUZ_MAX_WIDTH;
757 settings->img_height = BUZ_MAX_HEIGHT / 2;
758 break;
759 case 2:
760
761 settings->HorDcm = 2;
762 settings->VerDcm = 1;
763 settings->TmpDcm = 2;
764 settings->field_per_buff = 1;
765 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
766 settings->img_y = 0;
767 settings->img_width =
768 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
769 settings->img_height = BUZ_MAX_HEIGHT / 2;
770 break;
771 case 4:
772
773 if (zr->card.type == DC10_new) {
774 dprintk(1,
775 KERN_DEBUG
Trent Piephoc61402b2009-03-10 23:28:33 -0300776 "%s: %s - HDec by 4 is not supported on the DC10\n",
777 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 err0++;
779 break;
780 }
781
782 settings->HorDcm = 4;
783 settings->VerDcm = 2;
784 settings->TmpDcm = 2;
785 settings->field_per_buff = 1;
786 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
787 settings->img_y = 0;
788 settings->img_width =
789 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
790 settings->img_height = BUZ_MAX_HEIGHT / 2;
791 break;
792 case 0:
793
794 /* We have to check the data the user has set */
795
796 if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300797 (zr->card.type == DC10_new || settings->HorDcm != 4)) {
798 settings->HorDcm = clamp(settings->HorDcm, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300800 }
801 if (settings->VerDcm != 1 && settings->VerDcm != 2) {
802 settings->VerDcm = clamp(settings->VerDcm, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300804 }
805 if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
806 settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300808 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 if (settings->field_per_buff != 1 &&
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300810 settings->field_per_buff != 2) {
811 settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300813 }
814 if (settings->img_x < 0) {
815 settings->img_x = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300817 }
818 if (settings->img_y < 0) {
819 settings->img_y = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300821 }
822 if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
823 settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300825 }
826 if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
827 settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300829 }
830 if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
831 settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300833 }
834 if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
835 settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300837 }
838 if (settings->img_width % (16 * settings->HorDcm) != 0) {
839 settings->img_width -= settings->img_width % (16 * settings->HorDcm);
840 if (settings->img_width == 0)
841 settings->img_width = 16 * settings->HorDcm;
842 err0++;
843 }
844 if (settings->img_height % (8 * settings->VerDcm) != 0) {
845 settings->img_height -= settings->img_height % (8 * settings->VerDcm);
846 if (settings->img_height == 0)
847 settings->img_height = 8 * settings->VerDcm;
848 err0++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 }
850
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300851 if (!try && err0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 dprintk(1,
853 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -0300854 "%s: %s - error in params for decimation = 0\n",
855 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 err++;
857 }
858 break;
859 default:
860 dprintk(1,
861 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -0300862 "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n",
863 ZR_DEVNAME(zr), __func__, settings->decimation);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 err++;
865 break;
866 }
867
868 if (settings->jpg_comp.quality > 100)
869 settings->jpg_comp.quality = 100;
870 if (settings->jpg_comp.quality < 5)
871 settings->jpg_comp.quality = 5;
872 if (settings->jpg_comp.APPn < 0)
873 settings->jpg_comp.APPn = 0;
874 if (settings->jpg_comp.APPn > 15)
875 settings->jpg_comp.APPn = 15;
876 if (settings->jpg_comp.APP_len < 0)
877 settings->jpg_comp.APP_len = 0;
878 if (settings->jpg_comp.APP_len > 60)
879 settings->jpg_comp.APP_len = 60;
880 if (settings->jpg_comp.COM_len < 0)
881 settings->jpg_comp.COM_len = 0;
882 if (settings->jpg_comp.COM_len > 60)
883 settings->jpg_comp.COM_len = 60;
884 if (err)
885 return -EINVAL;
886 return 0;
887}
888
889void
890zoran_open_init_params (struct zoran *zr)
891{
892 int i;
893
894 /* User must explicitly set a window */
895 zr->overlay_settings.is_set = 0;
896 zr->overlay_mask = NULL;
897 zr->overlay_active = ZORAN_FREE;
898
899 zr->v4l_memgrab_active = 0;
900 zr->v4l_overlay_active = 0;
901 zr->v4l_grab_frame = NO_GRAB_ACTIVE;
902 zr->v4l_grab_seq = 0;
903 zr->v4l_settings.width = 192;
904 zr->v4l_settings.height = 144;
Jean Delvarec014ec92008-09-07 05:21:34 -0300905 zr->v4l_settings.format = &zoran_formats[7]; /* YUY2 - YUV-4:2:2 packed */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 zr->v4l_settings.bytesperline =
907 zr->v4l_settings.width *
908 ((zr->v4l_settings.format->depth + 7) / 8);
909
910 /* DMA ring stuff for V4L */
911 zr->v4l_pend_tail = 0;
912 zr->v4l_pend_head = 0;
913 zr->v4l_sync_tail = 0;
914 zr->v4l_buffers.active = ZORAN_FREE;
915 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
916 zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
917 }
918 zr->v4l_buffers.allocated = 0;
919
920 for (i = 0; i < BUZ_MAX_FRAME; i++) {
921 zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
922 }
923 zr->jpg_buffers.active = ZORAN_FREE;
924 zr->jpg_buffers.allocated = 0;
925 /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
926 zr->jpg_settings.decimation = 1;
927 zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
928 if (zr->card.type != BUZ)
929 zr->jpg_settings.odd_even = 1;
930 else
931 zr->jpg_settings.odd_even = 0;
932 zr->jpg_settings.jpg_comp.APPn = 0;
933 zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */
934 memset(zr->jpg_settings.jpg_comp.APP_data, 0,
935 sizeof(zr->jpg_settings.jpg_comp.APP_data));
936 zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */
937 memset(zr->jpg_settings.jpg_comp.COM_data, 0,
938 sizeof(zr->jpg_settings.jpg_comp.COM_data));
939 zr->jpg_settings.jpg_comp.jpeg_markers =
Hans Verkuilad1ecf82010-12-25 06:58:01 -0300940 V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300941 i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 if (i)
Trent Piephoc61402b2009-03-10 23:28:33 -0300943 dprintk(1, KERN_ERR "%s: %s internal error\n",
944 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
946 clear_interrupt_counters(zr);
947 zr->testing = 0;
948}
949
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -0800950static void test_interrupts (struct zoran *zr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951{
952 DEFINE_WAIT(wait);
953 int timeout, icr;
954
955 clear_interrupt_counters(zr);
956
957 zr->testing = 1;
958 icr = btread(ZR36057_ICR);
959 btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR);
960 prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE);
961 timeout = schedule_timeout(HZ);
962 finish_wait(&zr->test_q, &wait);
963 btwrite(0, ZR36057_ICR);
964 btwrite(0x78000000, ZR36057_ISR);
965 zr->testing = 0;
966 dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr));
967 if (timeout) {
968 dprintk(1, ": time spent: %d\n", 1 * HZ - timeout);
969 }
Jean Delvare18b548c2007-07-17 18:29:41 -0300970 if (zr36067_debug > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 print_interrupts(zr);
972 btwrite(icr, ZR36057_ICR);
973}
974
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -0800975static int zr36057_init (struct zoran *zr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976{
Jean Delvaredaf72f42006-03-22 03:48:37 -0300977 int j, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
979 dprintk(1,
980 KERN_INFO
Trent Piephoc61402b2009-03-10 23:28:33 -0300981 "%s: %s - initializing card[%d], zr=%p\n",
982 ZR_DEVNAME(zr), __func__, zr->id, zr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
984 /* default setup of all parameters which will persist between opens */
985 zr->user = 0;
986
987 init_waitqueue_head(&zr->v4l_capq);
988 init_waitqueue_head(&zr->jpg_capq);
989 init_waitqueue_head(&zr->test_q);
990 zr->jpg_buffers.allocated = 0;
991 zr->v4l_buffers.allocated = 0;
992
Hans Verkuil7f6adea2009-02-19 17:31:17 -0300993 zr->vbuf_base = (void *) vidmem;
994 zr->vbuf_width = 0;
995 zr->vbuf_height = 0;
996 zr->vbuf_depth = 0;
997 zr->vbuf_bytesperline = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
999 /* Avoid nonsense settings from user for default input/norm */
Roel Kluinb475f4e2009-05-02 17:52:52 -03001000 if (default_norm < 0 || default_norm > 2)
Hans Verkuil7f6adea2009-02-19 17:31:17 -03001001 default_norm = 0;
1002 if (default_norm == 0) {
Hans Verkuil107063c2009-02-18 17:26:06 -03001003 zr->norm = V4L2_STD_PAL;
1004 zr->timing = zr->card.tvn[0];
Hans Verkuil7f6adea2009-02-19 17:31:17 -03001005 } else if (default_norm == 1) {
Hans Verkuil107063c2009-02-18 17:26:06 -03001006 zr->norm = V4L2_STD_NTSC;
1007 zr->timing = zr->card.tvn[1];
1008 } else {
1009 zr->norm = V4L2_STD_SECAM;
1010 zr->timing = zr->card.tvn[2];
1011 }
1012 if (zr->timing == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 dprintk(1,
1014 KERN_WARNING
Trent Piephoc61402b2009-03-10 23:28:33 -03001015 "%s: %s - default TV standard not supported by hardware. PAL will be used.\n",
1016 ZR_DEVNAME(zr), __func__);
Hans Verkuil107063c2009-02-18 17:26:06 -03001017 zr->norm = V4L2_STD_PAL;
1018 zr->timing = zr->card.tvn[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 }
1020
Trent Piepho60e3cac2007-07-17 18:29:42 -03001021 if (default_input > zr->card.inputs-1) {
1022 dprintk(1,
1023 KERN_WARNING
1024 "%s: default_input value %d out of range (0-%d)\n",
1025 ZR_DEVNAME(zr), default_input, zr->card.inputs-1);
1026 default_input = 0;
1027 }
1028 zr->input = default_input;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 /* default setup (will be repeated at every open) */
1031 zoran_open_init_params(zr);
1032
1033 /* allocate memory *before* doing anything to the hardware
1034 * in case allocation fails */
Jean Delvaredaf72f42006-03-22 03:48:37 -03001035 zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL);
Hans Verkuil6ce3ced2010-12-31 11:28:51 -03001036 zr->video_dev = video_device_alloc();
Jean Delvaredaf72f42006-03-22 03:48:37 -03001037 if (!zr->stat_com || !zr->video_dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 dprintk(1,
1039 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001040 "%s: %s - kmalloc (STAT_COM) failed\n",
1041 ZR_DEVNAME(zr), __func__);
Jean Delvaredaf72f42006-03-22 03:48:37 -03001042 err = -ENOMEM;
1043 goto exit_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
Al Viro9c169df2008-06-22 14:19:49 -03001046 zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 }
1048
1049 /*
1050 * Now add the template and register the device unit.
1051 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
Hans Verkuil9592bd02013-06-10 07:30:08 -03001053 zr->video_dev->v4l2_dev = &zr->v4l2_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
Hans Verkuil954f3402012-09-05 06:05:50 -03001055 /* It's not a mem2mem device, but you can both capture and output from
1056 one and the same device. This should really be split up into two
1057 device nodes, but that's a job for another day. */
1058 zr->video_dev->vfl_dir = VFL_DIR_M2M;
Trent Piepho60e3cac2007-07-17 18:29:42 -03001059 err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
Jean Delvaredaf72f42006-03-22 03:48:37 -03001060 if (err < 0)
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001061 goto exit_free;
Trent Piepho601139e2009-01-12 13:09:46 -03001062 video_set_drvdata(zr->video_dev, zr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063
1064 zoran_init_hardware(zr);
Jean Delvare18b548c2007-07-17 18:29:41 -03001065 if (zr36067_debug > 2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 detect_guest_activity(zr);
1067 test_interrupts(zr);
1068 if (!pass_through) {
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001069 decoder_call(zr, video, s_stream, 0);
Hans Verkuil5325b422009-04-02 11:26:22 -03001070 encoder_call(zr, video, s_routing, 2, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 }
1072
1073 zr->zoran_proc = NULL;
1074 zr->initialized = 1;
1075 return 0;
Jean Delvaredaf72f42006-03-22 03:48:37 -03001076
Jean Delvaredaf72f42006-03-22 03:48:37 -03001077exit_free:
1078 kfree(zr->stat_com);
1079 kfree(zr->video_dev);
1080 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081}
1082
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -08001083static void zoran_remove(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084{
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001085 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
1086 struct zoran *zr = to_zoran(v4l2_dev);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001087
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 if (!zr->initialized)
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001089 goto exit_free;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001090
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 /* unregister videocodec bus */
1092 if (zr->codec) {
1093 struct videocodec_master *master = zr->codec->master_data;
Jesper Juhl2ea75332005-11-07 01:01:31 -08001094
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 videocodec_detach(zr->codec);
Jesper Juhl2ea75332005-11-07 01:01:31 -08001096 kfree(master);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 }
1098 if (zr->vfe) {
1099 struct videocodec_master *master = zr->vfe->master_data;
Jesper Juhl2ea75332005-11-07 01:01:31 -08001100
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101 videocodec_detach(zr->vfe);
Jesper Juhl2ea75332005-11-07 01:01:31 -08001102 kfree(master);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 }
1104
1105 /* unregister i2c bus */
1106 zoran_unregister_i2c(zr);
1107 /* disable PCI bus-mastering */
1108 zoran_set_pci_master(zr, 0);
1109 /* put chip into reset */
1110 btwrite(0, ZR36057_SPGPPCR);
1111 free_irq(zr->pci_dev->irq, zr);
1112 /* unmap and free memory */
Jean Delvaredaf72f42006-03-22 03:48:37 -03001113 kfree(zr->stat_com);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 zoran_proc_cleanup(zr);
1115 iounmap(zr->zr36057_mem);
1116 pci_disable_device(zr->pci_dev);
1117 video_unregister_device(zr->video_dev);
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001118exit_free:
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001119 v4l2_device_unregister(&zr->v4l2_dev);
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001120 kfree(zr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121}
1122
1123void
1124zoran_vdev_release (struct video_device *vdev)
1125{
1126 kfree(vdev);
1127}
1128
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -08001129static struct videocodec_master *zoran_setup_videocodec(struct zoran *zr,
1130 int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131{
1132 struct videocodec_master *m = NULL;
1133
1134 m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
1135 if (!m) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001136 dprintk(1, KERN_ERR "%s: %s - no memory\n",
1137 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 return m;
1139 }
1140
Mauro Carvalho Chehab22c4a4e2007-10-15 12:09:17 -03001141 /* magic and type are unused for master struct. Makes sense only at
1142 codec structs.
1143 In the past, .type were initialized to the old V4L1 .hardware
1144 value, as VID_HARDWARE_ZR36067
1145 */
1146 m->magic = 0L;
1147 m->type = 0;
1148
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
Roel Kluinbd0eb122009-08-08 12:58:52 -03001150 strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 m->data = zr;
1152
1153 switch (type)
1154 {
1155 case CODEC_TYPE_ZR36060:
1156 m->readreg = zr36060_read;
1157 m->writereg = zr36060_write;
1158 m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
1159 break;
1160 case CODEC_TYPE_ZR36050:
1161 m->readreg = zr36050_read;
1162 m->writereg = zr36050_write;
1163 m->flags |= CODEC_FLAG_JPEG;
1164 break;
1165 case CODEC_TYPE_ZR36016:
1166 m->readreg = zr36016_read;
1167 m->writereg = zr36016_write;
1168 m->flags |= CODEC_FLAG_VFE;
1169 break;
1170 }
1171
1172 return m;
1173}
1174
Hans Verkuil33470422009-03-14 12:53:37 -03001175static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -03001176{
1177 struct zoran *zr = to_zoran(sd->v4l2_dev);
1178
1179 /* Bt819 needs to reset its FIFO buffer using #FRST pin and
1180 LML33 card uses GPIO(7) for that. */
1181 if (cmd == BT819_FIFO_RESET_LOW)
1182 GPIO(zr, 7, 0);
1183 else if (cmd == BT819_FIFO_RESET_HIGH)
1184 GPIO(zr, 7, 1);
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -03001185}
1186
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187/*
Joe Perchesc84e6032008-02-03 17:18:59 +02001188 * Scan for a Buz card (actually for the PCI controller ZR36057),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 * request the irq and map the io memory
1190 */
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -08001191static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192{
1193 unsigned char latency, need_latency;
1194 struct zoran *zr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 int result;
1196 struct videocodec_master *master_vfe = NULL;
1197 struct videocodec_master *master_codec = NULL;
1198 int card_num;
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001199 char *codec_name, *vfe_name;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001200 unsigned int nr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001202
Trent Piepho601139e2009-01-12 13:09:46 -03001203 nr = zoran_num++;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001204 if (nr >= BUZ_MAX) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001205 dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001206 ZORAN_NAME, BUZ_MAX);
1207 return -ENOENT;
1208 }
1209
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001210 zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
1211 if (!zr) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001212 dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n",
1213 ZORAN_NAME, __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001214 return -ENOMEM;
1215 }
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -03001216 zr->v4l2_dev.notify = zoran_subdev_notify;
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001217 if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
1218 goto zr_free_mem;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001219 zr->pci_dev = pdev;
1220 zr->id = nr;
1221 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
1222 spin_lock_init(&zr->spinlock);
1223 mutex_init(&zr->resource_lock);
Arnd Bergmann0edf2e52010-10-27 09:30:32 -03001224 mutex_init(&zr->other_lock);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001225 if (pci_enable_device(pdev))
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001226 goto zr_unreg;
Bjørn Morkabd34d82011-03-21 11:35:56 -03001227 zr->revision = zr->pci_dev->revision;
Trent Piepho17faeb22009-01-12 13:09:46 -03001228
1229 dprintk(1,
1230 KERN_INFO
Trent Piepho5e098b62009-01-12 13:09:46 -03001231 "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
Trent Piepho17faeb22009-01-12 13:09:46 -03001232 ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
Trent Piepho5e098b62009-01-12 13:09:46 -03001233 zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
Trent Piepho17faeb22009-01-12 13:09:46 -03001234 if (zr->revision >= 2) {
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001235 dprintk(1,
1236 KERN_INFO
Trent Piepho17faeb22009-01-12 13:09:46 -03001237 "%s: Subsystem vendor=0x%04x id=0x%04x\n",
1238 ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
1239 zr->pci_dev->subsystem_device);
1240 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001241
Trent Piepho17faeb22009-01-12 13:09:46 -03001242 /* Use auto-detected card type? */
1243 if (card[nr] == -1) {
1244 if (zr->revision < 2) {
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001245 dprintk(1,
1246 KERN_ERR
Trent Piepho17faeb22009-01-12 13:09:46 -03001247 "%s: No card type specified, please use the card=X module parameter\n",
1248 ZR_DEVNAME(zr));
1249 dprintk(1,
1250 KERN_ERR
1251 "%s: It is not possible to auto-detect ZR36057 based cards\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001252 ZR_DEVNAME(zr));
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001253 goto zr_unreg;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
Trent Piepho17faeb22009-01-12 13:09:46 -03001256 card_num = ent->driver_data;
1257 if (card_num >= NUM_CARDS) {
1258 dprintk(1,
1259 KERN_ERR
1260 "%s: Unknown card, try specifying card=X module parameter\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001261 ZR_DEVNAME(zr));
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001262 goto zr_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 }
Trent Piepho17faeb22009-01-12 13:09:46 -03001264 dprintk(3,
1265 KERN_DEBUG
1266 "%s: %s() - card %s detected\n",
1267 ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
1268 } else {
1269 card_num = card[nr];
1270 if (card_num >= NUM_CARDS || card_num < 0) {
1271 dprintk(1,
1272 KERN_ERR
1273 "%s: User specified card type %d out of range (0 .. %d)\n",
1274 ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001275 goto zr_unreg;
Trent Piepho17faeb22009-01-12 13:09:46 -03001276 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001277 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001279 /* even though we make this a non pointer and thus
1280 * theoretically allow for making changes to this struct
1281 * on a per-individual card basis at runtime, this is
1282 * strongly discouraged. This structure is intended to
1283 * keep general card information, no settings or anything */
1284 zr->card = zoran_cards[card_num];
1285 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
1286 "%s[%u]", zr->card.name, zr->id);
1287
Trent Piepho5e098b62009-01-12 13:09:46 -03001288 zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001289 if (!zr->zr36057_mem) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001290 dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n",
Trent Piepho5e098b62009-01-12 13:09:46 -03001291 ZR_DEVNAME(zr), __func__);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001292 goto zr_unreg;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001293 }
1294
1295 result = request_irq(zr->pci_dev->irq, zoran_irq,
1296 IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
1297 if (result < 0) {
1298 if (result == -EINVAL) {
1299 dprintk(1,
1300 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001301 "%s: %s - bad irq number or handler\n",
1302 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001303 } else if (result == -EBUSY) {
1304 dprintk(1,
1305 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001306 "%s: %s - IRQ %d busy, change your PnP config in BIOS\n",
1307 ZR_DEVNAME(zr), __func__, zr->pci_dev->irq);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001308 } else {
1309 dprintk(1,
1310 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001311 "%s: %s - can't assign irq, error code %d\n",
1312 ZR_DEVNAME(zr), __func__, result);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001313 }
1314 goto zr_unmap;
1315 }
1316
1317 /* set PCI latency timer */
1318 pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
1319 &latency);
1320 need_latency = zr->revision > 1 ? 32 : 48;
1321 if (latency != need_latency) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001322 dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001323 ZR_DEVNAME(zr), latency, need_latency);
1324 pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
1325 need_latency);
1326 }
1327
1328 zr36057_restart(zr);
1329 /* i2c */
1330 dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
1331 ZR_DEVNAME(zr));
1332
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001333 if (zoran_register_i2c(zr) < 0) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001334 dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n",
1335 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001336 goto zr_free_irq;
1337 }
1338
Hans Verkuil53dacb12009-08-10 02:49:08 -03001339 zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
Laurent Pinchart9a1f8b32010-09-24 10:16:44 -03001340 &zr->i2c_adapter, zr->card.i2c_decoder,
Hans Verkuil53dacb12009-08-10 02:49:08 -03001341 0, zr->card.addrs_decoder);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001342
Laurent Pinchart99f7d812010-09-24 08:19:18 -03001343 if (zr->card.i2c_encoder)
Hans Verkuil53dacb12009-08-10 02:49:08 -03001344 zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
Laurent Pinchart9a1f8b32010-09-24 10:16:44 -03001345 &zr->i2c_adapter, zr->card.i2c_encoder,
Hans Verkuil53dacb12009-08-10 02:49:08 -03001346 0, zr->card.addrs_encoder);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001347
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001348 dprintk(2,
1349 KERN_INFO "%s: Initializing videocodec bus...\n",
1350 ZR_DEVNAME(zr));
1351
1352 if (zr->card.video_codec) {
1353 codec_name = codecid_to_modulename(zr->card.video_codec);
1354 if (codec_name) {
1355 result = request_module(codec_name);
1356 if (result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 dprintk(1,
1358 KERN_ERR
1359 "%s: failed to load modules %s: %d\n",
1360 ZR_DEVNAME(zr), codec_name, result);
1361 }
1362 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001363 }
1364 if (zr->card.video_vfe) {
1365 vfe_name = codecid_to_modulename(zr->card.video_vfe);
1366 if (vfe_name) {
1367 result = request_module(vfe_name);
1368 if (result < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 dprintk(1,
1370 KERN_ERR
1371 "%s: failed to load modules %s: %d\n",
1372 ZR_DEVNAME(zr), vfe_name, result);
1373 }
1374 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 }
Alan Coxe491cbc2006-10-03 20:44:12 -03001376
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001377 /* reset JPEG codec */
1378 jpeg_codec_sleep(zr, 1);
1379 jpeg_codec_reset(zr);
1380 /* video bus enabled */
1381 /* display codec revision */
1382 if (zr->card.video_codec != 0) {
1383 master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
1384 if (!master_codec)
1385 goto zr_unreg_i2c;
1386 zr->codec = videocodec_attach(master_codec);
1387 if (!zr->codec) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001388 dprintk(1, KERN_ERR "%s: %s - no codec found\n",
1389 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001390 goto zr_free_codec;
1391 }
1392 if (zr->codec->type != zr->card.video_codec) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001393 dprintk(1, KERN_ERR "%s: %s - wrong codec\n",
1394 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001395 goto zr_detach_codec;
1396 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001398 if (zr->card.video_vfe != 0) {
1399 master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
1400 if (!master_vfe)
1401 goto zr_detach_codec;
1402 zr->vfe = videocodec_attach(master_vfe);
1403 if (!zr->vfe) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001404 dprintk(1, KERN_ERR "%s: %s - no VFE found\n",
1405 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001406 goto zr_free_vfe;
1407 }
1408 if (zr->vfe->type != zr->card.video_vfe) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001409 dprintk(1, KERN_ERR "%s: %s = wrong VFE\n",
1410 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001411 goto zr_detach_vfe;
1412 }
1413 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001414
1415 /* take care of Natoma chipset and a revision 1 zr36057 */
1416 if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
1417 zr->jpg_buffers.need_contiguous = 1;
Trent Piephoc61402b2009-03-10 23:28:33 -03001418 dprintk(1, KERN_INFO
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001419 "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
1420 ZR_DEVNAME(zr));
1421 }
1422
1423 if (zr36057_init(zr) < 0)
1424 goto zr_detach_vfe;
1425
1426 zoran_proc_init(zr);
1427
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001428 return 0;
1429
1430zr_detach_vfe:
1431 videocodec_detach(zr->vfe);
1432zr_free_vfe:
1433 kfree(master_vfe);
1434zr_detach_codec:
1435 videocodec_detach(zr->codec);
1436zr_free_codec:
1437 kfree(master_codec);
1438zr_unreg_i2c:
1439 zoran_unregister_i2c(zr);
1440zr_free_irq:
1441 btwrite(0, ZR36057_SPGPPCR);
1442 free_irq(zr->pci_dev->irq, zr);
1443zr_unmap:
1444 iounmap(zr->zr36057_mem);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001445zr_unreg:
1446 v4l2_device_unregister(&zr->v4l2_dev);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001447zr_free_mem:
1448 kfree(zr);
1449
1450 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451}
1452
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001453static struct pci_driver zoran_driver = {
1454 .name = "zr36067",
1455 .id_table = zr36067_pci_tbl,
1456 .probe = zoran_probe,
Greg Kroah-Hartman4c62e972012-12-21 13:17:53 -08001457 .remove = zoran_remove,
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001458};
1459
1460static int __init zoran_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461{
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001462 int res;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -03001464 printk(KERN_INFO "Zoran MJPEG board driver version %s\n",
1465 ZORAN_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 /* check the parameters we have been given, adjust if necessary */
1468 if (v4l_nbufs < 2)
1469 v4l_nbufs = 2;
1470 if (v4l_nbufs > VIDEO_MAX_FRAME)
1471 v4l_nbufs = VIDEO_MAX_FRAME;
1472 /* The user specfies the in KB, we want them in byte
1473 * (and page aligned) */
1474 v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
1475 if (v4l_bufsize < 32768)
1476 v4l_bufsize = 32768;
1477 /* 2 MB is arbitrary but sufficient for the maximum possible images */
1478 if (v4l_bufsize > 2048 * 1024)
1479 v4l_bufsize = 2048 * 1024;
1480 if (jpg_nbufs < 4)
1481 jpg_nbufs = 4;
1482 if (jpg_nbufs > BUZ_MAX_FRAME)
1483 jpg_nbufs = BUZ_MAX_FRAME;
1484 jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024);
1485 if (jpg_bufsize < 8192)
1486 jpg_bufsize = 8192;
1487 if (jpg_bufsize > (512 * 1024))
1488 jpg_bufsize = 512 * 1024;
1489 /* Use parameter for vidmem or try to find a video card */
1490 if (vidmem) {
1491 dprintk(1,
1492 KERN_INFO
1493 "%s: Using supplied video memory base address @ 0x%lx\n",
1494 ZORAN_NAME, vidmem);
1495 }
1496
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 /* some mainboards might not do PCI-PCI data transfer well */
Alan Coxe3558802006-09-14 11:47:55 -03001498 if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 dprintk(1,
1500 KERN_WARNING
Alan Coxe3558802006-09-14 11:47:55 -03001501 "%s: chipset does not support reliable PCI-PCI DMA\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 ZORAN_NAME);
1503 }
1504
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001505 res = pci_register_driver(&zoran_driver);
1506 if (res) {
1507 dprintk(1,
1508 KERN_ERR
1509 "%s: Unable to register ZR36057 driver\n",
1510 ZORAN_NAME);
1511 return res;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 }
1513
1514 return 0;
1515}
1516
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001517static void __exit zoran_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518{
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001519 pci_unregister_driver(&zoran_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520}
1521
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001522module_init(zoran_init);
1523module_exit(zoran_exit);