fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / media / video / zr36050.c
index 688de95..a6bbd12 100644 (file)
@@ -26,7 +26,6 @@
 
 #define ZR050_VERSION "v0.7.1"
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -35,7 +34,7 @@
 #include <linux/types.h>
 #include <linux/wait.h>
 
-/* includes for structures and defines regarding video 
+/* includes for structures and defines regarding video
    #include<linux/videodev.h> */
 
 /* I/O commands, error codes */
@@ -58,7 +57,7 @@ static int zr36050_codecs = 0;
 /* debugging is available via module parameter */
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-4)");
 
 #define dprintk(num, format, args...) \
@@ -160,7 +159,7 @@ zr36050_wait_end (struct zr36050 *ptr)
 
        while (!(zr36050_read_status1(ptr) & 0x4)) {
                udelay(1);
-               if (i++ > 200000) {     // 200ms, there is for shure something wrong!!!
+               if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
                        dprintk(1,
                                "%s: timout at wait_end (last status: 0x%02x)\n",
                                ptr->name, ptr->status1);
@@ -172,7 +171,7 @@ zr36050_wait_end (struct zr36050 *ptr)
 /* =========================================================================
    Local helper function:
 
-   basic test of "connectivity", writes/reads to/from memory the SOF marker 
+   basic test of "connectivity", writes/reads to/from memory the SOF marker
    ========================================================================= */
 
 static int
@@ -219,9 +218,9 @@ zr36050_basic_test (struct zr36050 *ptr)
 
 static int
 zr36050_pushit (struct zr36050 *ptr,
-               u16             startreg,
-               u16             len,
-               const char     *data)
+               u16             startreg,
+               u16             len,
+               const char     *data)
 {
        int i = 0;
 
@@ -325,32 +324,6 @@ static const char zr36050_dht[0x1a4] = {
        0xF9, 0xFA
 };
 
-static const char zr36050_app[0x40] = {
-       0xff, 0xe0,             //Marker: APP0
-       0x00, 0x3e,             //Length: 60+2
-       ' ', 'A', 'V', 'I', '1', 0, 0, 0,       // 'AVI' field
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0
-};
-
-static const char zr36050_com[0x40] = {
-       0xff, 0xfe,             //Marker: COM
-       0x00, 0x3e,             //Length: 60+2
-       ' ', 'C', 'O', 'M', 0, 0, 0, 0, // 'COM' field
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0
-};
-
 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
 #define NO_OF_COMPONENTS          0x3  //Y,U,V
 #define BASELINE_PRECISION        0x8  //MCU size (?)
@@ -372,7 +345,7 @@ static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
 /* ------------------------------------------------------------------------- */
 
 /* SOF (start of frame) segment depends on width, height and sampling ratio
-                         of each color component */
+                        of each color component */
 
 static int
 zr36050_set_sof (struct zr36050 *ptr)
@@ -403,8 +376,8 @@ zr36050_set_sof (struct zr36050 *ptr)
 
 /* ------------------------------------------------------------------------- */
 
-/* SOS (start of scan) segment depends on the used scan components 
-                        of each color component */
+/* SOS (start of scan) segment depends on the used scan components
+                       of each color component */
 
 static int
 zr36050_set_sos (struct zr36050 *ptr)
@@ -445,7 +418,7 @@ zr36050_set_dri (struct zr36050 *ptr)
        dri_data[2] = 0x00;
        dri_data[3] = 0x04;
        dri_data[4] = ptr->dri >> 8;
-       dri_data[5] = ptr->dri * 0xff;
+       dri_data[5] = ptr->dri & 0xff;
        return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
 }
 
@@ -499,10 +472,18 @@ zr36050_init (struct zr36050 *ptr)
                                      sizeof(zr36050_dqt), zr36050_dqt);
                sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
                                      sizeof(zr36050_dht), zr36050_dht);
-               sum += zr36050_pushit(ptr, ZR050_APP_IDX,
-                                     sizeof(zr36050_app), zr36050_app);
-               sum += zr36050_pushit(ptr, ZR050_COM_IDX,
-                                     sizeof(zr36050_com), zr36050_com);
+               zr36050_write(ptr, ZR050_APP_IDX, 0xff);
+               zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
+               zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
+               zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
+               sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
+                                     ptr->app.data) + 4;
+               zr36050_write(ptr, ZR050_COM_IDX, 0xff);
+               zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
+               zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
+               zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
+               sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
+                                     ptr->com.data) + 4;
 
                /* do the internal huffman table preload */
                zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
@@ -553,8 +534,9 @@ zr36050_init (struct zr36050 *ptr)
 
                /* this headers seem to deliver "valid AVI" jpeg frames */
                zr36050_write(ptr, ZR050_MARKERS_EN,
-                             ZR050_ME_APP | ZR050_ME_DQT | ZR050_ME_DHT |
-                             ZR050_ME_COM);
+                             ZR050_ME_DQT | ZR050_ME_DHT |
+                             ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
+                             ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
        } else {
                dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
 
@@ -733,6 +715,47 @@ zr36050_control (struct videocodec *codec,
                        return -EFAULT;
                ptr->scalefact = *ival;
                break;
+
+       case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
+               struct jpeg_app_marker *app = data;
+
+               if (size != sizeof(struct jpeg_app_marker))
+                       return -EFAULT;
+
+               *app = ptr->app;
+               break;
+       }
+
+       case CODEC_S_JPEG_APP_DATA: {    /* set appn marker data */
+               struct jpeg_app_marker *app = data;
+
+               if (size != sizeof(struct jpeg_app_marker))
+                       return -EFAULT;
+
+               ptr->app = *app;
+               break;
+       }
+
+       case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
+               struct jpeg_com_marker *com = data;
+
+               if (size != sizeof(struct jpeg_com_marker))
+                       return -EFAULT;
+
+               *com = ptr->com;
+               break;
+       }
+
+       case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
+               struct jpeg_com_marker *com = data;
+
+               if (size != sizeof(struct jpeg_com_marker))
+                       return -EFAULT;
+
+               ptr->com = *com;
+               break;
+       }
+
        default:
                return -EINVAL;
        }
@@ -790,12 +813,11 @@ zr36050_setup (struct videocodec *codec)
                return -ENOSPC;
        }
        //mem structure init
-       codec->data = ptr = kmalloc(sizeof(struct zr36050), GFP_KERNEL);
+       codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL);
        if (NULL == ptr) {
                dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
                return -ENOMEM;
        }
-       memset(ptr, 0, sizeof(struct zr36050));
 
        snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
                 zr36050_codecs);
@@ -821,6 +843,12 @@ zr36050_setup (struct videocodec *codec)
        ptr->max_block_vol = 240;
        ptr->scalefact = 0x100;
        ptr->dri = 1;
+
+       /* no app/com marker by default */
+       ptr->app.appn = 0;
+       ptr->app.len = 0;
+       ptr->com.len = 0;
+
        zr36050_init(ptr);
 
        dprintk(1, KERN_INFO "%s: codec attached and running\n",