blob: bfcd3aef50f95913aa37244987ddba60f091f053 [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
Trent Piepho45bdcef2009-01-12 13:09:46 -030067static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
Trent Piepho60e3cac2007-07-17 18:29:42 -030068module_param_array(encoder, int, NULL, 0444);
Trent Piepho45bdcef2009-01-12 13:09:46 -030069MODULE_PARM_DESC(encoder, "Video encoder chip");
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Trent Piepho45bdcef2009-01-12 13:09:46 -030071static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
Trent Piepho60e3cac2007-07-17 18:29:42 -030072module_param_array(decoder, int, NULL, 0444);
Trent Piepho45bdcef2009-01-12 13:09:46 -030073MODULE_PARM_DESC(decoder, "Video decoder chip");
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
75/*
76 The video mem address of the video card.
77 The driver has a little database for some videocards
78 to determine it from there. If your video card is not in there
79 you have either to give it to the driver as a parameter
80 or set in in a VIDIOCSFBUF ioctl
81 */
82
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030083static unsigned long vidmem; /* default = 0 - Video memory base address */
Trent Piepho60e3cac2007-07-17 18:29:42 -030084module_param(vidmem, ulong, 0444);
85MODULE_PARM_DESC(vidmem, "Default video memory base address");
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87/*
88 Default input and video norm at startup of the driver.
89*/
90
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030091static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */
Trent Piepho60e3cac2007-07-17 18:29:42 -030092module_param(default_input, uint, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093MODULE_PARM_DESC(default_input,
94 "Default input (0=Composite, 1=S-Video, 2=Internal)");
95
Martin Samuelssonfbe60da2006-04-27 10:17:00 -030096static int default_mux = 1; /* 6 Eyes input selection */
Trent Piepho60e3cac2007-07-17 18:29:42 -030097module_param(default_mux, int, 0644);
Martin Samuelssonfbe60da2006-04-27 10:17:00 -030098MODULE_PARM_DESC(default_mux,
99 "Default 6 Eyes mux setting (Input selection)");
100
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300101static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300102module_param(default_norm, int, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
104
Trent Piepho60e3cac2007-07-17 18:29:42 -0300105/* /dev/videoN, -1 for autodetect */
Trent Piepho45bdcef2009-01-12 13:09:46 -0300106static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
Trent Piepho60e3cac2007-07-17 18:29:42 -0300107module_param_array(video_nr, int, NULL, 0444);
Trent Piepho45bdcef2009-01-12 13:09:46 -0300108MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Hans Verkuil497d7d02009-02-18 18:33:35 -0300110int v4l_nbufs = 4;
Hans Verkuile686e732009-02-20 15:06:59 -0300111int v4l_bufsize = 864; /* Everybody should be able to work with this setting */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300112module_param(v4l_nbufs, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
Trent Piepho60e3cac2007-07-17 18:29:42 -0300114module_param(v4l_bufsize, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
116
117int jpg_nbufs = 32;
118int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300119module_param(jpg_nbufs, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
Trent Piepho60e3cac2007-07-17 18:29:42 -0300121module_param(jpg_bufsize, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
123
124int pass_through = 0; /* 1=Pass through TV signal when device is not used */
125 /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300126module_param(pass_through, int, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127MODULE_PARM_DESC(pass_through,
128 "Pass TV signal through to TV-out when idling");
129
Jean Delvare18b548c2007-07-17 18:29:41 -0300130int zr36067_debug = 1;
131module_param_named(debug, zr36067_debug, int, 0644);
132MODULE_PARM_DESC(debug, "Debug level (0-5)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
135MODULE_AUTHOR("Serguei Miridonov");
136MODULE_LICENSE("GPL");
137
Trent Piepho17faeb22009-01-12 13:09:46 -0300138#define ZR_DEVICE(subven, subdev, data) { \
139 .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
140 .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
141
Mauro Carvalho Chehabdbdf03b2009-01-08 23:27:32 -0300142static struct pci_device_id zr36067_pci_tbl[] = {
Trent Piepho17faeb22009-01-12 13:09:46 -0300143 ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
144 ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
145 ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
146 ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
147 ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
Mauro Carvalho Chehabdbdf03b2009-01-08 23:27:32 -0300148 {0}
149};
150MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
Trent Piepho601139e2009-01-12 13:09:46 -0300152static unsigned int zoran_num; /* number of cards found */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
154/* videocodec bus functions ZR36060 */
155static u32
156zr36060_read (struct videocodec *codec,
157 u16 reg)
158{
159 struct zoran *zr = (struct zoran *) codec->master_data->data;
160 __u32 data;
161
162 if (post_office_wait(zr)
163 || post_office_write(zr, 0, 1, reg >> 8)
164 || post_office_write(zr, 0, 2, reg & 0xff)) {
165 return -1;
166 }
167
168 data = post_office_read(zr, 0, 3) & 0xff;
169 return data;
170}
171
172static void
173zr36060_write (struct videocodec *codec,
174 u16 reg,
175 u32 val)
176{
177 struct zoran *zr = (struct zoran *) codec->master_data->data;
178
179 if (post_office_wait(zr)
180 || post_office_write(zr, 0, 1, reg >> 8)
181 || post_office_write(zr, 0, 2, reg & 0xff)) {
182 return;
183 }
184
185 post_office_write(zr, 0, 3, val & 0xff);
186}
187
188/* videocodec bus functions ZR36050 */
189static u32
190zr36050_read (struct videocodec *codec,
191 u16 reg)
192{
193 struct zoran *zr = (struct zoran *) codec->master_data->data;
194 __u32 data;
195
196 if (post_office_wait(zr)
197 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
198 return -1;
199 }
200
201 data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read
202 return data;
203}
204
205static void
206zr36050_write (struct videocodec *codec,
207 u16 reg,
208 u32 val)
209{
210 struct zoran *zr = (struct zoran *) codec->master_data->data;
211
212 if (post_office_wait(zr)
213 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
214 return;
215 }
216
217 post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data
218}
219
220/* videocodec bus functions ZR36016 */
221static u32
222zr36016_read (struct videocodec *codec,
223 u16 reg)
224{
225 struct zoran *zr = (struct zoran *) codec->master_data->data;
226 __u32 data;
227
228 if (post_office_wait(zr)) {
229 return -1;
230 }
231
232 data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read
233 return data;
234}
235
236/* hack for in zoran_device.c */
237void
238zr36016_write (struct videocodec *codec,
239 u16 reg,
240 u32 val)
241{
242 struct zoran *zr = (struct zoran *) codec->master_data->data;
243
244 if (post_office_wait(zr)) {
245 return;
246 }
247
248 post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data
249}
250
251/*
252 * Board specific information
253 */
254
255static void
256dc10_init (struct zoran *zr)
257{
Trent Piephoc61402b2009-03-10 23:28:33 -0300258 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260 /* Pixel clock selection */
261 GPIO(zr, 4, 0);
262 GPIO(zr, 5, 1);
263 /* Enable the video bus sync signals */
264 GPIO(zr, 7, 0);
265}
266
267static void
268dc10plus_init (struct zoran *zr)
269{
Trent Piephoc61402b2009-03-10 23:28:33 -0300270 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271}
272
273static void
274buz_init (struct zoran *zr)
275{
Trent Piephoc61402b2009-03-10 23:28:33 -0300276 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
278 /* some stuff from Iomega */
279 pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
280 pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
281 pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
282}
283
284static void
285lml33_init (struct zoran *zr)
286{
Trent Piephoc61402b2009-03-10 23:28:33 -0300287 dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288
289 GPIO(zr, 2, 1); // Set Composite input/output
290}
291
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300292static void
293avs6eyes_init (struct zoran *zr)
294{
295 // AverMedia 6-Eyes original driver by Christer Weinigel
296
297 // Lifted straight from Christer's old driver and
298 // modified slightly by Martin Samuelsson.
299
300 int mux = default_mux; /* 1 = BT866, 7 = VID1 */
301
302 GPIO(zr, 4, 1); /* Bt866 SLEEP on */
303 udelay(2);
304
305 GPIO(zr, 0, 1); /* ZR36060 /RESET on */
306 GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
307 GPIO(zr, 2, mux & 1); /* MUX S0 */
308 GPIO(zr, 3, 0); /* /FRAME on */
309 GPIO(zr, 4, 0); /* Bt866 SLEEP off */
310 GPIO(zr, 5, mux & 2); /* MUX S1 */
311 GPIO(zr, 6, 0); /* ? */
312 GPIO(zr, 7, mux & 4); /* MUX S2 */
313
314}
315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316static char *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317codecid_to_modulename (u16 codecid)
318{
319 char *name = NULL;
320
321 switch (codecid) {
322 case CODEC_TYPE_ZR36060:
323 name = "zr36060";
324 break;
325 case CODEC_TYPE_ZR36050:
326 name = "zr36050";
327 break;
328 case CODEC_TYPE_ZR36016:
329 name = "zr36016";
330 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 }
332
333 return name;
334}
335
336// struct tvnorm {
337// u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
338// };
339
340static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
341static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
342static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
343static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
344
345static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 };
346static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 };
347
348/* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */
349static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
350static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
351
352/* FIXME: I cannot swap U and V in saa7114, so i do one
353 * pixel left shift in zoran (75 -> 74)
354 * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */
355static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
356static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
357
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300358/* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I
359 * copy Maxim's left shift hack for the 6 Eyes.
360 *
361 * Christer's driver used the unshifted norms, though...
362 * /Sam */
363static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
364static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
365
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300366static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
367static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
368static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
369static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
370static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
371static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
372static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
373static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
374static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
375static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
376
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
378 {
379 .type = DC10_old,
380 .name = "DC10(old)",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300381 .i2c_decoder = "vpx3220a",
382 .mod_decoder = "vpx3220",
383 .addrs_decoder = vpx3220_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 .video_codec = CODEC_TYPE_ZR36050,
385 .video_vfe = CODEC_TYPE_ZR36016,
386
387 .inputs = 3,
388 .input = {
389 { 1, "Composite" },
390 { 2, "S-Video" },
391 { 0, "Internal/comp" }
392 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300393 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 .tvn = {
395 &f50sqpixel_dc10,
396 &f60sqpixel_dc10,
397 &f50sqpixel_dc10
398 },
399 .jpeg_int = 0,
400 .vsync_int = ZR36057_ISR_GIRQ1,
401 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
402 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
403 .gpcs = { -1, 0 },
404 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
405 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300406 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 .init = &dc10_init,
408 }, {
409 .type = DC10_new,
410 .name = "DC10(new)",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300411 .i2c_decoder = "saa7110",
412 .mod_decoder = "saa7110",
413 .addrs_decoder = saa7110_addrs,
414 .i2c_encoder = "adv7175",
415 .mod_encoder = "adv7175",
416 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 .video_codec = CODEC_TYPE_ZR36060,
418
419 .inputs = 3,
420 .input = {
421 { 0, "Composite" },
422 { 7, "S-Video" },
423 { 5, "Internal/comp" }
424 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300425 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 .tvn = {
427 &f50sqpixel,
428 &f60sqpixel,
429 &f50sqpixel},
430 .jpeg_int = ZR36057_ISR_GIRQ0,
431 .vsync_int = ZR36057_ISR_GIRQ1,
432 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
433 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
434 .gpcs = { -1, 1},
435 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
436 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300437 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 .init = &dc10plus_init,
439 }, {
440 .type = DC10plus,
441 .name = "DC10plus",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300442 .i2c_decoder = "saa7110",
443 .mod_decoder = "saa7110",
444 .addrs_decoder = saa7110_addrs,
445 .i2c_encoder = "adv7175",
446 .mod_encoder = "adv7175",
447 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 .video_codec = CODEC_TYPE_ZR36060,
449
450 .inputs = 3,
451 .input = {
452 { 0, "Composite" },
453 { 7, "S-Video" },
454 { 5, "Internal/comp" }
455 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300456 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 .tvn = {
458 &f50sqpixel,
459 &f60sqpixel,
460 &f50sqpixel
461 },
462 .jpeg_int = ZR36057_ISR_GIRQ0,
463 .vsync_int = ZR36057_ISR_GIRQ1,
464 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
465 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
466 .gpcs = { -1, 1 },
467 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
468 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300469 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 .init = &dc10plus_init,
471 }, {
472 .type = DC30,
473 .name = "DC30",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300474 .i2c_decoder = "vpx3220a",
475 .mod_decoder = "vpx3220",
476 .addrs_decoder = vpx3220_addrs,
477 .i2c_encoder = "adv7175",
478 .mod_encoder = "adv7175",
479 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 .video_codec = CODEC_TYPE_ZR36050,
481 .video_vfe = CODEC_TYPE_ZR36016,
482
483 .inputs = 3,
484 .input = {
485 { 1, "Composite" },
486 { 2, "S-Video" },
487 { 0, "Internal/comp" }
488 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300489 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 .tvn = {
491 &f50sqpixel_dc10,
492 &f60sqpixel_dc10,
493 &f50sqpixel_dc10
494 },
495 .jpeg_int = 0,
496 .vsync_int = ZR36057_ISR_GIRQ1,
497 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
498 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
499 .gpcs = { -1, 0 },
500 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
501 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300502 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 .init = &dc10_init,
504 }, {
505 .type = DC30plus,
506 .name = "DC30plus",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300507 .i2c_decoder = "vpx3220a",
508 .mod_decoder = "vpx3220",
509 .addrs_decoder = vpx3220_addrs,
510 .i2c_encoder = "adv7175",
511 .mod_encoder = "adv7175",
512 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 .video_codec = CODEC_TYPE_ZR36050,
514 .video_vfe = CODEC_TYPE_ZR36016,
515
516 .inputs = 3,
517 .input = {
518 { 1, "Composite" },
519 { 2, "S-Video" },
520 { 0, "Internal/comp" }
521 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300522 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 .tvn = {
524 &f50sqpixel_dc10,
525 &f60sqpixel_dc10,
526 &f50sqpixel_dc10
527 },
528 .jpeg_int = 0,
529 .vsync_int = ZR36057_ISR_GIRQ1,
530 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
531 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
532 .gpcs = { -1, 0 },
533 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
534 .gws_not_connected = 0,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300535 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 .init = &dc10_init,
537 }, {
538 .type = LML33,
539 .name = "LML33",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300540 .i2c_decoder = "bt819a",
541 .mod_decoder = "bt819",
542 .addrs_decoder = bt819_addrs,
543 .i2c_encoder = "bt856",
544 .mod_encoder = "bt856",
545 .addrs_encoder = bt856_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 .video_codec = CODEC_TYPE_ZR36060,
547
548 .inputs = 2,
549 .input = {
550 { 0, "Composite" },
551 { 7, "S-Video" }
552 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300553 .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 .tvn = {
555 &f50ccir601_lml33,
556 &f60ccir601_lml33,
557 NULL
558 },
559 .jpeg_int = ZR36057_ISR_GIRQ1,
560 .vsync_int = ZR36057_ISR_GIRQ0,
561 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
562 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
563 .gpcs = { 3, 1 },
564 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
565 .gws_not_connected = 1,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300566 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 .init = &lml33_init,
568 }, {
569 .type = LML33R10,
570 .name = "LML33R10",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300571 .i2c_decoder = "saa7114",
572 .mod_decoder = "saa7115",
573 .addrs_decoder = saa7114_addrs,
574 .i2c_encoder = "adv7170",
575 .mod_encoder = "adv7170",
576 .addrs_encoder = adv717x_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 .video_codec = CODEC_TYPE_ZR36060,
578
579 .inputs = 2,
580 .input = {
581 { 0, "Composite" },
582 { 7, "S-Video" }
583 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300584 .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 .tvn = {
586 &f50ccir601_lm33r10,
587 &f60ccir601_lm33r10,
588 NULL
589 },
590 .jpeg_int = ZR36057_ISR_GIRQ1,
591 .vsync_int = ZR36057_ISR_GIRQ0,
592 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
593 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
594 .gpcs = { 3, 1 },
595 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
596 .gws_not_connected = 1,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300597 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 .init = &lml33_init,
599 }, {
600 .type = BUZ,
601 .name = "Buz",
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300602 .i2c_decoder = "saa7111",
603 .mod_decoder = "saa7115",
604 .addrs_decoder = saa7111_addrs,
605 .i2c_encoder = "saa7185",
606 .mod_encoder = "saa7185",
607 .addrs_encoder = saa7185_addrs,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 .video_codec = CODEC_TYPE_ZR36060,
609
610 .inputs = 2,
611 .input = {
612 { 3, "Composite" },
613 { 7, "S-Video" }
614 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300615 .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 .tvn = {
617 &f50ccir601,
618 &f60ccir601,
619 &f50ccir601
620 },
621 .jpeg_int = ZR36057_ISR_GIRQ1,
622 .vsync_int = ZR36057_ISR_GIRQ0,
623 .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
624 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
625 .gpcs = { 3, 1 },
626 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
627 .gws_not_connected = 1,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300628 .input_mux = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 .init = &buz_init,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300630 }, {
631 .type = AVS6EYES,
632 .name = "6-Eyes",
633 /* AverMedia chose not to brand the 6-Eyes. Thus it
634 can't be autodetected, and requires card=x. */
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300635 .i2c_decoder = "ks0127",
636 .mod_decoder = "ks0127",
637 .addrs_decoder = ks0127_addrs,
638 .i2c_encoder = "bt866",
639 .mod_encoder = "bt866",
640 .addrs_encoder = bt866_addrs,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300641 .video_codec = CODEC_TYPE_ZR36060,
642
643 .inputs = 10,
644 .input = {
645 { 0, "Composite 1" },
646 { 1, "Composite 2" },
647 { 2, "Composite 3" },
648 { 4, "Composite 4" },
649 { 5, "Composite 5" },
650 { 6, "Composite 6" },
651 { 8, "S-Video 1" },
652 { 9, "S-Video 2" },
653 {10, "S-Video 3" },
654 {15, "YCbCr" }
655 },
Hans Verkuil107063c2009-02-18 17:26:06 -0300656 .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300657 .tvn = {
658 &f50ccir601_avs6eyes,
659 &f60ccir601_avs6eyes,
660 NULL
661 },
662 .jpeg_int = ZR36057_ISR_GIRQ1,
663 .vsync_int = ZR36057_ISR_GIRQ0,
664 .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
665 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
666 .gpcs = { 3, 1 }, // Validity unknown /Sam
667 .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam
668 .gws_not_connected = 1,
669 .input_mux = 1,
670 .init = &avs6eyes_init,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 }
Martin Samuelssonfbe60da2006-04-27 10:17:00 -0300672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673};
674
675/*
676 * I2C functions
677 */
678/* software I2C functions */
679static int
680zoran_i2c_getsda (void *data)
681{
682 struct zoran *zr = (struct zoran *) data;
683
684 return (btread(ZR36057_I2CBR) >> 1) & 1;
685}
686
687static int
688zoran_i2c_getscl (void *data)
689{
690 struct zoran *zr = (struct zoran *) data;
691
692 return btread(ZR36057_I2CBR) & 1;
693}
694
695static void
696zoran_i2c_setsda (void *data,
697 int state)
698{
699 struct zoran *zr = (struct zoran *) data;
700
701 if (state)
702 zr->i2cbr |= 2;
703 else
704 zr->i2cbr &= ~2;
705 btwrite(zr->i2cbr, ZR36057_I2CBR);
706}
707
708static void
709zoran_i2c_setscl (void *data,
710 int state)
711{
712 struct zoran *zr = (struct zoran *) data;
713
714 if (state)
715 zr->i2cbr |= 1;
716 else
717 zr->i2cbr &= ~1;
718 btwrite(zr->i2cbr, ZR36057_I2CBR);
719}
720
Jean Delvare62751632008-06-12 13:20:46 -0300721static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 .setsda = zoran_i2c_setsda,
723 .setscl = zoran_i2c_setscl,
724 .getsda = zoran_i2c_getsda,
725 .getscl = zoran_i2c_getscl,
726 .udelay = 10,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 .timeout = 100,
728};
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730static int
731zoran_register_i2c (struct zoran *zr)
732{
733 memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
734 sizeof(struct i2c_algo_bit_data));
735 zr->i2c_algo.data = zr;
Jean Delvare62751632008-06-12 13:20:46 -0300736 strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
737 sizeof(zr->i2c_adapter.name));
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -0300738 i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 zr->i2c_adapter.algo_data = &zr->i2c_algo;
Jean Delvare12a917f2007-02-13 22:09:03 +0100740 zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 return i2c_bit_add_bus(&zr->i2c_adapter);
742}
743
744static void
745zoran_unregister_i2c (struct zoran *zr)
746{
Jean Delvare32697112006-12-10 21:21:33 +0100747 i2c_del_adapter(&zr->i2c_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748}
749
750/* Check a zoran_params struct for correctness, insert default params */
751
752int
753zoran_check_jpg_settings (struct zoran *zr,
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300754 struct zoran_jpg_settings *settings,
755 int try)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756{
757 int err = 0, err0 = 0;
758
759 dprintk(4,
760 KERN_DEBUG
Trent Piephoc61402b2009-03-10 23:28:33 -0300761 "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
762 ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 settings->VerDcm, settings->TmpDcm);
764 dprintk(4,
765 KERN_DEBUG
Trent Piephoc61402b2009-03-10 23:28:33 -0300766 "%s: %s - x: %d, y: %d, w: %d, y: %d\n",
767 ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 settings->img_width, settings->img_height);
769 /* Check decimation, set default values for decimation = 1, 2, 4 */
770 switch (settings->decimation) {
771 case 1:
772
773 settings->HorDcm = 1;
774 settings->VerDcm = 1;
775 settings->TmpDcm = 1;
776 settings->field_per_buff = 2;
777 settings->img_x = 0;
778 settings->img_y = 0;
779 settings->img_width = BUZ_MAX_WIDTH;
780 settings->img_height = BUZ_MAX_HEIGHT / 2;
781 break;
782 case 2:
783
784 settings->HorDcm = 2;
785 settings->VerDcm = 1;
786 settings->TmpDcm = 2;
787 settings->field_per_buff = 1;
788 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
789 settings->img_y = 0;
790 settings->img_width =
791 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
792 settings->img_height = BUZ_MAX_HEIGHT / 2;
793 break;
794 case 4:
795
796 if (zr->card.type == DC10_new) {
797 dprintk(1,
798 KERN_DEBUG
Trent Piephoc61402b2009-03-10 23:28:33 -0300799 "%s: %s - HDec by 4 is not supported on the DC10\n",
800 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 err0++;
802 break;
803 }
804
805 settings->HorDcm = 4;
806 settings->VerDcm = 2;
807 settings->TmpDcm = 2;
808 settings->field_per_buff = 1;
809 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
810 settings->img_y = 0;
811 settings->img_width =
812 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
813 settings->img_height = BUZ_MAX_HEIGHT / 2;
814 break;
815 case 0:
816
817 /* We have to check the data the user has set */
818
819 if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300820 (zr->card.type == DC10_new || settings->HorDcm != 4)) {
821 settings->HorDcm = clamp(settings->HorDcm, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300823 }
824 if (settings->VerDcm != 1 && settings->VerDcm != 2) {
825 settings->VerDcm = clamp(settings->VerDcm, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300827 }
828 if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
829 settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300831 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 if (settings->field_per_buff != 1 &&
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300833 settings->field_per_buff != 2) {
834 settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300836 }
837 if (settings->img_x < 0) {
838 settings->img_x = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300840 }
841 if (settings->img_y < 0) {
842 settings->img_y = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300844 }
845 if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
846 settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300848 }
849 if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
850 settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300852 }
853 if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
854 settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300856 }
857 if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
858 settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 err0++;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300860 }
861 if (settings->img_width % (16 * settings->HorDcm) != 0) {
862 settings->img_width -= settings->img_width % (16 * settings->HorDcm);
863 if (settings->img_width == 0)
864 settings->img_width = 16 * settings->HorDcm;
865 err0++;
866 }
867 if (settings->img_height % (8 * settings->VerDcm) != 0) {
868 settings->img_height -= settings->img_height % (8 * settings->VerDcm);
869 if (settings->img_height == 0)
870 settings->img_height = 8 * settings->VerDcm;
871 err0++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 }
873
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300874 if (!try && err0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 dprintk(1,
876 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -0300877 "%s: %s - error in params for decimation = 0\n",
878 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 err++;
880 }
881 break;
882 default:
883 dprintk(1,
884 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -0300885 "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n",
886 ZR_DEVNAME(zr), __func__, settings->decimation);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 err++;
888 break;
889 }
890
891 if (settings->jpg_comp.quality > 100)
892 settings->jpg_comp.quality = 100;
893 if (settings->jpg_comp.quality < 5)
894 settings->jpg_comp.quality = 5;
895 if (settings->jpg_comp.APPn < 0)
896 settings->jpg_comp.APPn = 0;
897 if (settings->jpg_comp.APPn > 15)
898 settings->jpg_comp.APPn = 15;
899 if (settings->jpg_comp.APP_len < 0)
900 settings->jpg_comp.APP_len = 0;
901 if (settings->jpg_comp.APP_len > 60)
902 settings->jpg_comp.APP_len = 60;
903 if (settings->jpg_comp.COM_len < 0)
904 settings->jpg_comp.COM_len = 0;
905 if (settings->jpg_comp.COM_len > 60)
906 settings->jpg_comp.COM_len = 60;
907 if (err)
908 return -EINVAL;
909 return 0;
910}
911
912void
913zoran_open_init_params (struct zoran *zr)
914{
915 int i;
916
917 /* User must explicitly set a window */
918 zr->overlay_settings.is_set = 0;
919 zr->overlay_mask = NULL;
920 zr->overlay_active = ZORAN_FREE;
921
922 zr->v4l_memgrab_active = 0;
923 zr->v4l_overlay_active = 0;
924 zr->v4l_grab_frame = NO_GRAB_ACTIVE;
925 zr->v4l_grab_seq = 0;
926 zr->v4l_settings.width = 192;
927 zr->v4l_settings.height = 144;
Jean Delvarec014ec92008-09-07 05:21:34 -0300928 zr->v4l_settings.format = &zoran_formats[7]; /* YUY2 - YUV-4:2:2 packed */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 zr->v4l_settings.bytesperline =
930 zr->v4l_settings.width *
931 ((zr->v4l_settings.format->depth + 7) / 8);
932
933 /* DMA ring stuff for V4L */
934 zr->v4l_pend_tail = 0;
935 zr->v4l_pend_head = 0;
936 zr->v4l_sync_tail = 0;
937 zr->v4l_buffers.active = ZORAN_FREE;
938 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
939 zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
940 }
941 zr->v4l_buffers.allocated = 0;
942
943 for (i = 0; i < BUZ_MAX_FRAME; i++) {
944 zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
945 }
946 zr->jpg_buffers.active = ZORAN_FREE;
947 zr->jpg_buffers.allocated = 0;
948 /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
949 zr->jpg_settings.decimation = 1;
950 zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
951 if (zr->card.type != BUZ)
952 zr->jpg_settings.odd_even = 1;
953 else
954 zr->jpg_settings.odd_even = 0;
955 zr->jpg_settings.jpg_comp.APPn = 0;
956 zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */
957 memset(zr->jpg_settings.jpg_comp.APP_data, 0,
958 sizeof(zr->jpg_settings.jpg_comp.APP_data));
959 zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */
960 memset(zr->jpg_settings.jpg_comp.COM_data, 0,
961 sizeof(zr->jpg_settings.jpg_comp.COM_data));
962 zr->jpg_settings.jpg_comp.jpeg_markers =
963 JPEG_MARKER_DHT | JPEG_MARKER_DQT;
Hans Verkuil0ba514d2009-02-18 17:11:17 -0300964 i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 if (i)
Trent Piephoc61402b2009-03-10 23:28:33 -0300966 dprintk(1, KERN_ERR "%s: %s internal error\n",
967 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968
969 clear_interrupt_counters(zr);
970 zr->testing = 0;
971}
972
973static void __devinit
974test_interrupts (struct zoran *zr)
975{
976 DEFINE_WAIT(wait);
977 int timeout, icr;
978
979 clear_interrupt_counters(zr);
980
981 zr->testing = 1;
982 icr = btread(ZR36057_ICR);
983 btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR);
984 prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE);
985 timeout = schedule_timeout(HZ);
986 finish_wait(&zr->test_q, &wait);
987 btwrite(0, ZR36057_ICR);
988 btwrite(0x78000000, ZR36057_ISR);
989 zr->testing = 0;
990 dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr));
991 if (timeout) {
992 dprintk(1, ": time spent: %d\n", 1 * HZ - timeout);
993 }
Jean Delvare18b548c2007-07-17 18:29:41 -0300994 if (zr36067_debug > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 print_interrupts(zr);
996 btwrite(icr, ZR36057_ICR);
997}
998
999static int __devinit
1000zr36057_init (struct zoran *zr)
1001{
Jean Delvaredaf72f42006-03-22 03:48:37 -03001002 int j, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
1004 dprintk(1,
1005 KERN_INFO
Trent Piephoc61402b2009-03-10 23:28:33 -03001006 "%s: %s - initializing card[%d], zr=%p\n",
1007 ZR_DEVNAME(zr), __func__, zr->id, zr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009 /* default setup of all parameters which will persist between opens */
1010 zr->user = 0;
1011
1012 init_waitqueue_head(&zr->v4l_capq);
1013 init_waitqueue_head(&zr->jpg_capq);
1014 init_waitqueue_head(&zr->test_q);
1015 zr->jpg_buffers.allocated = 0;
1016 zr->v4l_buffers.allocated = 0;
1017
Hans Verkuil7f6adea2009-02-19 17:31:17 -03001018 zr->vbuf_base = (void *) vidmem;
1019 zr->vbuf_width = 0;
1020 zr->vbuf_height = 0;
1021 zr->vbuf_depth = 0;
1022 zr->vbuf_bytesperline = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
1024 /* Avoid nonsense settings from user for default input/norm */
Roel Kluinb475f4e2009-05-02 17:52:52 -03001025 if (default_norm < 0 || default_norm > 2)
Hans Verkuil7f6adea2009-02-19 17:31:17 -03001026 default_norm = 0;
1027 if (default_norm == 0) {
Hans Verkuil107063c2009-02-18 17:26:06 -03001028 zr->norm = V4L2_STD_PAL;
1029 zr->timing = zr->card.tvn[0];
Hans Verkuil7f6adea2009-02-19 17:31:17 -03001030 } else if (default_norm == 1) {
Hans Verkuil107063c2009-02-18 17:26:06 -03001031 zr->norm = V4L2_STD_NTSC;
1032 zr->timing = zr->card.tvn[1];
1033 } else {
1034 zr->norm = V4L2_STD_SECAM;
1035 zr->timing = zr->card.tvn[2];
1036 }
1037 if (zr->timing == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 dprintk(1,
1039 KERN_WARNING
Trent Piephoc61402b2009-03-10 23:28:33 -03001040 "%s: %s - default TV standard not supported by hardware. PAL will be used.\n",
1041 ZR_DEVNAME(zr), __func__);
Hans Verkuil107063c2009-02-18 17:26:06 -03001042 zr->norm = V4L2_STD_PAL;
1043 zr->timing = zr->card.tvn[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 }
1045
Trent Piepho60e3cac2007-07-17 18:29:42 -03001046 if (default_input > zr->card.inputs-1) {
1047 dprintk(1,
1048 KERN_WARNING
1049 "%s: default_input value %d out of range (0-%d)\n",
1050 ZR_DEVNAME(zr), default_input, zr->card.inputs-1);
1051 default_input = 0;
1052 }
1053 zr->input = default_input;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 /* default setup (will be repeated at every open) */
1056 zoran_open_init_params(zr);
1057
1058 /* allocate memory *before* doing anything to the hardware
1059 * in case allocation fails */
Jean Delvaredaf72f42006-03-22 03:48:37 -03001060 zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL);
1061 zr->video_dev = kmalloc(sizeof(struct video_device), GFP_KERNEL);
1062 if (!zr->stat_com || !zr->video_dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 dprintk(1,
1064 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001065 "%s: %s - kmalloc (STAT_COM) failed\n",
1066 ZR_DEVNAME(zr), __func__);
Jean Delvaredaf72f42006-03-22 03:48:37 -03001067 err = -ENOMEM;
1068 goto exit_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
Al Viro9c169df2008-06-22 14:19:49 -03001071 zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 }
1073
1074 /*
1075 * Now add the template and register the device unit.
1076 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
Hans Verkuilaff88bc2009-02-18 13:52:24 -03001078 zr->video_dev->parent = &zr->pci_dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
Trent Piepho60e3cac2007-07-17 18:29:42 -03001080 err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
Jean Delvaredaf72f42006-03-22 03:48:37 -03001081 if (err < 0)
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001082 goto exit_free;
Trent Piepho601139e2009-01-12 13:09:46 -03001083 video_set_drvdata(zr->video_dev, zr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
1085 zoran_init_hardware(zr);
Jean Delvare18b548c2007-07-17 18:29:41 -03001086 if (zr36067_debug > 2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 detect_guest_activity(zr);
1088 test_interrupts(zr);
1089 if (!pass_through) {
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001090 decoder_call(zr, video, s_stream, 0);
Hans Verkuil5325b422009-04-02 11:26:22 -03001091 encoder_call(zr, video, s_routing, 2, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 }
1093
1094 zr->zoran_proc = NULL;
1095 zr->initialized = 1;
1096 return 0;
Jean Delvaredaf72f42006-03-22 03:48:37 -03001097
Jean Delvaredaf72f42006-03-22 03:48:37 -03001098exit_free:
1099 kfree(zr->stat_com);
1100 kfree(zr->video_dev);
1101 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102}
1103
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001104static void __devexit zoran_remove(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105{
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001106 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
1107 struct zoran *zr = to_zoran(v4l2_dev);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001108
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 if (!zr->initialized)
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001110 goto exit_free;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 /* unregister videocodec bus */
1113 if (zr->codec) {
1114 struct videocodec_master *master = zr->codec->master_data;
Jesper Juhl2ea75332005-11-07 01:01:31 -08001115
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 videocodec_detach(zr->codec);
Jesper Juhl2ea75332005-11-07 01:01:31 -08001117 kfree(master);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 }
1119 if (zr->vfe) {
1120 struct videocodec_master *master = zr->vfe->master_data;
Jesper Juhl2ea75332005-11-07 01:01:31 -08001121
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 videocodec_detach(zr->vfe);
Jesper Juhl2ea75332005-11-07 01:01:31 -08001123 kfree(master);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 }
1125
1126 /* unregister i2c bus */
1127 zoran_unregister_i2c(zr);
1128 /* disable PCI bus-mastering */
1129 zoran_set_pci_master(zr, 0);
1130 /* put chip into reset */
1131 btwrite(0, ZR36057_SPGPPCR);
1132 free_irq(zr->pci_dev->irq, zr);
1133 /* unmap and free memory */
Jean Delvaredaf72f42006-03-22 03:48:37 -03001134 kfree(zr->stat_com);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 zoran_proc_cleanup(zr);
1136 iounmap(zr->zr36057_mem);
1137 pci_disable_device(zr->pci_dev);
1138 video_unregister_device(zr->video_dev);
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001139exit_free:
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001140 v4l2_device_unregister(&zr->v4l2_dev);
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001141 kfree(zr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142}
1143
1144void
1145zoran_vdev_release (struct video_device *vdev)
1146{
1147 kfree(vdev);
1148}
1149
1150static struct videocodec_master * __devinit
1151zoran_setup_videocodec (struct zoran *zr,
1152 int type)
1153{
1154 struct videocodec_master *m = NULL;
1155
1156 m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
1157 if (!m) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001158 dprintk(1, KERN_ERR "%s: %s - no memory\n",
1159 ZR_DEVNAME(zr), __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 return m;
1161 }
1162
Mauro Carvalho Chehab22c4a4e2007-10-15 12:09:17 -03001163 /* magic and type are unused for master struct. Makes sense only at
1164 codec structs.
1165 In the past, .type were initialized to the old V4L1 .hardware
1166 value, as VID_HARDWARE_ZR36067
1167 */
1168 m->magic = 0L;
1169 m->type = 0;
1170
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
Roel Kluinbd0eb122009-08-08 12:58:52 -03001172 strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 m->data = zr;
1174
1175 switch (type)
1176 {
1177 case CODEC_TYPE_ZR36060:
1178 m->readreg = zr36060_read;
1179 m->writereg = zr36060_write;
1180 m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
1181 break;
1182 case CODEC_TYPE_ZR36050:
1183 m->readreg = zr36050_read;
1184 m->writereg = zr36050_write;
1185 m->flags |= CODEC_FLAG_JPEG;
1186 break;
1187 case CODEC_TYPE_ZR36016:
1188 m->readreg = zr36016_read;
1189 m->writereg = zr36016_write;
1190 m->flags |= CODEC_FLAG_VFE;
1191 break;
1192 }
1193
1194 return m;
1195}
1196
Hans Verkuil33470422009-03-14 12:53:37 -03001197static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -03001198{
1199 struct zoran *zr = to_zoran(sd->v4l2_dev);
1200
1201 /* Bt819 needs to reset its FIFO buffer using #FRST pin and
1202 LML33 card uses GPIO(7) for that. */
1203 if (cmd == BT819_FIFO_RESET_LOW)
1204 GPIO(zr, 7, 0);
1205 else if (cmd == BT819_FIFO_RESET_HIGH)
1206 GPIO(zr, 7, 1);
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -03001207}
1208
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209/*
Joe Perchesc84e6032008-02-03 17:18:59 +02001210 * Scan for a Buz card (actually for the PCI controller ZR36057),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 * request the irq and map the io memory
1212 */
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001213static int __devinit zoran_probe(struct pci_dev *pdev,
1214 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215{
1216 unsigned char latency, need_latency;
1217 struct zoran *zr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 int result;
1219 struct videocodec_master *master_vfe = NULL;
1220 struct videocodec_master *master_codec = NULL;
1221 int card_num;
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001222 char *codec_name, *vfe_name;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001223 unsigned int nr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001225
Trent Piepho601139e2009-01-12 13:09:46 -03001226 nr = zoran_num++;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001227 if (nr >= BUZ_MAX) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001228 dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001229 ZORAN_NAME, BUZ_MAX);
1230 return -ENOENT;
1231 }
1232
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001233 zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
1234 if (!zr) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001235 dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n",
1236 ZORAN_NAME, __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001237 return -ENOMEM;
1238 }
Hans Verkuil1cd3c0f2009-03-08 17:04:38 -03001239 zr->v4l2_dev.notify = zoran_subdev_notify;
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001240 if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
1241 goto zr_free_mem;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001242 zr->pci_dev = pdev;
1243 zr->id = nr;
1244 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
1245 spin_lock_init(&zr->spinlock);
1246 mutex_init(&zr->resource_lock);
1247 if (pci_enable_device(pdev))
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001248 goto zr_unreg;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001249 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
Trent Piepho17faeb22009-01-12 13:09:46 -03001250
1251 dprintk(1,
1252 KERN_INFO
Trent Piepho5e098b62009-01-12 13:09:46 -03001253 "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
Trent Piepho17faeb22009-01-12 13:09:46 -03001254 ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
Trent Piepho5e098b62009-01-12 13:09:46 -03001255 zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
Trent Piepho17faeb22009-01-12 13:09:46 -03001256 if (zr->revision >= 2) {
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001257 dprintk(1,
1258 KERN_INFO
Trent Piepho17faeb22009-01-12 13:09:46 -03001259 "%s: Subsystem vendor=0x%04x id=0x%04x\n",
1260 ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
1261 zr->pci_dev->subsystem_device);
1262 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001263
Trent Piepho17faeb22009-01-12 13:09:46 -03001264 /* Use auto-detected card type? */
1265 if (card[nr] == -1) {
1266 if (zr->revision < 2) {
Jean Delvare85b9b8a2008-07-14 09:51:03 -03001267 dprintk(1,
1268 KERN_ERR
Trent Piepho17faeb22009-01-12 13:09:46 -03001269 "%s: No card type specified, please use the card=X module parameter\n",
1270 ZR_DEVNAME(zr));
1271 dprintk(1,
1272 KERN_ERR
1273 "%s: It is not possible to auto-detect ZR36057 based cards\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001274 ZR_DEVNAME(zr));
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001275 goto zr_unreg;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
Trent Piepho17faeb22009-01-12 13:09:46 -03001278 card_num = ent->driver_data;
1279 if (card_num >= NUM_CARDS) {
1280 dprintk(1,
1281 KERN_ERR
1282 "%s: Unknown card, try specifying card=X module parameter\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001283 ZR_DEVNAME(zr));
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001284 goto zr_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 }
Trent Piepho17faeb22009-01-12 13:09:46 -03001286 dprintk(3,
1287 KERN_DEBUG
1288 "%s: %s() - card %s detected\n",
1289 ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
1290 } else {
1291 card_num = card[nr];
1292 if (card_num >= NUM_CARDS || card_num < 0) {
1293 dprintk(1,
1294 KERN_ERR
1295 "%s: User specified card type %d out of range (0 .. %d)\n",
1296 ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001297 goto zr_unreg;
Trent Piepho17faeb22009-01-12 13:09:46 -03001298 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001299 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001301 /* even though we make this a non pointer and thus
1302 * theoretically allow for making changes to this struct
1303 * on a per-individual card basis at runtime, this is
1304 * strongly discouraged. This structure is intended to
1305 * keep general card information, no settings or anything */
1306 zr->card = zoran_cards[card_num];
1307 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
1308 "%s[%u]", zr->card.name, zr->id);
1309
Trent Piepho5e098b62009-01-12 13:09:46 -03001310 zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001311 if (!zr->zr36057_mem) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001312 dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n",
Trent Piepho5e098b62009-01-12 13:09:46 -03001313 ZR_DEVNAME(zr), __func__);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001314 goto zr_unreg;
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001315 }
1316
1317 result = request_irq(zr->pci_dev->irq, zoran_irq,
1318 IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
1319 if (result < 0) {
1320 if (result == -EINVAL) {
1321 dprintk(1,
1322 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001323 "%s: %s - bad irq number or handler\n",
1324 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001325 } else if (result == -EBUSY) {
1326 dprintk(1,
1327 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001328 "%s: %s - IRQ %d busy, change your PnP config in BIOS\n",
1329 ZR_DEVNAME(zr), __func__, zr->pci_dev->irq);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001330 } else {
1331 dprintk(1,
1332 KERN_ERR
Trent Piephoc61402b2009-03-10 23:28:33 -03001333 "%s: %s - can't assign irq, error code %d\n",
1334 ZR_DEVNAME(zr), __func__, result);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001335 }
1336 goto zr_unmap;
1337 }
1338
1339 /* set PCI latency timer */
1340 pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
1341 &latency);
1342 need_latency = zr->revision > 1 ? 32 : 48;
1343 if (latency != need_latency) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001344 dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n",
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001345 ZR_DEVNAME(zr), latency, need_latency);
1346 pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
1347 need_latency);
1348 }
1349
1350 zr36057_restart(zr);
1351 /* i2c */
1352 dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
1353 ZR_DEVNAME(zr));
1354
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001355 if (zoran_register_i2c(zr) < 0) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001356 dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n",
1357 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001358 goto zr_free_irq;
1359 }
1360
Hans Verkuil53dacb12009-08-10 02:49:08 -03001361 zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
Hans Verkuile6574f22009-04-01 03:57:53 -03001362 &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder,
Hans Verkuil53dacb12009-08-10 02:49:08 -03001363 0, zr->card.addrs_decoder);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001364
1365 if (zr->card.mod_encoder)
Hans Verkuil53dacb12009-08-10 02:49:08 -03001366 zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
Hans Verkuile6574f22009-04-01 03:57:53 -03001367 &zr->i2c_adapter,
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001368 zr->card.mod_encoder, zr->card.i2c_encoder,
Hans Verkuil53dacb12009-08-10 02:49:08 -03001369 0, zr->card.addrs_encoder);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001370
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001371 dprintk(2,
1372 KERN_INFO "%s: Initializing videocodec bus...\n",
1373 ZR_DEVNAME(zr));
1374
1375 if (zr->card.video_codec) {
1376 codec_name = codecid_to_modulename(zr->card.video_codec);
1377 if (codec_name) {
1378 result = request_module(codec_name);
1379 if (result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 dprintk(1,
1381 KERN_ERR
1382 "%s: failed to load modules %s: %d\n",
1383 ZR_DEVNAME(zr), codec_name, result);
1384 }
1385 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001386 }
1387 if (zr->card.video_vfe) {
1388 vfe_name = codecid_to_modulename(zr->card.video_vfe);
1389 if (vfe_name) {
1390 result = request_module(vfe_name);
1391 if (result < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 dprintk(1,
1393 KERN_ERR
1394 "%s: failed to load modules %s: %d\n",
1395 ZR_DEVNAME(zr), vfe_name, result);
1396 }
1397 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 }
Alan Coxe491cbc2006-10-03 20:44:12 -03001399
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001400 /* reset JPEG codec */
1401 jpeg_codec_sleep(zr, 1);
1402 jpeg_codec_reset(zr);
1403 /* video bus enabled */
1404 /* display codec revision */
1405 if (zr->card.video_codec != 0) {
1406 master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
1407 if (!master_codec)
1408 goto zr_unreg_i2c;
1409 zr->codec = videocodec_attach(master_codec);
1410 if (!zr->codec) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001411 dprintk(1, KERN_ERR "%s: %s - no codec found\n",
1412 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001413 goto zr_free_codec;
1414 }
1415 if (zr->codec->type != zr->card.video_codec) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001416 dprintk(1, KERN_ERR "%s: %s - wrong codec\n",
1417 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001418 goto zr_detach_codec;
1419 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001421 if (zr->card.video_vfe != 0) {
1422 master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
1423 if (!master_vfe)
1424 goto zr_detach_codec;
1425 zr->vfe = videocodec_attach(master_vfe);
1426 if (!zr->vfe) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001427 dprintk(1, KERN_ERR "%s: %s - no VFE found\n",
1428 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001429 goto zr_free_vfe;
1430 }
1431 if (zr->vfe->type != zr->card.video_vfe) {
Trent Piephoc61402b2009-03-10 23:28:33 -03001432 dprintk(1, KERN_ERR "%s: %s = wrong VFE\n",
1433 ZR_DEVNAME(zr), __func__);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001434 goto zr_detach_vfe;
1435 }
1436 }
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001437
1438 /* take care of Natoma chipset and a revision 1 zr36057 */
1439 if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
1440 zr->jpg_buffers.need_contiguous = 1;
Trent Piephoc61402b2009-03-10 23:28:33 -03001441 dprintk(1, KERN_INFO
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001442 "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
1443 ZR_DEVNAME(zr));
1444 }
1445
1446 if (zr36057_init(zr) < 0)
1447 goto zr_detach_vfe;
1448
1449 zoran_proc_init(zr);
1450
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001451 return 0;
1452
1453zr_detach_vfe:
1454 videocodec_detach(zr->vfe);
1455zr_free_vfe:
1456 kfree(master_vfe);
1457zr_detach_codec:
1458 videocodec_detach(zr->codec);
1459zr_free_codec:
1460 kfree(master_codec);
1461zr_unreg_i2c:
1462 zoran_unregister_i2c(zr);
1463zr_free_irq:
1464 btwrite(0, ZR36057_SPGPPCR);
1465 free_irq(zr->pci_dev->irq, zr);
1466zr_unmap:
1467 iounmap(zr->zr36057_mem);
Hans Verkuil0ab6e1c2009-02-19 16:18:23 -03001468zr_unreg:
1469 v4l2_device_unregister(&zr->v4l2_dev);
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001470zr_free_mem:
1471 kfree(zr);
1472
1473 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474}
1475
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001476static struct pci_driver zoran_driver = {
1477 .name = "zr36067",
1478 .id_table = zr36067_pci_tbl,
1479 .probe = zoran_probe,
Jean Delvaree36bc312009-06-04 11:07:16 -03001480 .remove = __devexit_p(zoran_remove),
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001481};
1482
1483static int __init zoran_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484{
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001485 int res;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
1488 MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
1489
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 /* check the parameters we have been given, adjust if necessary */
1491 if (v4l_nbufs < 2)
1492 v4l_nbufs = 2;
1493 if (v4l_nbufs > VIDEO_MAX_FRAME)
1494 v4l_nbufs = VIDEO_MAX_FRAME;
1495 /* The user specfies the in KB, we want them in byte
1496 * (and page aligned) */
1497 v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
1498 if (v4l_bufsize < 32768)
1499 v4l_bufsize = 32768;
1500 /* 2 MB is arbitrary but sufficient for the maximum possible images */
1501 if (v4l_bufsize > 2048 * 1024)
1502 v4l_bufsize = 2048 * 1024;
1503 if (jpg_nbufs < 4)
1504 jpg_nbufs = 4;
1505 if (jpg_nbufs > BUZ_MAX_FRAME)
1506 jpg_nbufs = BUZ_MAX_FRAME;
1507 jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024);
1508 if (jpg_bufsize < 8192)
1509 jpg_bufsize = 8192;
1510 if (jpg_bufsize > (512 * 1024))
1511 jpg_bufsize = 512 * 1024;
1512 /* Use parameter for vidmem or try to find a video card */
1513 if (vidmem) {
1514 dprintk(1,
1515 KERN_INFO
1516 "%s: Using supplied video memory base address @ 0x%lx\n",
1517 ZORAN_NAME, vidmem);
1518 }
1519
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 /* some mainboards might not do PCI-PCI data transfer well */
Alan Coxe3558802006-09-14 11:47:55 -03001521 if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 dprintk(1,
1523 KERN_WARNING
Alan Coxe3558802006-09-14 11:47:55 -03001524 "%s: chipset does not support reliable PCI-PCI DMA\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 ZORAN_NAME);
1526 }
1527
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001528 res = pci_register_driver(&zoran_driver);
1529 if (res) {
1530 dprintk(1,
1531 KERN_ERR
1532 "%s: Unable to register ZR36057 driver\n",
1533 ZORAN_NAME);
1534 return res;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 }
1536
1537 return 0;
1538}
1539
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001540static void __exit zoran_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541{
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001542 pci_unregister_driver(&zoran_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543}
1544
Trent Piepho66aa66ea32009-01-11 12:02:54 -03001545module_init(zoran_init);
1546module_exit(zoran_exit);