Commit 66aa66ea authored by Trent Piepho's avatar Trent Piepho Committed by Mauro Carvalho Chehab

V4L/DVB (10212): Convert to be a pci driver

This is a really old and crufty driver that wasn't using the long
established pci driver framework.
Signed-off-by: default avatarTrent Piepho <xyzzy@speakeasy.org>
Acked-by: default avatarJean Delvare <khali@linux-fr.org>
[mchehab@redhat.com: Cleaned up a few CodingStyle issues]
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent f90c3c0b
...@@ -153,16 +153,13 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); ...@@ -153,16 +153,13 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
MODULE_AUTHOR("Serguei Miridonov"); MODULE_AUTHOR("Serguei Miridonov");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#if (defined(CONFIG_VIDEO_ZORAN_MODULE) && defined(MODULE))
static struct pci_device_id zr36067_pci_tbl[] = { static struct pci_device_id zr36067_pci_tbl[] = {
{PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, { PCI_DEVICE(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057), },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0} {0}
}; };
MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); 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]; struct zoran *zoran[BUZ_MAX];
/* videocodec bus functions ZR36060 */ /* videocodec bus functions ZR36060 */
...@@ -1146,7 +1143,7 @@ zr36057_init (struct zoran *zr) ...@@ -1146,7 +1143,7 @@ zr36057_init (struct zoran *zr)
strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0) if (err < 0)
goto exit_unregister; goto exit_free;
zoran_init_hardware(zr); zoran_init_hardware(zr);
if (zr36067_debug > 2) if (zr36067_debug > 2)
...@@ -1161,19 +1158,19 @@ zr36057_init (struct zoran *zr) ...@@ -1161,19 +1158,19 @@ zr36057_init (struct zoran *zr)
zr->initialized = 1; zr->initialized = 1;
return 0; return 0;
exit_unregister:
zoran_unregister_i2c(zr);
exit_free: exit_free:
kfree(zr->stat_com); kfree(zr->stat_com);
kfree(zr->video_dev); kfree(zr->video_dev);
return err; return err;
} }
static void static void __devexit zoran_remove(struct pci_dev *pdev)
zoran_release (struct zoran *zr)
{ {
struct zoran *zr = pci_get_drvdata(pdev);
if (!zr->initialized) if (!zr->initialized)
goto exit_free; goto exit_free;
/* unregister videocodec bus */ /* unregister videocodec bus */
if (zr->codec) { if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data; struct videocodec_master *master = zr->codec->master_data;
...@@ -1202,6 +1199,7 @@ zoran_release (struct zoran *zr) ...@@ -1202,6 +1199,7 @@ zoran_release (struct zoran *zr)
pci_disable_device(zr->pci_dev); pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev); video_unregister_device(zr->video_dev);
exit_free: exit_free:
pci_set_drvdata(pdev, NULL);
kfree(zr); kfree(zr);
} }
...@@ -1264,41 +1262,47 @@ zoran_setup_videocodec (struct zoran *zr, ...@@ -1264,41 +1262,47 @@ zoran_setup_videocodec (struct zoran *zr,
* Scan for a Buz card (actually for the PCI controller ZR36057), * Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory * request the irq and map the io memory
*/ */
static int __devinit static int __devinit zoran_probe(struct pci_dev *pdev,
find_zr36057 (void) const struct pci_device_id *ent)
{ {
unsigned char latency, need_latency; unsigned char latency, need_latency;
struct zoran *zr; struct zoran *zr;
struct pci_dev *dev = NULL;
int result; int result;
struct videocodec_master *master_vfe = NULL; struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL; struct videocodec_master *master_codec = NULL;
int card_num; int card_num;
char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
unsigned int nr;
zoran_num = 0;
while (zoran_num < BUZ_MAX && nr = atomic_inc_return(&zoran_num) - 1;
(dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) { if (nr >= BUZ_MAX) {
card_num = card[zoran_num]; dprintk(1,
KERN_ERR
"%s: driver limited to %d card(s) maximum\n",
ZORAN_NAME, BUZ_MAX);
return -ENOENT;
}
card_num = card[nr];
zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
if (!zr) { if (!zr) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: find_zr36057() - kzalloc failed\n", "%s: find_zr36057() - kzalloc failed\n",
ZORAN_NAME); ZORAN_NAME);
continue; /* The entry in zoran[] gets leaked */
return -ENOMEM;
} }
zr->pci_dev = dev; zr->pci_dev = pdev;
//zr->zr36057_mem = NULL; zr->id = nr;
zr->id = zoran_num;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock); spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock); mutex_init(&zr->resource_lock);
if (pci_enable_device(dev)) if (pci_enable_device(pdev))
goto zr_free_mem; goto zr_free_mem;
zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
&zr->revision);
if (zr->revision < 2) { if (zr->revision < 2) {
dprintk(1, dprintk(1,
KERN_INFO KERN_INFO
...@@ -1333,7 +1337,7 @@ find_zr36057 (void) ...@@ -1333,7 +1337,7 @@ find_zr36057 (void)
KERN_DEBUG KERN_DEBUG
"%s: find_zr36057() - trying to autodetect card type\n", "%s: find_zr36057() - trying to autodetect card type\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
for (i=0;i<NUM_CARDS;i++) { for (i = 0; i < NUM_CARDS; i++) {
if (ss_vendor == zoran_cards[i].vendor_id && if (ss_vendor == zoran_cards[i].vendor_id &&
ss_device == zoran_cards[i].device_id) { ss_device == zoran_cards[i].device_id) {
dprintk(3, dprintk(3,
...@@ -1381,11 +1385,8 @@ find_zr36057 (void) ...@@ -1381,11 +1385,8 @@ find_zr36057 (void)
goto zr_free_mem; goto zr_free_mem;
} }
result = request_irq(zr->pci_dev->irq, result = request_irq(zr->pci_dev->irq, zoran_irq,
zoran_irq, IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
IRQF_SHARED | IRQF_DISABLED,
ZR_DEVNAME(zr),
(void *) zr);
if (result < 0) { if (result < 0) {
if (result == -EINVAL) { if (result == -EINVAL) {
dprintk(1, dprintk(1,
...@@ -1413,10 +1414,9 @@ find_zr36057 (void) ...@@ -1413,10 +1414,9 @@ find_zr36057 (void)
if (latency != need_latency) { if (latency != need_latency) {
dprintk(2, dprintk(2,
KERN_INFO KERN_INFO
"%s: Changing PCI latency from %d to %d.\n", "%s: Changing PCI latency from %d to %d\n",
ZR_DEVNAME(zr), latency, need_latency); ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev, pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
PCI_LATENCY_TIMER,
need_latency); need_latency);
} }
...@@ -1430,14 +1430,14 @@ find_zr36057 (void) ...@@ -1430,14 +1430,14 @@ find_zr36057 (void)
i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
zr->card.i2c_decoder = decoder[zr->id]; zr->card.i2c_decoder = decoder[zr->id];
} else if (zr->card.i2c_decoder != 0) { } else if (zr->card.i2c_decoder != 0) {
i2c_dec_name = i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
i2cid_to_modulename(zr->card.i2c_decoder);
} else { } else {
i2c_dec_name = NULL; i2c_dec_name = NULL;
} }
if (i2c_dec_name) { if (i2c_dec_name) {
if ((result = request_module(i2c_dec_name)) < 0) { result = request_module(i2c_dec_name);
if (result < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: failed to load module %s: %d\n", "%s: failed to load module %s: %d\n",
...@@ -1450,14 +1450,14 @@ find_zr36057 (void) ...@@ -1450,14 +1450,14 @@ find_zr36057 (void)
i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
zr->card.i2c_encoder = encoder[zr->id]; zr->card.i2c_encoder = encoder[zr->id];
} else if (zr->card.i2c_encoder != 0) { } else if (zr->card.i2c_encoder != 0) {
i2c_enc_name = i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
i2cid_to_modulename(zr->card.i2c_encoder);
} else { } else {
i2c_enc_name = NULL; i2c_enc_name = NULL;
} }
if (i2c_enc_name) { if (i2c_enc_name) {
if ((result = request_module(i2c_enc_name)) < 0) { result = request_module(i2c_enc_name);
if (result < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: failed to load module %s: %d\n", "%s: failed to load module %s: %d\n",
...@@ -1477,26 +1477,30 @@ find_zr36057 (void) ...@@ -1477,26 +1477,30 @@ find_zr36057 (void)
KERN_INFO "%s: Initializing videocodec bus...\n", KERN_INFO "%s: Initializing videocodec bus...\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
if (zr->card.video_codec != 0 && if (zr->card.video_codec) {
(codec_name = codec_name = codecid_to_modulename(zr->card.video_codec);
codecid_to_modulename(zr->card.video_codec)) != NULL) { if (codec_name) {
if ((result = request_module(codec_name)) < 0) { result = request_module(codec_name);
if (result) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: failed to load modules %s: %d\n", "%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), codec_name, result); ZR_DEVNAME(zr), codec_name, result);
} }
} }
if (zr->card.video_vfe != 0 && }
(vfe_name = if (zr->card.video_vfe) {
codecid_to_modulename(zr->card.video_vfe)) != NULL) { vfe_name = codecid_to_modulename(zr->card.video_vfe);
if ((result = request_module(vfe_name)) < 0) { if (vfe_name) {
result = request_module(vfe_name);
if (result < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: failed to load modules %s: %d\n", "%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), vfe_name, result); ZR_DEVNAME(zr), vfe_name, result);
} }
} }
}
/* reset JPEG codec */ /* reset JPEG codec */
jpeg_codec_sleep(zr, 1); jpeg_codec_sleep(zr, 1);
...@@ -1504,8 +1508,7 @@ find_zr36057 (void) ...@@ -1504,8 +1508,7 @@ find_zr36057 (void)
/* video bus enabled */ /* video bus enabled */
/* display codec revision */ /* display codec revision */
if (zr->card.video_codec != 0) { if (zr->card.video_codec != 0) {
master_codec = zoran_setup_videocodec(zr, master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
zr->card.video_codec);
if (!master_codec) if (!master_codec)
goto zr_unreg_i2c; goto zr_unreg_i2c;
zr->codec = videocodec_attach(master_codec); zr->codec = videocodec_attach(master_codec);
...@@ -1525,8 +1528,7 @@ find_zr36057 (void) ...@@ -1525,8 +1528,7 @@ find_zr36057 (void)
} }
} }
if (zr->card.video_vfe != 0) { if (zr->card.video_vfe != 0) {
master_vfe = zoran_setup_videocodec(zr, master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
zr->card.video_vfe);
if (!master_vfe) if (!master_vfe)
goto zr_detach_codec; goto zr_detach_codec;
zr->vfe = videocodec_attach(master_vfe); zr->vfe = videocodec_attach(master_vfe);
...@@ -1545,57 +1547,62 @@ find_zr36057 (void) ...@@ -1545,57 +1547,62 @@ find_zr36057 (void)
goto zr_detach_vfe; goto zr_detach_vfe;
} }
} }
/* Success so keep the pci_dev referenced */ zoran[nr] = zr;
pci_dev_get(zr->pci_dev);
zoran[zoran_num++] = zr; /* take care of Natoma chipset and a revision 1 zr36057 */
continue; 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));
}
// Init errors if (zr36057_init(zr) < 0)
zr_detach_vfe: goto zr_detach_vfe;
zoran_proc_init(zr);
pci_set_drvdata(pdev, zr);
return 0;
zr_detach_vfe:
videocodec_detach(zr->vfe); videocodec_detach(zr->vfe);
zr_free_vfe: zr_free_vfe:
kfree(master_vfe); kfree(master_vfe);
zr_detach_codec: zr_detach_codec:
videocodec_detach(zr->codec); videocodec_detach(zr->codec);
zr_free_codec: zr_free_codec:
kfree(master_codec); kfree(master_codec);
zr_unreg_i2c: zr_unreg_i2c:
zoran_unregister_i2c(zr); zoran_unregister_i2c(zr);
zr_free_irq: zr_free_irq:
btwrite(0, ZR36057_SPGPPCR); btwrite(0, ZR36057_SPGPPCR);
free_irq(zr->pci_dev->irq, zr); free_irq(zr->pci_dev->irq, zr);
zr_unmap: zr_unmap:
iounmap(zr->zr36057_mem); iounmap(zr->zr36057_mem);
zr_free_mem: zr_free_mem:
kfree(zr); kfree(zr);
continue;
}
if (dev) /* Clean up ref count on early exit */
pci_dev_put(dev);
if (zoran_num == 0) { return -ENODEV;
dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
}
return zoran_num;
} }
static int __init static struct pci_driver zoran_driver = {
init_dc10_cards (void) .name = "zr36067",
.id_table = zr36067_pci_tbl,
.probe = zoran_probe,
.remove = zoran_remove,
};
static int __init zoran_init(void)
{ {
int i; int res;
memset(zoran, 0, sizeof(zoran)); memset(zoran, 0, sizeof(zoran));
printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); 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 */ /* check the parameters we have been given, adjust if necessary */
if (v4l_nbufs < 2) if (v4l_nbufs < 2)
v4l_nbufs = 2; v4l_nbufs = 2;
...@@ -1637,37 +1644,22 @@ init_dc10_cards (void) ...@@ -1637,37 +1644,22 @@ init_dc10_cards (void)
ZORAN_NAME); ZORAN_NAME);
} }
/* take care of Natoma chipset and a revision 1 zr36057 */ res = pci_register_driver(&zoran_driver);
for (i = 0; i < zoran_num; i++) { if (res) {
struct zoran *zr = zoran[i];
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
dprintk(1, dprintk(1,
KERN_INFO KERN_ERR
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n", "%s: Unable to register ZR36057 driver\n",
ZR_DEVNAME(zr)); ZORAN_NAME);
} return res;
if (zr36057_init(zr) < 0) {
for (i = 0; i < zoran_num; i++)
zoran_release(zoran[i]);
return -EIO;
}
zoran_proc_init(zr);
} }
return 0; return 0;
} }
static void __exit static void __exit zoran_exit(void)
unload_dc10_cards (void)
{ {
int i; pci_unregister_driver(&zoran_driver);
for (i = 0; i < zoran_num; i++)
zoran_release(zoran[i]);
} }
module_init(init_dc10_cards); module_init(zoran_init);
module_exit(unload_dc10_cards); module_exit(zoran_exit);
...@@ -40,7 +40,7 @@ extern int zr36067_debug; ...@@ -40,7 +40,7 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */ /* Anybody who uses more than four? */
#define BUZ_MAX 4 #define BUZ_MAX 4
extern int zoran_num; extern atomic_t zoran_num;
extern struct zoran *zoran[BUZ_MAX]; extern struct zoran *zoran[BUZ_MAX];
extern struct video_device zoran_template; extern struct video_device zoran_template;
......
...@@ -1206,7 +1206,7 @@ zoran_open(struct file *file) ...@@ -1206,7 +1206,7 @@ zoran_open(struct file *file)
lock_kernel(); lock_kernel();
/* find the device */ /* 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) { if (zoran[i]->video_dev->minor == minor) {
zr = zoran[i]; zr = zoran[i];
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment