Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / media / video / saa7134 / saa6752hs.c
index 1db0226..0e0ba50 100644 (file)
@@ -9,11 +9,11 @@
 #include <linux/poll.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 
-#include <media/id.h>
 
 #define MPEG_VIDEO_TARGET_BITRATE_MAX  27000
 #define MPEG_VIDEO_MAX_BITRATE_MAX     27000
@@ -22,7 +22,6 @@
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
@@ -42,22 +41,23 @@ enum saa6752hs_videoformat {
 
 static const struct v4l2_format v4l2_format_table[] =
 {
-       [SAA6752HS_VF_D1] = {
-               .fmt = { .pix = { .width = 720, .height = 576 }, }, },
-       [SAA6752HS_VF_2_3_D1] = {
-               .fmt = { .pix = { .width = 480, .height = 576 }, }, },
-       [SAA6752HS_VF_1_2_D1] = {
-               .fmt = { .pix = { .width = 352, .height = 576 }, }, },
-       [SAA6752HS_VF_SIF] = {
-               .fmt = { .pix = { .width = 352, .height = 288 }, }, },
-       [SAA6752HS_VF_UNKNOWN] = {
-               .fmt = { .pix = { .width = 0, .height = 0 }, }, },
+       [SAA6752HS_VF_D1] =
+               { .fmt = { .pix = { .width = 720, .height = 576 }}},
+       [SAA6752HS_VF_2_3_D1] =
+               { .fmt = { .pix = { .width = 480, .height = 576 }}},
+       [SAA6752HS_VF_1_2_D1] =
+               { .fmt = { .pix = { .width = 352, .height = 576 }}},
+       [SAA6752HS_VF_SIF] =
+               { .fmt = { .pix = { .width = 352, .height = 288 }}},
+       [SAA6752HS_VF_UNKNOWN] =
+               { .fmt = { .pix = { .width = 0, .height = 0}}},
 };
 
 struct saa6752hs_state {
        struct i2c_client             client;
        struct v4l2_mpeg_compression  params;
        enum saa6752hs_videoformat    video_format;
+       v4l2_std_id                   standard;
 };
 
 enum saa6752hs_command {
@@ -75,58 +75,58 @@ enum saa6752hs_command {
 /* ---------------------------------------------------------------------- */
 
 static u8 PAT[] = {
-       0xc2, // i2c register
-       0x00, // table number for encoder
+       0xc2, /* i2c register */
+       0x00, /* table number for encoder */
 
-       0x47, // sync
-       0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0)
-       0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
+       0x47, /* sync */
+       0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
+       0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
 
-       0x00, // PSI pointer to start of table
+       0x00, /* PSI pointer to start of table */
 
-       0x00, // tid(0)
-       0xb0, 0x0d, // section_syntax_indicator(1), section_length(13)
+       0x00, /* tid(0) */
+       0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
 
-       0x00, 0x01, // transport_stream_id(1)
+       0x00, 0x01, /* transport_stream_id(1) */
 
-       0xc1, // version_number(0), current_next_indicator(1)
+       0xc1, /* version_number(0), current_next_indicator(1) */
 
-       0x00, 0x00, // section_number(0), last_section_number(0)
+       0x00, 0x00, /* section_number(0), last_section_number(0) */
 
-       0x00, 0x01, // program_number(1)
+       0x00, 0x01, /* program_number(1) */
 
-       0xe0, 0x00, // PMT PID
+       0xe0, 0x00, /* PMT PID */
 
-       0x00, 0x00, 0x00, 0x00 // CRC32
+       0x00, 0x00, 0x00, 0x00 /* CRC32 */
 };
 
 static u8 PMT[] = {
-       0xc2, // i2c register
-       0x01, // table number for encoder
+       0xc2, /* i2c register */
+       0x01, /* table number for encoder */
 
-       0x47, // sync
-       0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid
-       0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
+       0x47, /* sync */
+       0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
+       0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
 
-       0x00, // PSI pointer to start of table
+       0x00, /* PSI pointer to start of table */
 
-       0x02, // tid(2)
-       0xb0, 0x17, // section_syntax_indicator(1), section_length(23)
+       0x02, /* tid(2) */
+       0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
 
-       0x00, 0x01, // program_number(1)
+       0x00, 0x01, /* program_number(1) */
 
-       0xc1, // version_number(0), current_next_indicator(1)
+       0xc1, /* version_number(0), current_next_indicator(1) */
 
-       0x00, 0x00, // section_number(0), last_section_number(0)
+       0x00, 0x00, /* section_number(0), last_section_number(0) */
 
-       0xe0, 0x00, // PCR_PID
+       0xe0, 0x00, /* PCR_PID */
 
-       0xf0, 0x00, // program_info_length(0)
+       0xf0, 0x00, /* program_info_length(0) */
 
-       0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid
-       0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid
+       0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
+       0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
 
-       0x00, 0x00, 0x00, 0x00 // CRC32
+       0x00, 0x00, 0x00, 0x00 /* CRC32 */
 };
 
 static struct v4l2_mpeg_compression param_defaults =
@@ -156,10 +156,6 @@ static struct v4l2_mpeg_compression param_defaults =
                .target  = 256,
        },
 
-#if 0
-       /* FIXME: size? via S_FMT? */
-       .video_format = MPEG_VIDEO_FORMAT_D1,
-#endif
 };
 
 /* ---------------------------------------------------------------------- */
@@ -171,33 +167,33 @@ static int saa6752hs_chip_command(struct i2c_client* client,
        unsigned long timeout;
        int status = 0;
 
-       // execute the command
+       /* execute the command */
        switch(command) {
-       case SAA6752HS_COMMAND_RESET:
-               buf[0] = 0x00;
+       case SAA6752HS_COMMAND_RESET:
+               buf[0] = 0x00;
                break;
 
        case SAA6752HS_COMMAND_STOP:
-               buf[0] = 0x03;
+               buf[0] = 0x03;
                break;
 
        case SAA6752HS_COMMAND_START:
-               buf[0] = 0x02;
+               buf[0] = 0x02;
                break;
 
        case SAA6752HS_COMMAND_PAUSE:
-               buf[0] = 0x04;
+               buf[0] = 0x04;
                break;
 
        case SAA6752HS_COMMAND_RECONFIGURE:
                buf[0] = 0x05;
                break;
 
-       case SAA6752HS_COMMAND_SLEEP:
-               buf[0] = 0x06;
+       case SAA6752HS_COMMAND_SLEEP:
+               buf[0] = 0x06;
                break;
 
-       case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
+       case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
                buf[0] = 0x07;
                break;
 
@@ -205,13 +201,13 @@ static int saa6752hs_chip_command(struct i2c_client* client,
                return -EINVAL;
        }
 
-       // set it and wait for it to be so
+       /* set it and wait for it to be so */
        i2c_master_send(client, buf, 1);
        timeout = jiffies + HZ * 3;
        for (;;) {
-               // get the current status
+               /* get the current status */
                buf[0] = 0x10;
-               i2c_master_send(client, buf, 1);
+               i2c_master_send(client, buf, 1);
                i2c_master_recv(client, buf, 1);
 
                if (!(buf[0] & 0x20))
@@ -221,61 +217,58 @@ static int saa6752hs_chip_command(struct i2c_client* client,
                        break;
                }
 
-               // wait a bit
                msleep(10);
        }
 
-       // delay a bit to let encoder settle
+       /* delay a bit to let encoder settle */
        msleep(50);
 
-       // done
-       return status;
+       return status;
 }
 
 
 static int saa6752hs_set_bitrate(struct i2c_client* client,
                                 struct v4l2_mpeg_compression* params)
 {
-       u8 buf[3];
+       u8 buf[3];
 
-       // set the bitrate mode
+       /* set the bitrate mode */
        buf[0] = 0x71;
        buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
        i2c_master_send(client, buf, 2);
 
-       // set the video bitrate
+       /* set the video bitrate */
        if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
-               // set the target bitrate
+               /* set the target bitrate */
                buf[0] = 0x80;
                buf[1] = params->vi_bitrate.target >> 8;
-               buf[2] = params->vi_bitrate.target & 0xff;
+               buf[2] = params->vi_bitrate.target & 0xff;
                i2c_master_send(client, buf, 3);
 
-               // set the max bitrate
+               /* set the max bitrate */
                buf[0] = 0x81;
                buf[1] = params->vi_bitrate.max >> 8;
-               buf[2] = params->vi_bitrate.max & 0xff;
+               buf[2] = params->vi_bitrate.max & 0xff;
                i2c_master_send(client, buf, 3);
        } else {
-               // set the target bitrate (no max bitrate for CBR)
-               buf[0] = 0x81;
+               /* set the target bitrate (no max bitrate for CBR) */
+               buf[0] = 0x81;
                buf[1] = params->vi_bitrate.target >> 8;
-               buf[2] = params->vi_bitrate.target & 0xff;
+               buf[2] = params->vi_bitrate.target & 0xff;
                i2c_master_send(client, buf, 3);
        }
 
-       // set the audio bitrate
-       buf[0] = 0x94;
+       /* set the audio bitrate */
+       buf[0] = 0x94;
        buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
        i2c_master_send(client, buf, 2);
 
-       // set the total bitrate
+       /* set the total bitrate */
        buf[0] = 0xb1;
-       buf[1] = params->st_bitrate.target >> 8;
-       buf[2] = params->st_bitrate.target & 0xff;
+       buf[1] = params->st_bitrate.target >> 8;
+       buf[2] = params->st_bitrate.target & 0xff;
        i2c_master_send(client, buf, 3);
 
-       // return success
        return 0;
 }
 
@@ -381,36 +374,43 @@ static int saa6752hs_init(struct i2c_client* client)
 
        h = i2c_get_clientdata(client);
 
-       // Set video format - must be done first as it resets other settings
+       /* Set video format - must be done first as it resets other settings */
        buf[0] = 0x41;
        buf[1] = h->video_format;
        i2c_master_send(client, buf, 2);
 
-        // set bitrate
-        saa6752hs_set_bitrate(client, &h->params);
+       /* Set number of lines in input signal */
+       buf[0] = 0x40;
+       buf[1] = 0x00;
+       if (h->standard & V4L2_STD_525_60)
+               buf[1] = 0x01;
+       i2c_master_send(client, buf, 2);
+
+       /* set bitrate */
+       saa6752hs_set_bitrate(client, &h->params);
 
-       // Set GOP structure {3, 13}
+       /* Set GOP structure {3, 13} */
        buf[0] = 0x72;
        buf[1] = 0x03;
        buf[2] = 0x0D;
        i2c_master_send(client,buf,3);
 
-       // Set minimum Q-scale {4}
+       /* Set minimum Q-scale {4} */
        buf[0] = 0x82;
        buf[1] = 0x04;
        i2c_master_send(client,buf,2);
 
-       // Set maximum Q-scale {12}
+       /* Set maximum Q-scale {12} */
        buf[0] = 0x83;
        buf[1] = 0x0C;
        i2c_master_send(client,buf,2);
 
-       // Set Output Protocol
+       /* Set Output Protocol */
        buf[0] = 0xD0;
        buf[1] = 0x81;
        i2c_master_send(client,buf,2);
 
-       // Set video output stream format {TS}
+       /* Set video output stream format {TS} */
        buf[0] = 0xB0;
        buf[1] = 0x05;
        i2c_master_send(client,buf,2);
@@ -426,9 +426,9 @@ static int saa6752hs_init(struct i2c_client* client)
        localPAT[sizeof(PAT) - 1] = crc & 0xFF;
 
        /* compute PMT */
-       memcpy(localPMT, PMT, sizeof(PMT));
-       localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
-       localPMT[4] = h->params.ts_pid_pmt & 0xff;
+       memcpy(localPMT, PMT, sizeof(PMT));
+       localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
+       localPMT[4] = h->params.ts_pid_pmt & 0xff;
        localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
        localPMT[16] = h->params.ts_pid_pcr & 0xFF;
        localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
@@ -441,39 +441,39 @@ static int saa6752hs_init(struct i2c_client* client)
        localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
        localPMT[sizeof(PMT) - 1] = crc & 0xFF;
 
-       // Set Audio PID
+       /* Set Audio PID */
        buf[0] = 0xC1;
        buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
        buf[2] = h->params.ts_pid_audio & 0xFF;
        i2c_master_send(client,buf,3);
 
-       // Set Video PID
+       /* Set Video PID */
        buf[0] = 0xC0;
        buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
        buf[2] = h->params.ts_pid_video & 0xFF;
        i2c_master_send(client,buf,3);
 
-       // Set PCR PID
+       /* Set PCR PID */
        buf[0] = 0xC4;
        buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
        buf[2] = h->params.ts_pid_pcr & 0xFF;
        i2c_master_send(client,buf,3);
 
-       // Send SI tables
+       /* Send SI tables */
        i2c_master_send(client,localPAT,sizeof(PAT));
        i2c_master_send(client,localPMT,sizeof(PMT));
 
-       // mute then unmute audio. This removes buzzing artefacts
+       /* mute then unmute audio. This removes buzzing artefacts */
        buf[0] = 0xa4;
        buf[1] = 1;
        i2c_master_send(client, buf, 2);
-       buf[1] = 0;
+       buf[1] = 0;
        i2c_master_send(client, buf, 2);
 
-       // start it going
+       /* start it going */
        saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
 
-       // readout current state
+       /* readout current state */
        buf[0] = 0xE1;
        buf[1] = 0xA7;
        buf[2] = 0xFE;
@@ -482,7 +482,7 @@ static int saa6752hs_init(struct i2c_client* client)
        i2c_master_send(client, buf, 5);
        i2c_master_recv(client, buf2, 4);
 
-       // change aspect ratio
+       /* change aspect ratio */
        buf[0] = 0xE0;
        buf[1] = 0xA7;
        buf[2] = 0xFE;
@@ -503,7 +503,6 @@ static int saa6752hs_init(struct i2c_client* client)
        buf[8] = buf2[3];
        i2c_master_send(client, buf, 9);
 
-       // return success
        return 0;
 }
 
@@ -511,18 +510,22 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
 {
        struct saa6752hs_state *h;
 
-        printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
 
-        if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
-                return -ENOMEM;
-       memset(h,0,sizeof(*h));
+       if (NULL == (h = kzalloc(sizeof(*h), GFP_KERNEL)))
+               return -ENOMEM;
        h->client = client_template;
        h->params = param_defaults;
        h->client.adapter = adap;
        h->client.addr = addr;
 
+       /* Assume 625 input lines */
+       h->standard = 0;
+
        i2c_set_clientdata(&h->client, h);
-        i2c_attach_client(&h->client);
+       i2c_attach_client(&h->client);
+
+       v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1);
+
        return 0;
 }
 
@@ -550,7 +553,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
        struct v4l2_mpeg_compression *params = arg;
        int err = 0;
 
-        switch (cmd) {
+       switch (cmd) {
        case VIDIOC_S_MPEGCOMP:
                if (NULL == params) {
                        /* apply settings and start encoder */
@@ -564,7 +567,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
                break;
        case VIDIOC_G_FMT:
        {
-           struct v4l2_format *f = arg;
+          struct v4l2_format *f = arg;
 
           if (h->video_format == SAA6752HS_VF_UNKNOWN)
                   h->video_format = SAA6752HS_VF_D1;
@@ -581,6 +584,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
                saa6752hs_set_subsampling(client, f);
                break;
        }
+       case VIDIOC_S_STD:
+               h->standard = *((v4l2_std_id *) arg);
+               break;
        default:
                /* nothing */
                break;
@@ -592,20 +598,19 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-       .owner          = THIS_MODULE,
-        .name           = "i2c saa6752hs MPEG encoder",
-        .id             = I2C_DRIVERID_SAA6752HS,
-        .flags          = I2C_DF_NOTIFY,
-        .attach_adapter = saa6752hs_probe,
-        .detach_client  = saa6752hs_detach,
-        .command        = saa6752hs_command,
+       .driver = {
+               .name   = "saa6752hs",
+       },
+       .id             = I2C_DRIVERID_SAA6752HS,
+       .attach_adapter = saa6752hs_probe,
+       .detach_client  = saa6752hs_detach,
+       .command        = saa6752hs_command,
 };
 
 static struct i2c_client client_template =
 {
-       I2C_DEVNAME("saa6752hs"),
-       .flags      = I2C_CLIENT_ALLOW_USE,
-        .driver     = &driver,
+       .name       = "saa6752hs",
+       .driver     = &driver,
 };
 
 static int __init saa6752hs_init_module(void)