From 3ba27c900cccb378926138315d78e418be98bd37 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 9 Jan 2009 20:59:27 -0500 Subject: cx23885: Fix Oops for mixed install of analog and digital only cards From: Andy Walls Analog support for HVR-1250 has not been completed, but does exist for the HVR-1800. Since both cards use the same driver, it tries to create the analog dev for both devices, which is not possible. This causes a NULL error to show up in video_open and mpeg_open. -Mark Iterations through the cx23885_devlist must check for NULL pointers as some supported devices only have DVB support at the moment. Mark Jenks encoutered an Oops in a system with both an HVR-1250 and HVR-1800 installed. -Andy Reported-by: Mark Jenks Priority: normal Tested-by: Mark Jenks Signed-off-by: Mark Jenks Signed-off-by: Andy Walls --- linux/drivers/media/video/cx23885/cx23885-417.c | 3 ++- linux/drivers/media/video/cx23885/cx23885-video.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c index 52f6824ff..0766a97a0 100644 --- a/linux/drivers/media/video/cx23885/cx23885-417.c +++ b/linux/drivers/media/video/cx23885/cx23885-417.c @@ -1594,7 +1594,8 @@ static int mpeg_open(struct file *file) lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); - if (h->v4l_device->minor == minor) { + if (h->v4l_device && + h->v4l_device->minor == minor) { dev = h; break; } diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index 838b3ac5a..09291888d 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -786,12 +786,13 @@ static int video_open(struct file *file) lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); - if (h->video_dev->minor == minor) { + if (h->video_dev && + h->video_dev->minor == minor) { dev = h; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } if (h->vbi_dev && - h->vbi_dev->minor == minor) { + h->vbi_dev->minor == minor) { dev = h; type = V4L2_BUF_TYPE_VBI_CAPTURE; } -- cgit v1.2.3 From 3c3d30d203929d5e8692abbb31f8bbf106d1a08c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 10 Jan 2009 12:31:15 +0100 Subject: Fix 'stb0899_get_srate' defined but not used warning From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/frontends/stb0899_algo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/stb0899_algo.c b/linux/drivers/media/dvb/frontends/stb0899_algo.c index b7211130c..3d13968a7 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_algo.c +++ b/linux/drivers/media/dvb/frontends/stb0899_algo.c @@ -31,6 +31,8 @@ inline u32 stb0899_do_div(u64 n, u32 d) return n; } +#if 0 /* keep */ +/* These functions are currently unused */ /* * stb0899_calc_srate * Compute symbol rate @@ -63,6 +65,7 @@ static u32 stb0899_get_srate(struct stb0899_state *state) return stb0899_calc_srate(internal->master_clk, sfr); } +#endif /* * stb0899_set_srate -- cgit v1.2.3 From 682ea867d9eec7d10d92eaf805693ded0ec20d64 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 10 Jan 2009 14:16:16 +0100 Subject: saa7127: fix broken S-Video with saa7129 From: Martin Dauskardt Register 0x2d has to be set differently in the saa7129 compared to the saa7127. This was not done correctly, so S-Video was broken in certain circumstances. This fixes a regression introduced in 2.6.28. Priority: high Signed-off-by: Martin Dauskardt Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7127.c | 52 +++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7127.c b/linux/drivers/media/video/saa7127.c index 79c947ca0..c6ddb476c 100644 --- a/linux/drivers/media/video/saa7127.c +++ b/linux/drivers/media/video/saa7127.c @@ -155,7 +155,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = { { SAA7127_REG_COPYGEN_0, 0x77 }, { SAA7127_REG_COPYGEN_1, 0x41 }, { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ - { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e }, + { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf }, { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ @@ -494,12 +494,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output) break; case SAA7127_OUTPUT_TYPE_COMPOSITE: - state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x20; /* CVBS only */ + else + state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; case SAA7127_OUTPUT_TYPE_SVIDEO: - state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */ + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x18; /* Y + C */ + else + state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; @@ -514,7 +520,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output) break; case SAA7127_OUTPUT_TYPE_BOTH: - state->reg_2d = 0xbf; + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x38; + else + state->reg_2d = 0xbf; state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; @@ -741,24 +750,6 @@ static int saa7127_probe(struct i2c_client *client, return -ENODEV; } - /* Configure Encoder */ - - v4l2_dbg(1, debug, sd, "Configuring encoder\n"); - saa7127_write_inittab(sd, saa7127_init_config_common); - saa7127_set_std(sd, V4L2_STD_NTSC); - saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH); - saa7127_set_vps(sd, &vbi); - saa7127_set_wss(sd, &vbi); - saa7127_set_cc(sd, &vbi); - saa7127_set_xds(sd, &vbi); - if (test_image == 1) - /* The Encoder has an internal Colorbar generator */ - /* This can be used for debugging */ - saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE); - else - saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL); - saa7127_set_video_enable(sd, 1); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) if (id->driver_data) { /* Chip type is already known */ state->ident = id->driver_data; @@ -784,6 +775,23 @@ static int saa7127_probe(struct i2c_client *client, v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); + + v4l2_dbg(1, debug, sd, "Configuring encoder\n"); + saa7127_write_inittab(sd, saa7127_init_config_common); + saa7127_set_std(sd, V4L2_STD_NTSC); + saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH); + saa7127_set_vps(sd, &vbi); + saa7127_set_wss(sd, &vbi); + saa7127_set_cc(sd, &vbi); + saa7127_set_xds(sd, &vbi); + if (test_image == 1) + /* The Encoder has an internal Colorbar generator */ + /* This can be used for debugging */ + saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE); + else + saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL); + saa7127_set_video_enable(sd, 1); + if (state->ident == V4L2_IDENT_SAA7129) saa7127_write_inittab(sd, saa7129_init_config_extra); return 0; -- cgit v1.2.3 From a7eec9c2d5f8725340da03c5509bf04980a03072 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 10 Jan 2009 16:04:45 -0500 Subject: saa7134: Prevent Oops due to stale IRQ status when enabling interrupts From: Andy Walls When enabling a shared IRQ line, then saa7134_irq handler could be invoked before the driver had completely set up internal structures, due to a shared interrupt line firing. Clear the saa7134 interrupt status reg, before requesting the irq line, so that stale IRQ status isn't processed before the internal structures are set up. Marcin Slusarz recently brought this Oops to the attention of the v4l-dvb lists and provided an initial analysis by investigating reports found here: http://kerneloops.org/guilty.php?guilty=mute_input_7133&version=2.6.27-release&start=1802240&end=1835007&class=oops Reported-by: Marcin Slusarz Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/saa7134/saa7134-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 2e9a015e9..624ac4537 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -721,6 +721,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, 0); + + /* Clear any stale IRQ reports */ + saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT)); + mutex_init(&dev->lock); spin_lock_init(&dev->slock); -- cgit v1.2.3 From 2d91773c33fffd026876e75af92d335ea1dc0aaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 11 Jan 2009 11:29:43 -0200 Subject: vivi: Implements 4 inputs on vivi From: Mauro Carvalho Chehab This patch adds the capability of selecting between 4 different inputs on vivi driver. Input 0 is the normal color bar, while inputs 1-3 are modified color bars. This allows testing input selection on userspace applications and serves as an implementation model for other drivers. The current approach allows a maximum of 10 different inputs, since the input name generator assumes that we need just one digit to present the input. It shouldn't be hard to modify it to present a bigger name of inputs, but, in fact, it doesn't make much sense of doing it for this test driver. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/vivi.c | 186 ++++++++++++++++++++++++++++++--------- 1 file changed, 142 insertions(+), 44 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 90a6f70bb..603274874 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -226,6 +226,9 @@ struct vivi_dev { char timestr[13]; int mv_count; /* Controls bars movement */ + + /* Input Number */ + int input; }; struct vivi_fh { @@ -238,6 +241,7 @@ struct vivi_fh { enum v4l2_buf_type type; unsigned char bars[8][3]; + int input; /* Input Number on bars */ }; /* ------------------------------------------------------------------ @@ -257,18 +261,72 @@ enum colors { BLACK, }; -static u8 bars[8][3] = { /* R G B */ - {204, 204, 204}, /* white */ - {208, 208, 0}, /* ambar */ - { 0, 206, 206}, /* cyan */ - { 0, 239, 0}, /* green */ - {239, 0, 239}, /* magenta */ - {205, 0, 0}, /* red */ - { 0, 0, 255}, /* blue */ - { 0, 0, 0}, /* black */ +#define COLOR_WHITE {204, 204, 204} +#define COLOR_AMBAR {208, 208, 0} +#define COLOR_CIAN { 0, 206, 206} +#define COLOR_GREEN { 0, 239, 0} +#define COLOR_MAGENTA {239, 0, 239} +#define COLOR_RED {205, 0, 0} +#define COLOR_BLUE { 0, 0, 255} +#define COLOR_BLACK { 0, 0, 0} + +struct bar_std { + u8 bar[8][3]; +}; + +/* Maximum number of bars are 10 - otherwise, the input print code + should be modified */ +static struct bar_std bars[] = { + { /* Standard ITU-R color bar sequence */ + { + COLOR_WHITE, + COLOR_AMBAR, + COLOR_CIAN, + COLOR_GREEN, + COLOR_MAGENTA, + COLOR_RED, + COLOR_BLUE, + COLOR_BLACK, + } + }, { + { + COLOR_WHITE, + COLOR_AMBAR, + COLOR_BLACK, + COLOR_WHITE, + COLOR_AMBAR, + COLOR_BLACK, + COLOR_WHITE, + COLOR_AMBAR, + } + }, { + { + COLOR_WHITE, + COLOR_CIAN, + COLOR_BLACK, + COLOR_WHITE, + COLOR_CIAN, + COLOR_BLACK, + COLOR_WHITE, + COLOR_CIAN, + } + }, { + { + COLOR_WHITE, + COLOR_GREEN, + COLOR_BLACK, + COLOR_WHITE, + COLOR_GREEN, + COLOR_BLACK, + COLOR_WHITE, + COLOR_GREEN, + } + }, }; +#define NUM_INPUTS ARRAY_SIZE(bars) + #define TO_Y(r, g, b) \ (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16) /* RGB to V(Cr) Color transform */ @@ -278,9 +336,10 @@ static u8 bars[8][3] = { #define TO_U(r, g, b) \ (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) -#define TSTAMP_MIN_Y 24 -#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 -#define TSTAMP_MIN_X 64 +#define TSTAMP_MIN_Y 24 +#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15) +#define TSTAMP_INPUT_X 10 +#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) { @@ -395,9 +454,29 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, pos += 4; /* only 16 bpp supported for now */ } - /* Checks if it is possible to show timestamp */ + /* Prints input entry number */ + + /* Checks if it is possible to input number */ if (TSTAMP_MAX_Y >= hmax) goto end; + + if (TSTAMP_INPUT_X + strlen(timestr) >= wmax) + goto end; + + if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) { + chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y]; + pos = TSTAMP_INPUT_X; + for (i = 0; i < 7; i++) { + /* Draw white font on black background */ + if (chr & 1 << (7 - i)) + gen_twopix(fh, basep + pos, WHITE); + else + gen_twopix(fh, basep + pos, BLACK); + pos += 2; + } + } + + /* Checks if it is possible to show timestamp */ if (TSTAMP_MIN_X + strlen(timestr) >= wmax) goto end; @@ -810,38 +889,19 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -/*FIXME: This seems to be generic enough to be at videodev2 */ -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) +/* precalculate color bar values to speed up rendering */ +static void precalculate_bars(struct vivi_fh *fh) { - struct vivi_fh *fh = priv; - struct videobuf_queue *q = &fh->vb_vidq; + struct vivi_dev *dev = fh->dev; unsigned char r, g, b; int k, is_yuv; - int ret = vidioc_try_fmt_vid_cap(file, fh, f); - if (ret < 0) - return (ret); - - mutex_lock(&q->vb_lock); - - if (videobuf_queue_is_busy(&fh->vb_vidq)) { - dprintk(fh->dev, 1, "%s queue busy\n", __func__); - ret = -EBUSY; - goto out; - } + fh->input = dev->input; - fh->fmt = get_format(f); - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vb_vidq.field = f->fmt.pix.field; - fh->type = f->type; - - /* precalculate color bar values to speed up rendering */ for (k = 0; k < 8; k++) { - r = bars[k][0]; - g = bars[k][1]; - b = bars[k][2]; + r = bars[fh->input].bar[k][0]; + g = bars[fh->input].bar[k][1]; + b = bars[fh->input].bar[k][2]; is_yuv = 0; switch (fh->fmt->fourcc) { @@ -874,11 +934,40 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, } } +} + +/*FIXME: This seems to be generic enough to be at videodev2 */ +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct vivi_fh *fh = priv; + struct videobuf_queue *q = &fh->vb_vidq; + + int ret = vidioc_try_fmt_vid_cap(file, fh, f); + if (ret < 0) + return ret; + + mutex_lock(&q->vb_lock); + + if (videobuf_queue_is_busy(&fh->vb_vidq)) { + dprintk(fh->dev, 1, "%s queue busy\n", __func__); + ret = -EBUSY; + goto out; + } + + fh->fmt = get_format(f); + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->vb_vidq.field = f->fmt.pix.field; + fh->type = f->type; + + precalculate_bars(fh); + ret = 0; out: mutex_unlock(&q->vb_lock); - return (ret); + return ret; } static int vidioc_reqbufs(struct file *file, void *priv, @@ -953,27 +1042,36 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp) { - if (inp->index != 0) + if (inp->index >= NUM_INPUTS) return -EINVAL; inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = V4L2_STD_525_60; - strcpy(inp->name, "Camera"); + sprintf(inp->name, "Camera %u", inp->index); return (0); } static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { - *i = 0; + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; + + *i = dev->input; return (0); } static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { - if (i > 0) + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; + + if (i >= NUM_INPUTS) return -EINVAL; + dev->input = i; + precalculate_bars(fh); + return (0); } -- cgit v1.2.3 From 73020b46e06d7107e869d9c03a18ef97e0ab52ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 11 Jan 2009 13:02:54 -0200 Subject: Convert to be a pci driver From: Trent Piepho This is a really old and crufty driver that wasn't using the long established pci driver framework. Priority: normal Signed-off-by: Trent Piepho Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran/zoran_card.c | 614 ++++++++++++------------- linux/drivers/media/video/zoran/zoran_card.h | 2 +- linux/drivers/media/video/zoran/zoran_driver.c | 2 +- 3 files changed, 305 insertions(+), 313 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index db8fd103d..84edad6a7 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -154,16 +154,13 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); MODULE_AUTHOR("Serguei Miridonov"); MODULE_LICENSE("GPL"); -#if (defined(CONFIG_VIDEO_ZORAN_MODULE) && defined(MODULE)) static struct pci_device_id zr36067_pci_tbl[] = { - {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_DEVICE(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057), }, {0} }; MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); -#endif -int zoran_num; /* number of Buzs in use */ +atomic_t zoran_num = ATOMIC_INIT(0); /* number of Buzs in use */ struct zoran *zoran[BUZ_MAX]; /* videocodec bus functions ZR36060 */ @@ -1147,7 +1144,7 @@ zr36057_init (struct zoran *zr) strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) - goto exit_unregister; + goto exit_free; zoran_init_hardware(zr); if (zr36067_debug > 2) @@ -1162,19 +1159,19 @@ zr36057_init (struct zoran *zr) zr->initialized = 1; return 0; -exit_unregister: - zoran_unregister_i2c(zr); exit_free: kfree(zr->stat_com); kfree(zr->video_dev); return err; } -static void -zoran_release (struct zoran *zr) +static void __devexit zoran_remove(struct pci_dev *pdev) { + struct zoran *zr = pci_get_drvdata(pdev); + if (!zr->initialized) goto exit_free; + /* unregister videocodec bus */ if (zr->codec) { struct videocodec_master *master = zr->codec->master_data; @@ -1203,6 +1200,7 @@ zoran_release (struct zoran *zr) pci_disable_device(zr->pci_dev); video_unregister_device(zr->video_dev); exit_free: + pci_set_drvdata(pdev, NULL); kfree(zr); } @@ -1265,323 +1263,330 @@ zoran_setup_videocodec (struct zoran *zr, * Scan for a Buz card (actually for the PCI controller ZR36057), * request the irq and map the io memory */ -static int __devinit -find_zr36057 (void) +static int __devinit zoran_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { unsigned char latency, need_latency; struct zoran *zr; - struct pci_dev *dev = NULL; int result; struct videocodec_master *master_vfe = NULL; struct videocodec_master *master_codec = NULL; int card_num; char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; + unsigned int nr; - zoran_num = 0; - while (zoran_num < BUZ_MAX && - (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) { - card_num = card[zoran_num]; - zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); - if (!zr) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - kzalloc failed\n", - ZORAN_NAME); - continue; - } - zr->pci_dev = dev; - //zr->zr36057_mem = NULL; - zr->id = zoran_num; - snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); - spin_lock_init(&zr->spinlock); - mutex_init(&zr->resource_lock); - if (pci_enable_device(dev)) - goto zr_free_mem; - zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); - pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, - &zr->revision); - if (zr->revision < 2) { - dprintk(1, - KERN_INFO - "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n", - ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, - zr->zr36057_adr); - - if (card_num == -1) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", - ZR_DEVNAME(zr)); - goto zr_free_mem; - } - } else { - int i; - unsigned short ss_vendor, ss_device; - ss_vendor = zr->pci_dev->subsystem_vendor; - ss_device = zr->pci_dev->subsystem_device; - dprintk(1, - KERN_INFO - "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n", - ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, - zr->zr36057_adr); - dprintk(1, - KERN_INFO - "%s: subsystem vendor=0x%04x id=0x%04x\n", - ZR_DEVNAME(zr), ss_vendor, ss_device); - if (card_num == -1) { - dprintk(3, - KERN_DEBUG - "%s: find_zr36057() - trying to autodetect card type\n", - ZR_DEVNAME(zr)); - for (i=0;i= BUZ_MAX) { + dev_err(&pdev->dev, "driver limited to %d card(s) maximum\n", BUZ_MAX); + return -ENOENT; + } - if (card_num < 0 || card_num >= NUM_CARDS) { - dprintk(2, - KERN_ERR - "%s: find_zr36057() - invalid cardnum %d\n", - ZR_DEVNAME(zr), card_num); - goto zr_free_mem; - } + card_num = card[nr]; + zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); + if (!zr) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - kzalloc failed\n", + ZORAN_NAME); + /* The entry in zoran[] gets leaked */ + return -ENOMEM; + } + zr->pci_dev = pdev; + zr->id = nr; + snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); + spin_lock_init(&zr->spinlock); + mutex_init(&zr->resource_lock); + if (pci_enable_device(pdev)) + goto zr_free_mem; + zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); + pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); + if (zr->revision < 2) { + dprintk(1, + KERN_INFO + "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n", + ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, + zr->zr36057_adr); - /* even though we make this a non pointer and thus - * theoretically allow for making changes to this struct - * on a per-individual card basis at runtime, this is - * strongly discouraged. This structure is intended to - * keep general card information, no settings or anything */ - zr->card = zoran_cards[card_num]; - snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), - "%s[%u]", zr->card.name, zr->id); - - zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000); - if (!zr->zr36057_mem) { + if (card_num == -1) { dprintk(1, KERN_ERR - "%s: find_zr36057() - ioremap failed\n", + "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", ZR_DEVNAME(zr)); goto zr_free_mem; } + } else { + int i; + unsigned short ss_vendor, ss_device; - result = request_irq(zr->pci_dev->irq, - zoran_irq, - IRQF_SHARED | IRQF_DISABLED, - ZR_DEVNAME(zr), - (void *) zr); - if (result < 0) { - if (result == -EINVAL) { + ss_vendor = zr->pci_dev->subsystem_vendor; + ss_device = zr->pci_dev->subsystem_device; + dprintk(1, + KERN_INFO + "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n", + ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, + zr->zr36057_adr); + dprintk(1, + KERN_INFO + "%s: subsystem vendor=0x%04x id=0x%04x\n", + ZR_DEVNAME(zr), ss_vendor, ss_device); + if (card_num == -1) { + dprintk(3, + KERN_DEBUG + "%s: find_zr36057() - trying to autodetect card type\n", + ZR_DEVNAME(zr)); + for (i=0;ipci_dev->irq); - } else { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - can't assign irq, error code %d\n", - ZR_DEVNAME(zr), result); + goto zr_free_mem; } - goto zr_unmap; } + } - /* set PCI latency timer */ - pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, - &latency); - need_latency = zr->revision > 1 ? 32 : 48; - if (latency != need_latency) { - dprintk(2, - KERN_INFO - "%s: Changing PCI latency from %d to %d.\n", - ZR_DEVNAME(zr), latency, need_latency); - pci_write_config_byte(zr->pci_dev, - PCI_LATENCY_TIMER, - need_latency); - } + if (card_num < 0 || card_num >= NUM_CARDS) { + dprintk(2, + KERN_ERR + "%s: find_zr36057() - invalid cardnum %d\n", + ZR_DEVNAME(zr), card_num); + goto zr_free_mem; + } - zr36057_restart(zr); - /* i2c */ - dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", + /* even though we make this a non pointer and thus + * theoretically allow for making changes to this struct + * on a per-individual card basis at runtime, this is + * strongly discouraged. This structure is intended to + * keep general card information, no settings or anything */ + zr->card = zoran_cards[card_num]; + snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), + "%s[%u]", zr->card.name, zr->id); + + zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000); + if (!zr->zr36057_mem) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - ioremap failed\n", ZR_DEVNAME(zr)); + goto zr_free_mem; + } - /* i2c decoder */ - if (decoder[zr->id] != -1) { - i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); - zr->card.i2c_decoder = decoder[zr->id]; - } else if (zr->card.i2c_decoder != 0) { - i2c_dec_name = - i2cid_to_modulename(zr->card.i2c_decoder); + result = request_irq(zr->pci_dev->irq, zoran_irq, + IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); + if (result < 0) { + if (result == -EINVAL) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - bad irq number or handler\n", + ZR_DEVNAME(zr)); + } else if (result == -EBUSY) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n", + ZR_DEVNAME(zr), zr->pci_dev->irq); } else { - i2c_dec_name = NULL; + dprintk(1, + KERN_ERR + "%s: find_zr36057() - can't assign irq, error code %d\n", + ZR_DEVNAME(zr), result); } + goto zr_unmap; + } - if (i2c_dec_name) { - if ((result = request_module(i2c_dec_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load module %s: %d\n", - ZR_DEVNAME(zr), i2c_dec_name, result); - } - } + /* set PCI latency timer */ + pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, + &latency); + need_latency = zr->revision > 1 ? 32 : 48; + if (latency != need_latency) { + dprintk(2, + KERN_INFO + "%s: Changing PCI latency from %d to %d\n", + ZR_DEVNAME(zr), latency, need_latency); + pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, + need_latency); + } - /* i2c encoder */ - if (encoder[zr->id] != -1) { - i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); - zr->card.i2c_encoder = encoder[zr->id]; - } else if (zr->card.i2c_encoder != 0) { - i2c_enc_name = - i2cid_to_modulename(zr->card.i2c_encoder); - } else { - i2c_enc_name = NULL; - } + zr36057_restart(zr); + /* i2c */ + dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", + ZR_DEVNAME(zr)); + + /* i2c decoder */ + if (decoder[zr->id] != -1) { + i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); + zr->card.i2c_decoder = decoder[zr->id]; + } else if (zr->card.i2c_decoder != 0) { + i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder); + } else { + i2c_dec_name = NULL; + } - if (i2c_enc_name) { - if ((result = request_module(i2c_enc_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load module %s: %d\n", - ZR_DEVNAME(zr), i2c_enc_name, result); - } + if (i2c_dec_name) { + if ((result = request_module(i2c_dec_name)) < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_dec_name, result); } + } + + /* i2c encoder */ + if (encoder[zr->id] != -1) { + i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); + zr->card.i2c_encoder = encoder[zr->id]; + } else if (zr->card.i2c_encoder != 0) { + i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder); + } else { + i2c_enc_name = NULL; + } - if (zoran_register_i2c(zr) < 0) { + if (i2c_enc_name) { + if ((result = request_module(i2c_enc_name)) < 0) { dprintk(1, KERN_ERR - "%s: find_zr36057() - can't initialize i2c bus\n", - ZR_DEVNAME(zr)); - goto zr_free_irq; + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_enc_name, result); } + } - dprintk(2, - KERN_INFO "%s: Initializing videocodec bus...\n", + if (zoran_register_i2c(zr) < 0) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - can't initialize i2c bus\n", ZR_DEVNAME(zr)); + goto zr_free_irq; + } - if (zr->card.video_codec != 0 && - (codec_name = - codecid_to_modulename(zr->card.video_codec)) != NULL) { - if ((result = request_module(codec_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load modules %s: %d\n", - ZR_DEVNAME(zr), codec_name, result); - } + dprintk(2, + KERN_INFO "%s: Initializing videocodec bus...\n", + ZR_DEVNAME(zr)); + + if (zr->card.video_codec != 0 && + (codec_name = codecid_to_modulename(zr->card.video_codec)) != NULL) { + if ((result = request_module(codec_name)) < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load modules %s: %d\n", + ZR_DEVNAME(zr), codec_name, result); } - if (zr->card.video_vfe != 0 && - (vfe_name = - codecid_to_modulename(zr->card.video_vfe)) != NULL) { - if ((result = request_module(vfe_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load modules %s: %d\n", - ZR_DEVNAME(zr), vfe_name, result); - } + } + if (zr->card.video_vfe != 0 && + (vfe_name = codecid_to_modulename(zr->card.video_vfe)) != NULL) { + if ((result = request_module(vfe_name)) < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load modules %s: %d\n", + ZR_DEVNAME(zr), vfe_name, result); } + } - /* reset JPEG codec */ - jpeg_codec_sleep(zr, 1); - jpeg_codec_reset(zr); - /* video bus enabled */ - /* display codec revision */ - if (zr->card.video_codec != 0) { - master_codec = zoran_setup_videocodec(zr, - zr->card.video_codec); - if (!master_codec) - goto zr_unreg_i2c; - zr->codec = videocodec_attach(master_codec); - if (!zr->codec) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - no codec found\n", - ZR_DEVNAME(zr)); - goto zr_free_codec; - } - if (zr->codec->type != zr->card.video_codec) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - wrong codec\n", - ZR_DEVNAME(zr)); - goto zr_detach_codec; - } + /* reset JPEG codec */ + jpeg_codec_sleep(zr, 1); + jpeg_codec_reset(zr); + /* video bus enabled */ + /* display codec revision */ + if (zr->card.video_codec != 0) { + master_codec = zoran_setup_videocodec(zr, zr->card.video_codec); + if (!master_codec) + goto zr_unreg_i2c; + zr->codec = videocodec_attach(master_codec); + if (!zr->codec) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - no codec found\n", + ZR_DEVNAME(zr)); + goto zr_free_codec; } - if (zr->card.video_vfe != 0) { - master_vfe = zoran_setup_videocodec(zr, - zr->card.video_vfe); - if (!master_vfe) - goto zr_detach_codec; - zr->vfe = videocodec_attach(master_vfe); - if (!zr->vfe) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - no VFE found\n", - ZR_DEVNAME(zr)); - goto zr_free_vfe; - } - if (zr->vfe->type != zr->card.video_vfe) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() = wrong VFE\n", - ZR_DEVNAME(zr)); - goto zr_detach_vfe; - } + if (zr->codec->type != zr->card.video_codec) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - wrong codec\n", + ZR_DEVNAME(zr)); + goto zr_detach_codec; + } + } + if (zr->card.video_vfe != 0) { + master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe); + if (!master_vfe) + goto zr_detach_codec; + zr->vfe = videocodec_attach(master_vfe); + if (!zr->vfe) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - no VFE found\n", + ZR_DEVNAME(zr)); + goto zr_free_vfe; + } + if (zr->vfe->type != zr->card.video_vfe) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() = wrong VFE\n", + ZR_DEVNAME(zr)); + goto zr_detach_vfe; } - /* Success so keep the pci_dev referenced */ - pci_dev_get(zr->pci_dev); - zoran[zoran_num++] = zr; - continue; - - // Init errors - zr_detach_vfe: - videocodec_detach(zr->vfe); - zr_free_vfe: - kfree(master_vfe); - zr_detach_codec: - videocodec_detach(zr->codec); - zr_free_codec: - kfree(master_codec); - zr_unreg_i2c: - zoran_unregister_i2c(zr); - zr_free_irq: - btwrite(0, ZR36057_SPGPPCR); - free_irq(zr->pci_dev->irq, zr); - zr_unmap: - iounmap(zr->zr36057_mem); - zr_free_mem: - kfree(zr); - continue; } - if (dev) /* Clean up ref count on early exit */ - pci_dev_put(dev); + zoran[nr] = zr; - if (zoran_num == 0) { - dprintk(1, KERN_INFO "No known MJPEG cards found.\n"); + /* take care of Natoma chipset and a revision 1 zr36057 */ + if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { + zr->jpg_buffers.need_contiguous = 1; + dprintk(1, + KERN_INFO + "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", + ZR_DEVNAME(zr)); } - return zoran_num; + + if (zr36057_init(zr) < 0) + goto zr_detach_vfe; + + zoran_proc_init(zr); + + pci_set_drvdata(pdev, zr); + + return 0; + + // Init errors + zr_detach_vfe: + videocodec_detach(zr->vfe); + zr_free_vfe: + kfree(master_vfe); + zr_detach_codec: + videocodec_detach(zr->codec); + zr_free_codec: + kfree(master_codec); + zr_unreg_i2c: + zoran_unregister_i2c(zr); + zr_free_irq: + btwrite(0, ZR36057_SPGPPCR); + free_irq(zr->pci_dev->irq, zr); + zr_unmap: + iounmap(zr->zr36057_mem); + zr_free_mem: + kfree(zr); + + return -ENODEV; } -static int __init -init_dc10_cards (void) +static struct pci_driver zoran_driver = { + .name = "zr36067", + .id_table = zr36067_pci_tbl, + .probe = zoran_probe, + .remove = zoran_remove, +}; + +static int __init zoran_init(void) { int i; @@ -1589,14 +1594,6 @@ init_dc10_cards (void) printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); - /* Look for cards */ - if (find_zr36057() < 0) { - return -EIO; - } - if (zoran_num == 0) - return -ENODEV; - dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME, - zoran_num); /* check the parameters we have been given, adjust if necessary */ if (v4l_nbufs < 2) v4l_nbufs = 2; @@ -1638,37 +1635,32 @@ init_dc10_cards (void) ZORAN_NAME); } - /* take care of Natoma chipset and a revision 1 zr36057 */ - for (i = 0; i < zoran_num; i++) { - struct zoran *zr = zoran[i]; - - if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { - zr->jpg_buffers.need_contiguous = 1; - dprintk(1, - KERN_INFO - "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", - ZR_DEVNAME(zr)); - } - - if (zr36057_init(zr) < 0) { - for (i = 0; i < zoran_num; i++) - zoran_release(zoran[i]); - return -EIO; - } - zoran_proc_init(zr); + i = pci_register_driver(&zoran_driver); + if (i) { + dprintk(1, + KERN_ERR + "%s: Unable to register ZR36057 driver\n", + ZORAN_NAME); + return i; } return 0; } -static void __exit -unload_dc10_cards (void) +static void __exit zoran_exit(void) { - int i; - - for (i = 0; i < zoran_num; i++) - zoran_release(zoran[i]); + pci_unregister_driver(&zoran_driver); } -module_init(init_dc10_cards); -module_exit(unload_dc10_cards); +module_init(zoran_init); +module_exit(zoran_exit); + +/* +todo: + use pci ioremap functions + + use id table to provide card type + + get rid of zoran[] array +*/ + diff --git a/linux/drivers/media/video/zoran/zoran_card.h b/linux/drivers/media/video/zoran/zoran_card.h index e4dc9d29b..c989448a7 100644 --- a/linux/drivers/media/video/zoran/zoran_card.h +++ b/linux/drivers/media/video/zoran/zoran_card.h @@ -40,7 +40,7 @@ extern int zr36067_debug; /* Anybody who uses more than four? */ #define BUZ_MAX 4 -extern int zoran_num; +extern atomic_t zoran_num; extern struct zoran *zoran[BUZ_MAX]; extern struct video_device zoran_template; diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index dffa2e96f..6803ca326 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -1271,7 +1271,7 @@ zoran_open(struct file *file) lock_kernel(); /* find the device */ - for (i = 0; i < zoran_num; i++) { + for (i = 0; i < atomic_read(&zoran_num); i++) { if (zoran[i]->video_dev->minor == minor) { zr = zoran[i]; break; -- cgit v1.2.3 From f6c316d761d2686a153d7de7a83118c35b7cb494 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 11 Jan 2009 13:04:30 -0200 Subject: zoran: Fix a few CodingStyle issues rised by the previous patch From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab CC: Jean Delvare CC: Trent Piepho --- linux/drivers/media/video/zoran/zoran_card.c | 67 +++++++++++++++++----------- 1 file changed, 41 insertions(+), 26 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 84edad6a7..925737e8f 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -1335,7 +1335,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_DEBUG "%s: find_zr36057() - trying to autodetect card type\n", ZR_DEVNAME(zr)); - for (i=0;icard.video_codec != 0 && - (codec_name = codecid_to_modulename(zr->card.video_codec)) != NULL) { - if ((result = request_module(codec_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load modules %s: %d\n", - ZR_DEVNAME(zr), codec_name, result); + if (zr->card.video_codec) { + codec_name = codecid_to_modulename(zr->card.video_codec); + if (codec_name) { + result = request_module(codec_name); + if (result) { + dprintk(1, + KERN_ERR + "%s: failed to load modules %s: %d\n", + ZR_DEVNAME(zr), codec_name, result); + } } } - if (zr->card.video_vfe != 0 && - (vfe_name = codecid_to_modulename(zr->card.video_vfe)) != NULL) { - if ((result = request_module(vfe_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load modules %s: %d\n", - ZR_DEVNAME(zr), vfe_name, result); + if (zr->card.video_vfe) { + vfe_name = codecid_to_modulename(zr->card.video_vfe); + if (vfe_name) { + result = request_module(vfe_name); + if (result < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load modules %s: %d\n", + ZR_DEVNAME(zr), vfe_name, result); + } } } @@ -1557,23 +1565,30 @@ static int __devinit zoran_probe(struct pci_dev *pdev, return 0; - // Init errors - zr_detach_vfe: + /* Init errors */ +zr_detach_vfe: videocodec_detach(zr->vfe); - zr_free_vfe: + +zr_free_vfe: kfree(master_vfe); - zr_detach_codec: + +zr_detach_codec: videocodec_detach(zr->codec); - zr_free_codec: + +zr_free_codec: kfree(master_codec); - zr_unreg_i2c: + +zr_unreg_i2c: zoran_unregister_i2c(zr); - zr_free_irq: + +zr_free_irq: btwrite(0, ZR36057_SPGPPCR); free_irq(zr->pci_dev->irq, zr); - zr_unmap: + +zr_unmap: iounmap(zr->zr36057_mem); - zr_free_mem: + +zr_free_mem: kfree(zr); return -ENODEV; -- cgit v1.2.3