X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fsaa5246a.c;h=c2fb64d57ca79974d46cbdc1155b68cfc32a3548;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=eecc102dbeb717417269be5b79cb712a8445e6e0;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index eecc102db..c2fb64d57 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -1,9 +1,10 @@ /* - * Driver for the SAA5246A videotext decoder chip from Philips. + * Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from + * Philips. * - * Only capturing of videotext pages is tested. The SAA5246A chip also has - * a TV output but my hardware doesn't use it. For this reason this driver - * does not support changing any TV display settings. + * Only capturing of Teletext pages is tested. The videotext chips also have a + * TV output but my hardware doesn't use it. For this reason this driver does + * not support changing any TV display settings. * * Copyright (C) 2004 Michael Geng * @@ -47,6 +48,10 @@ #include #include "saa5246a.h" +MODULE_AUTHOR("Michael Geng "); +MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver"); +MODULE_LICENSE("GPL"); + struct saa5246a_device { u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; @@ -480,73 +485,76 @@ static inline int saa5246a_get_status(struct saa5246a_device *t, static inline int saa5246a_get_page(struct saa5246a_device *t, vtx_pagereq_t *req) { - int start, end; + int start, end, size; + char *buf; + int err; if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE) return -EINVAL; - /* Read "normal" part of page */ - end = min(req->end, VTX_PAGESIZE - 1); - if (i2c_senddata(t, SAA5246A_REGISTER_R8, - req->pgbuf | - R8_DO_NOT_CLEAR_MEMORY, + buf = kmalloc(VTX_PAGESIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; - ROW(req->start), + /* Read "normal" part of page */ + err = -EIO; - COLUMN(req->start), + end = min(req->end, VTX_PAGESIZE - 1); + if (i2c_senddata(t, SAA5246A_REGISTER_R8, + req->pgbuf | R8_DO_NOT_CLEAR_MEMORY, + ROW(req->start), COLUMN(req->start), COMMAND_END)) + goto out; + if (i2c_getdata(t, end - req->start + 1, buf)) + goto out; + err = -EFAULT; + if (copy_to_user(req->buffer, buf, end - req->start + 1)) + goto out; - COMMAND_END) || - i2c_getdata(t, end - req->start + 1, req->buffer)) - { - return -EIO; - } /* Always get the time from buffer 4, since this stupid SAA5246A only * updates the currently displayed buffer... */ - if (REQ_CONTAINS_TIME(req)) - { + if (REQ_CONTAINS_TIME(req)) { start = max(req->start, POS_TIME_START); end = min(req->end, POS_TIME_END); + size = end - start + 1; + err = -EINVAL; + if (size < 0) + goto out; + err = -EIO; if (i2c_senddata(t, SAA5246A_REGISTER_R8, - - R8_ACTIVE_CHAPTER_4 | - R8_DO_NOT_CLEAR_MEMORY, - - R9_CURSER_ROW_0, - - start, - - COMMAND_END) || - i2c_getdata(t, end - start + 1, - req->buffer + start - req->start)) - { - return -EIO; - } + R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY, + R9_CURSER_ROW_0, start, COMMAND_END)) + goto out; + if (i2c_getdata(t, size, buf)) + goto out; + err = -EFAULT; + if (copy_to_user(req->buffer + start - req->start, buf, size)) + goto out; } /* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */ - if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) - { + if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) { start = max(req->start, POS_HEADER_START); end = min(req->end, POS_HEADER_END); + size = end - start + 1; + err = -EINVAL; + if (size < 0) + goto out; + err = -EIO; if (i2c_senddata(t, SAA5246A_REGISTER_R8, - - R8_ACTIVE_CHAPTER_4 | - R8_DO_NOT_CLEAR_MEMORY, - - R9_CURSER_ROW_0, - - start, - - COMMAND_END) || - i2c_getdata(t, end - start + 1, - req->buffer + start - req->start)) - { - return -EIO; - } + R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY, + R9_CURSER_ROW_0, start, COMMAND_END)) + goto out; + if (i2c_getdata(t, end - start + 1, buf)) + goto out; + err = -EFAULT; + if (copy_to_user(req->buffer + start - req->start, buf, size)) + goto out; } - - return 0; + err = 0; +out: + kfree(buf); + return err; } /* Stops the acquisition circuit given in dau_no. The page buffer associated @@ -764,8 +772,8 @@ static int saa5246a_release(struct inode *inode, struct file *file) static int __init init_saa_5246a (void) { - printk(KERN_INFO "SAA5246A driver (" IF_NAME - " interface) for VideoText version %d.%d\n", + printk(KERN_INFO + "SAA5246A (or compatible) Teletext decoder driver version %d.%d\n", MAJOR_VERSION, MINOR_VERSION); return i2c_add_driver(&i2c_driver_videotext); } @@ -796,5 +804,3 @@ static struct video_device saa_template = .release = video_device_release, .minor = -1, }; - -MODULE_LICENSE("GPL");