V4L/DVB (4958): Fix namespace conflict between w9968cf.c on MIPS
[safe/jmp/linux-2.6] / drivers / media / video / saa7115.c
index 900c657..c2374ed 100644 (file)
@@ -48,6 +48,8 @@
 #include <media/saa7115.h>
 #include <asm/div64.h>
 
+#define VRES_60HZ      (480+16)
+
 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
 MODULE_AUTHOR(  "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
                "Hans Verkuil, Mauro Carvalho Chehab");
@@ -66,7 +68,7 @@ static unsigned short normal_i2c[] = {
 
 I2C_CLIENT_INSMOD;
 
-struct saa7115_state {
+struct saa711x_state {
        v4l2_std_id std;
        int input;
        int enable;
@@ -75,6 +77,8 @@ struct saa7115_state {
        int contrast;
        int hue;
        int sat;
+       int width;
+       int height;
        enum v4l2_chip_ident ident;
        u32 audclk_freq;
        u32 crystal_freq;
@@ -85,7 +89,7 @@ struct saa7115_state {
 
 /* ----------------------------------------------------------------------- */
 
-static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value)
 {
        return i2c_smbus_write_byte_data(client, reg, value);
 }
@@ -93,43 +97,38 @@ static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
 /* Sanity routine to check if a register is present */
 static int saa711x_has_reg(const int id, const u8 reg)
 {
+       if (id == V4L2_IDENT_SAA7111)
+               return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
+                      (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
+
+       /* common for saa7113/4/5/8 */
+       if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
+           reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
+           reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
+           reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
+               return 0;
+
        switch (id) {
-       case V4L2_IDENT_SAA7111:
-               if (reg>0x1f || reg==1 || reg==0x0f || reg==0x14 || reg==0x18
-                                      || reg==0x19 || reg==0x1d || reg==0x1e)
-                       return 0;
        case V4L2_IDENT_SAA7113:
-               if (reg>0x62 || reg==0x14 || (reg>=0x18 && reg<=0x1e) ||
-                                   (reg>=0x20 && reg<=0x3f) ||reg==0x5f )
-                       return 0;
+               return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
+                      reg != 0x5d && reg < 0x63;
        case V4L2_IDENT_SAA7114:
-               if (reg>=0xf0 || (reg>=0x1a && reg<=0x1e) ||
-                                 (reg>=0x20 && reg<=0x2f) ||
-                                 (reg>=0x63 && reg<=0x7f) )
-                       return 0;
+               return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
+                      (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
+                      reg != 0x81 && reg < 0xf0;
        case V4L2_IDENT_SAA7115:
-               if ((reg>=0x20 && reg<=0x2f) || (reg==0x5c) ||
-                               (reg>=0xfc && reg<=0xfe) )
-                       return 0;
+               return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
        case V4L2_IDENT_SAA7118:
-               if (reg>=0xf0 || (reg>=0x1a && reg<=0x1d) ||
-                                       (reg>=0x63 && reg<=0x6f) )
-                       return 0;
+               return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
+                      (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
+                      (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
        }
-
-       /* Those registers are reserved for all family */
-       if (unlikely((reg>=0x20 && reg<=0x22) ||
-                       (reg>=0x26 && reg<=0x28) ||
-                       (reg>=0x3b && reg<=0x3f) || (reg==0x5f) ||
-                       (reg>=0x63 && reg<=0x6f) ) )
-               return 0;
-
        return 1;
 }
 
-static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
+static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        unsigned char reg, data;
 
        while (*regs != 0x00) {
@@ -139,14 +138,16 @@ static int saa7115_writeregs(struct i2c_client *client, const unsigned char *reg
                /* According with datasheets, reserved regs should be
                   filled with 0 - seems better not to touch on they */
                if (saa711x_has_reg(state->ident,reg)) {
-                       if (saa7115_write(client, reg, data) < 0)
+                       if (saa711x_write(client, reg, data) < 0)
                                return -1;
+               } else {
+                       v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg);
                }
        }
        return 0;
 }
 
-static inline int saa7115_read(struct i2c_client *client, u8 reg)
+static inline int saa711x_read(struct i2c_client *client, u8 reg)
 {
        return i2c_smbus_read_byte_data(client, reg);
 }
@@ -154,7 +155,7 @@ static inline int saa7115_read(struct i2c_client *client, u8 reg)
 /* ----------------------------------------------------------------------- */
 
 /* SAA7111 initialization table */
-static const unsigned char saa7111_init_auto_input[] = {
+static const unsigned char saa7111_init[] = {
        R_01_INC_DELAY, 0x00,           /* reserved */
 
        /*front end */
@@ -194,7 +195,7 @@ static const unsigned char saa7111_init_auto_input[] = {
 };
 
 /* SAA7113 init codes */
-static const unsigned char saa7113_init_auto_input[] = {
+static const unsigned char saa7113_init[] = {
        R_01_INC_DELAY, 0x08,
        R_02_INPUT_CNTL_1, 0xc2,
        R_03_INPUT_CNTL_2, 0x30,
@@ -236,6 +237,7 @@ static const unsigned char saa7115_init_auto_input[] = {
                /* Decoder Part */
        R_06_H_SYNC_START, 0xeb,                /* horiz sync begin = -21 */
        R_07_H_SYNC_STOP, 0xe0,                 /* horiz sync stop = -17 */
+       R_09_LUMA_CNTL, 0x53,                   /* 0x53, was 0x56 for 60hz. luminance control */
        R_0A_LUMA_BRIGHT_CNTL, 0x80,            /* was 0x88. decoder brightness, 0x80 is itu standard */
        R_0B_LUMA_CONTRAST_CNTL, 0x44,          /* was 0x48. decoder contrast, 0x44 is itu standard */
        R_0C_CHROMA_SAT_CNTL, 0x40,             /* was 0x47. decoder saturation, 0x40 is itu standard */
@@ -253,6 +255,9 @@ static const unsigned char saa7115_init_auto_input[] = {
        R_1C_ENHAN_COMB_CTRL1, 0xa9,            /* recommended value */
        R_1D_ENHAN_COMB_CTRL2, 0x01,            /* recommended value */
 
+
+       R_80_GLOBAL_CNTL_1, 0x0,                /* No tasks enabled at init */
+
                /* Power Device Control */
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,    /* reset device */
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,    /* set device programmed, all in operational mode */
@@ -270,44 +275,6 @@ static const unsigned char saa7115_cfg_reset_scaler[] = {
 
 /* ============== SAA7715 VIDEO templates =============  */
 
-/* Used on saa7114 and saa7115 */
-static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
-       /* hsize = 0x2d0 = 720 */
-       R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
-       R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
-
-       /* Why not in 60hz-Land, too? */
-       R_D0_B_HORIZ_PRESCALING, 0x01,          /* downscale = 1 */
-       /* hor lum scaling 0x0400 = 1 */
-       R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
-       R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
-
-       /* must be hor lum scaling / 2 */
-       R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
-       R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
-
-       0x00, 0x00
-};
-
-/* Used on saa7114 and saa7115 */
-static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
-       /* output window size = 248 (but 60hz is 240?) */
-       R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0xf8,
-       R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
-
-       /* Why not in 60hz-Land, too? */
-       R_D5_B_LUMA_CONTRAST_CNTL, 0x40,                /* Lum contrast, nominal value = 0x40 */
-       R_D6_B_CHROMA_SATURATION_CNTL, 0x40,            /* Chroma satur. nominal value = 0x80 */
-
-       R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
-       R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
-
-       R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
-       R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
-
-       0x00, 0x00
-};
-
 static const unsigned char saa7115_cfg_60hz_video[] = {
        R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
@@ -366,8 +333,8 @@ static const unsigned char saa7115_cfg_60hz_video[] = {
        R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
 
        /* vwindow length 0xf8 = 248 */
-       R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0xf8,
-       R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
+       R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
+       R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
 
        /* hwindow 0x02d0 = 720 */
        R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
@@ -378,43 +345,6 @@ static const unsigned char saa7115_cfg_60hz_video[] = {
        R_F5_PULSGEN_LINE_LENGTH, 0xad,
        R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
 
-       R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,    /* Disable I-port output */
-       R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
-       R_80_GLOBAL_CNTL_1, 0x20,                       /* Activate only task "B", continuous mode (was 0xA0) */
-       R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
-       R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
-       0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
-       /* hsize low (output), 720 same as 60hz */
-       R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
-       R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
-
-       R_D0_B_HORIZ_PRESCALING, 0x01,          /* down scale = 1 */
-       R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,    /* hor lum scaling 0x0400 = 1 */
-       R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
-
-       /* must be hor lum scaling / 2 */
-       R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
-       R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
-
-       0x00, 0x00
-};
-static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
-       /* vsize low (output), 0x0120 = 288 */
-       R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0x20,
-       R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x01,
-
-       R_D5_B_LUMA_CONTRAST_CNTL, 0x40,        /* Lum contrast, nominal value = 0x40 */
-       R_D6_B_CHROMA_SATURATION_CNTL, 0x40,    /* Chroma satur. nominal value = 0x80 */
-
-       R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
-       R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
-
-       R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
-       R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
-
        0x00, 0x00
 };
 
@@ -488,21 +418,11 @@ static const unsigned char saa7115_cfg_50hz_video[] = {
        R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
        R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
 
-       /* vsize 0x0120 = 288 */
-       R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0x20,
-       R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x01,
-
        R_F0_LFCO_PER_LINE, 0xb0,               /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
        R_F1_P_I_PARAM_SELECT, 0x05,            /* low bit with 0xF0, (was 0x05) */
        R_F5_PULSGEN_LINE_LENGTH, 0xb0,
        R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
 
-       R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,    /* Disable I-port output */
-       R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler (was 0xD0) */
-       R_80_GLOBAL_CNTL_1, 0x20,                       /* Activate only task "B" */
-       R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
-       R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
-
        0x00, 0x00
 };
 
@@ -531,7 +451,6 @@ static const unsigned char saa7115_cfg_vbi_off[] = {
 
 static const unsigned char saa7115_init_misc[] = {
        R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
-       0x82, 0x00,             /* Reserved register - value should be zero*/
        R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
        R_84_I_PORT_SIGNAL_DEF, 0x20,
        R_85_I_PORT_SIGNAL_POLAR, 0x21,
@@ -664,7 +583,6 @@ static const unsigned char saa7115_init_misc[] = {
        R_5E_SDID, 0x35,
 
        R_02_INPUT_CNTL_1, 0x84,                /* input tuner -> input 4, amplifier active */
-       R_09_LUMA_CNTL, 0x53,                   /* 0x53, was 0x56 for 60hz. luminance control */
 
        R_80_GLOBAL_CNTL_1, 0x20,               /* enable task B */
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
@@ -672,7 +590,7 @@ static const unsigned char saa7115_init_misc[] = {
        0x00, 0x00
 };
 
-static int saa7115_odd_parity(u8 c)
+static int saa711x_odd_parity(u8 c)
 {
        c ^= (c >> 4);
        c ^= (c >> 2);
@@ -681,7 +599,7 @@ static int saa7115_odd_parity(u8 c)
        return c & 1;
 }
 
-static int saa7115_decode_vps(u8 * dst, u8 * p)
+static int saa711x_decode_vps(u8 * dst, u8 * p)
 {
        static const u8 biphase_tbl[] = {
                0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
@@ -728,7 +646,7 @@ static int saa7115_decode_vps(u8 * dst, u8 * p)
        return err & 0xf0;
 }
 
-static int saa7115_decode_wss(u8 * p)
+static int saa711x_decode_wss(u8 * p)
 {
        static const int wss_bits[8] = {
                0, 0, 0, 1, 0, 1, 1, 1
@@ -755,9 +673,9 @@ static int saa7115_decode_wss(u8 * p)
        return wss;
 }
 
-static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
+static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        u32 acpf;
        u32 acni;
        u32 hz;
@@ -795,26 +713,26 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
        if (state->apll)
                acc |= 0x08;
 
-       saa7115_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
-       saa7115_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
-       saa7115_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
+       saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
+       saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
+       saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
 
-       saa7115_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
-       saa7115_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
+       saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
+       saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
                                                        (acpf >> 8) & 0xff);
-       saa7115_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
+       saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
                                                        (acpf >> 16) & 0x03);
 
-       saa7115_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
-       saa7115_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
-       saa7115_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
+       saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
+       saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
+       saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
        state->audclk_freq = freq;
        return 0;
 }
 
-static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
 
        switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
@@ -824,7 +742,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
                }
 
                state->bright = ctrl->value;
-               saa7115_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
+               saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
                break;
 
        case V4L2_CID_CONTRAST:
@@ -834,7 +752,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
                }
 
                state->contrast = ctrl->value;
-               saa7115_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
+               saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
                break;
 
        case V4L2_CID_SATURATION:
@@ -844,7 +762,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
                }
 
                state->sat = ctrl->value;
-               saa7115_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
+               saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
                break;
 
        case V4L2_CID_HUE:
@@ -854,7 +772,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
                }
 
                state->hue = ctrl->value;
-               saa7115_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
+               saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
                break;
 
        default:
@@ -864,9 +782,9 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
        return 0;
 }
 
-static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
 
        switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
@@ -888,9 +806,115 @@ static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *c
        return 0;
 }
 
-static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+static int saa711x_set_size(struct i2c_client *client, int width, int height)
+{
+       struct saa711x_state *state = i2c_get_clientdata(client);
+       int HPSC, HFSC;
+       int VSCY;
+       int res;
+       int is_50hz = state->std & V4L2_STD_625_50;
+       int Vsrc = is_50hz ? 576 : 480;
+
+       v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height);
+
+       /* FIXME need better bounds checking here */
+       if ((width < 1) || (width > 1440))
+               return -EINVAL;
+       if ((height < 1) || (height > Vsrc))
+               return -EINVAL;
+
+       if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
+               /* Decoder only supports 720 columns and 480 or 576 lines */
+               if (width != 720)
+                       return -EINVAL;
+               if (height != Vsrc)
+                       return -EINVAL;
+       }
+
+       state->width = width;
+       state->height = height;
+
+       if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
+               return 0;
+
+       /* probably have a valid size, let's set it */
+       /* Set output width/height */
+       /* width */
+
+       saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
+                                       (u8) (width & 0xff));
+       saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
+                                       (u8) ((width >> 8) & 0xff));
+
+       /* Vertical Scaling uses height/2 */
+       res=height/2;
+
+       /* On 60Hz, it is using a higher Vertical Output Size */
+       if (!is_50hz)
+               res += (VRES_60HZ - 480) >> 1;
+
+               /* height */
+       saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
+                                       (u8) (res & 0xff));
+       saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
+                                       (u8) ((res >> 8) & 0xff));
+
+       /* Scaling settings */
+       /* Hprescaler is floor(inres/outres) */
+       HPSC = (int)(720 / width);
+       /* 0 is not allowed (div. by zero) */
+       HPSC = HPSC ? HPSC : 1;
+       HFSC = (int)((1024 * 720) / (HPSC * width));
+       /* FIXME hardcodes to "Task B"
+        * write H prescaler integer */
+       saa711x_write(client, R_D0_B_HORIZ_PRESCALING,
+                               (u8) (HPSC & 0x3f));
+
+       v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
+       /* write H fine-scaling (luminance) */
+       saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
+                               (u8) (HFSC & 0xff));
+       saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
+                               (u8) ((HFSC >> 8) & 0xff));
+       /* write H fine-scaling (chrominance)
+        * must be lum/2, so i'll just bitshift :) */
+       saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
+                               (u8) ((HFSC >> 1) & 0xff));
+       saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
+                               (u8) ((HFSC >> 9) & 0xff));
+
+       VSCY = (int)((1024 * Vsrc) / height);
+       v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
+
+       /* Correct Contrast and Luminance */
+       saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
+                                       (u8) (64 * 1024 / VSCY));
+       saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
+                                       (u8) (64 * 1024 / VSCY));
+
+               /* write V fine-scaling (luminance) */
+       saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
+                                       (u8) (VSCY & 0xff));
+       saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
+                                       (u8) ((VSCY >> 8) & 0xff));
+               /* write V fine-scaling (chrominance) */
+       saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
+                                       (u8) (VSCY & 0xff));
+       saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
+                                       (u8) ((VSCY >> 8) & 0xff));
+
+       saa711x_writeregs(client, saa7115_cfg_reset_scaler);
+
+       /* Activates task "B" */
+       saa711x_write(client, R_80_GLOBAL_CNTL_1,
+                               saa711x_read(client,R_80_GLOBAL_CNTL_1) | 0x20);
+
+       return 0;
+}
+
+static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
 
        /* Prevent unnecessary standard changes. During a standard
           change the I-Port is temporarily disabled. Any devices
@@ -902,13 +926,17 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
        if (std == state->std)
                return;
 
+       state->std = std;
+
        // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
        if (std & V4L2_STD_525_60) {
                v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
-               saa7115_writeregs(client, saa7115_cfg_60hz_video);
+               saa711x_writeregs(client, saa7115_cfg_60hz_video);
+               saa711x_set_size(client, 720, 480);
        } else {
                v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
-               saa7115_writeregs(client, saa7115_cfg_50hz_video);
+               saa711x_writeregs(client, saa7115_cfg_50hz_video);
+               saa711x_set_size(client, 720, 576);
        }
 
        /* Register 0E - Bits D6-D4 on NO-AUTO mode
@@ -922,7 +950,7 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
        */
        if (state->ident == V4L2_IDENT_SAA7111 ||
            state->ident == V4L2_IDENT_SAA7113) {
-               u8 reg = saa7115_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
+               u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
 
                if (std == V4L2_STD_PAL_M) {
                        reg |= 0x30;
@@ -932,33 +960,33 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
                        reg |= 0x10;
                } else if (std == V4L2_STD_NTSC_M_JP) {
                        reg |= 0x40;
+               } else if (std == V4L2_STD_SECAM) {
+                       reg |= 0x50;
                }
-               saa7115_write(client, R_0E_CHROMA_CNTL_1, reg);
+               saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
        } else {
                /* restart task B if needed */
-               int taskb = saa7115_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
+               int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
 
                if (taskb && state->ident == V4L2_IDENT_SAA7114) {
-                       saa7115_writeregs(client, saa7115_cfg_vbi_on);
+                       saa711x_writeregs(client, saa7115_cfg_vbi_on);
                }
 
                /* switch audio mode too! */
-               saa7115_set_audio_clock_freq(client, state->audclk_freq);
+               saa711x_set_audio_clock_freq(client, state->audclk_freq);
        }
-
-       state->std = std;
 }
 
-static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
+static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
 
        return state->std;
 }
 
-static void saa7115_log_status(struct i2c_client *client)
+static void saa711x_log_status(struct i2c_client *client)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        int reg1e, reg1f;
        int signalOk;
        int vcr;
@@ -966,7 +994,7 @@ static void saa7115_log_status(struct i2c_client *client)
        v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
        if (state->ident != V4L2_IDENT_SAA7115) {
                /* status for the saa7114 */
-               reg1f = saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
+               reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
                signalOk = (reg1f & 0xc1) == 0x81;
                v4l_info(client, "Video signal:    %s\n", signalOk ? "ok" : "bad");
                v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
@@ -974,8 +1002,8 @@ static void saa7115_log_status(struct i2c_client *client)
        }
 
        /* status for the saa7115 */
-       reg1e = saa7115_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
-       reg1f = saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
+       reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
+       reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
 
        signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
        vcr = !(reg1f & 0x10);
@@ -1002,12 +1030,13 @@ static void saa7115_log_status(struct i2c_client *client)
                        v4l_info(client, "Detected format: BW/No color\n");
                        break;
        }
+       v4l_info(client, "Width, Height:   %d, %d\n", state->width, state->height);
 }
 
 /* setup the sliced VBI lcr registers according to the sliced VBI format */
-static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
+static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        int is_50hz = (state->std & V4L2_STD_625_50);
        u8 lcr[24];
        int i, x;
@@ -1078,16 +1107,16 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
 
        /* write the lcr registers */
        for (i = 2; i <= 23; i++) {
-               saa7115_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
+               saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
        }
 
        /* enable/disable raw VBI capturing */
-       saa7115_writeregs(client, fmt->service_set == 0 ?
+       saa711x_writeregs(client, fmt->service_set == 0 ?
                                saa7115_cfg_vbi_on :
                                saa7115_cfg_vbi_off);
 }
 
-static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
 {
        static u16 lcr2vbi[] = {
                0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
@@ -1103,10 +1132,10 @@ static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
                return -EINVAL;
        memset(sliced, 0, sizeof(*sliced));
        /* done if using raw VBI */
-       if (saa7115_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
+       if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
                return 0;
        for (i = 2; i <= 23; i++) {
-               u8 v = saa7115_read(client, i - 2 + R_41_LCR_BASE);
+               u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE);
 
                sliced->service_lines[0][i] = lcr2vbi[v >> 4];
                sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -1116,125 +1145,16 @@ static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
        return 0;
 }
 
-static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
-       struct v4l2_pix_format *pix;
-       int HPSC, HFSC;
-       int VSCY;
-       int is_50hz = state->std & V4L2_STD_625_50;
-       int Vsrc = is_50hz ? 576 : 480;
-
        if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
-               saa7115_set_lcr(client, &fmt->fmt.sliced);
+               saa711x_set_lcr(client, &fmt->fmt.sliced);
                return 0;
        }
        if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
 
-       pix = &(fmt->fmt.pix);
-
-       v4l_dbg(1, debug, client, "decoder set size\n");
-
-       /* FIXME need better bounds checking here */
-       if ((pix->width < 1) || (pix->width > 1440))
-               return -EINVAL;
-       if ((pix->height < 1) || (pix->height > 960))
-               return -EINVAL;
-
-       if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
-               /* Decoder only supports 720 columns and 480 or 576 lines */
-               if (pix->width != 720)
-                       return -EINVAL;
-               if (pix->height != Vsrc)
-                       return -EINVAL;
-       }
-
-       /* probably have a valid size, let's set it */
-       /* Set output width/height */
-       /* width */
-
-       if (!saa711x_has_reg(state->ident,R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH)) {
-               saa7115_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
-                                       (u8) (pix->width & 0xff));
-               saa7115_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
-                                       (u8) ((pix->width >> 8) & 0xff));
-               /* height */
-               saa7115_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
-                                       (u8) (pix->height & 0xff));
-               saa7115_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
-                                       (u8) ((pix->height >> 8) & 0xff));
-       }
-
-       /* Scaling settings */
-       /* Hprescaler is floor(inres/outres) */
-       /* FIXME hardcoding input res */
-       if (pix->width != 720) {
-               HPSC = (int)(720 / pix->width);
-               /* 0 is not allowed (div. by zero) */
-               HPSC = HPSC ? HPSC : 1;
-               HFSC = (int)((1024 * 720) / (HPSC * pix->width));
-
-               v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
-               /* FIXME hardcodes to "Task B"
-                * write H prescaler integer */
-               saa7115_write(client, R_D0_B_HORIZ_PRESCALING,
-                                       (u8) (HPSC & 0x3f));
-
-               /* write H fine-scaling (luminance) */
-               saa7115_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
-                                       (u8) (HFSC & 0xff));
-               saa7115_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
-                                       (u8) ((HFSC >> 8) & 0xff));
-               /* write H fine-scaling (chrominance)
-                * must be lum/2, so i'll just bitshift :) */
-               saa7115_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
-                                       (u8) ((HFSC >> 1) & 0xff));
-               saa7115_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
-                                       (u8) ((HFSC >> 9) & 0xff));
-       } else {
-               if (is_50hz) {
-                       v4l_dbg(1, debug, client, "Setting full 50hz width\n");
-                       saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
-               } else {
-                       v4l_dbg(1, debug, client, "Setting full 60hz width\n");
-                       saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
-               }
-       }
-
-       if (pix->height != Vsrc) {
-               VSCY = (int)((1024 * Vsrc) / pix->height);
-               v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
-
-               /* Correct Contrast and Luminance */
-               saa7115_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
-                                       (u8) (64 * 1024 / VSCY));
-               saa7115_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
-                                       (u8) (64 * 1024 / VSCY));
-
-               /* write V fine-scaling (luminance) */
-               saa7115_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
-                                       (u8) (VSCY & 0xff));
-               saa7115_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
-                                       (u8) ((VSCY >> 8) & 0xff));
-               /* write V fine-scaling (chrominance) */
-               saa7115_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
-                                       (u8) (VSCY & 0xff));
-               saa7115_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
-                                       (u8) ((VSCY >> 8) & 0xff));
-       } else {
-               if (is_50hz) {
-                       v4l_dbg(1, debug, client, "Setting full 50Hz height\n");
-                       saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
-               } else {
-                       v4l_dbg(1, debug, client, "Setting full 60hz height\n");
-                       saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
-               }
-       }
-
-       saa7115_writeregs(client, saa7115_cfg_reset_scaler);
-
-       return 0;
+       return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height);
 }
 
 /* Decode the sliced VBI data stream as created by the saa7115.
@@ -1243,13 +1163,13 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
    The current implementation uses SAV/EAV codes and not the ancillary data
    headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
    code. */
-static void saa7115_decode_vbi_line(struct i2c_client *client,
+static void saa711x_decode_vbi_line(struct i2c_client *client,
                                    struct v4l2_decode_vbi_line *vbi)
 {
        static const char vbi_no_data_pattern[] = {
                0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
        };
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        u8 *p = vbi->p;
        u32 wss;
        int id1, id2;   /* the ID1 and ID2 bytes from the internal header */
@@ -1284,12 +1204,12 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
                vbi->type = V4L2_SLICED_TELETEXT_B;
                break;
        case 4:
-               if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
+               if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
                        return;
                vbi->type = V4L2_SLICED_CAPTION_525;
                break;
        case 5:
-               wss = saa7115_decode_wss(p);
+               wss = saa711x_decode_wss(p);
                if (wss == -1)
                        return;
                p[0] = wss & 0xff;
@@ -1297,7 +1217,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
                vbi->type = V4L2_SLICED_WSS_625;
                break;
        case 7:
-               if (saa7115_decode_vps(p, p) != 0)
+               if (saa711x_decode_vps(p, p) != 0)
                        return;
                vbi->type = V4L2_SLICED_VPS;
                break;
@@ -1308,21 +1228,21 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
 
 /* ============ SAA7115 AUDIO settings (end) ============= */
 
-static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        int *iarg = arg;
 
        /* ioctls to allow direct access to the saa7115 registers for testing */
        switch (cmd) {
        case VIDIOC_S_FMT:
-               return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
+               return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
 
        case VIDIOC_G_FMT:
-               return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
+               return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg);
 
        case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-               return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
+               return saa711x_set_audio_clock_freq(client, *(u32 *)arg);
 
        case VIDIOC_G_TUNER:
        {
@@ -1331,7 +1251,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
 
                if (state->radio)
                        break;
-               status = saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
+               status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
 
                v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
                vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
@@ -1339,14 +1259,14 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
        }
 
        case VIDIOC_LOG_STATUS:
-               saa7115_log_status(client);
+               saa711x_log_status(client);
                break;
 
        case VIDIOC_G_CTRL:
-               return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
+               return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg);
 
        case VIDIOC_S_CTRL:
-               return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
+               return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg);
 
        case VIDIOC_QUERYCTRL:
        {
@@ -1364,12 +1284,12 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
        }
 
        case VIDIOC_G_STD:
-               *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
+               *(v4l2_std_id *)arg = saa711x_get_v4lstd(client);
                break;
 
        case VIDIOC_S_STD:
                state->radio = 0;
-               saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
+               saa711x_set_v4lstd(client, *(v4l2_std_id *)arg);
                break;
 
        case AUDC_SET_RADIO:
@@ -1405,13 +1325,13 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
                state->input = route->input;
 
                /* select mode */
-               saa7115_write(client, R_02_INPUT_CNTL_1,
-                             (saa7115_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
+               saa711x_write(client, R_02_INPUT_CNTL_1,
+                             (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
                               state->input);
 
                /* bypass chrominance trap for S-Video modes */
-               saa7115_write(client, R_09_LUMA_CNTL,
-                             (saa7115_read(client, R_09_LUMA_CNTL) & 0x7f) |
+               saa711x_write(client, R_09_LUMA_CNTL,
+                             (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) |
                               (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
                break;
        }
@@ -1423,7 +1343,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
 
                if (state->enable != (cmd == VIDIOC_STREAMON)) {
                        state->enable = (cmd == VIDIOC_STREAMON);
-                       saa7115_write(client,
+                       saa711x_write(client,
                                R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
                                state->enable);
                }
@@ -1440,17 +1360,17 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
                state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
                state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
                state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
-               saa7115_set_audio_clock_freq(client, state->audclk_freq);
+               saa711x_set_audio_clock_freq(client, state->audclk_freq);
                break;
        }
 
        case VIDIOC_INT_DECODE_VBI_LINE:
-               saa7115_decode_vbi_line(client, arg);
+               saa711x_decode_vbi_line(client, arg);
                break;
 
        case VIDIOC_INT_RESET:
                v4l_dbg(1, debug, client, "decoder RESET\n");
-               saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+               saa711x_writeregs(client, saa7115_cfg_reset_scaler);
                break;
 
        case VIDIOC_INT_G_VBI_DATA:
@@ -1459,25 +1379,25 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
 
                switch (data->id) {
                case V4L2_SLICED_WSS_625:
-                       if (saa7115_read(client, 0x6b) & 0xc0)
+                       if (saa711x_read(client, 0x6b) & 0xc0)
                                return -EIO;
-                       data->data[0] = saa7115_read(client, 0x6c);
-                       data->data[1] = saa7115_read(client, 0x6d);
+                       data->data[0] = saa711x_read(client, 0x6c);
+                       data->data[1] = saa711x_read(client, 0x6d);
                        return 0;
                case V4L2_SLICED_CAPTION_525:
                        if (data->field == 0) {
                                /* CC */
-                               if (saa7115_read(client, 0x66) & 0xc0)
+                               if (saa711x_read(client, 0x66) & 0xc0)
                                        return -EIO;
-                               data->data[0] = saa7115_read(client, 0x67);
-                               data->data[1] = saa7115_read(client, 0x68);
+                               data->data[0] = saa711x_read(client, 0x67);
+                               data->data[1] = saa711x_read(client, 0x68);
                                return 0;
                        }
                        /* XDS */
-                       if (saa7115_read(client, 0x66) & 0x30)
+                       if (saa711x_read(client, 0x66) & 0x30)
                                return -EIO;
-                       data->data[0] = saa7115_read(client, 0x69);
-                       data->data[1] = saa7115_read(client, 0x6a);
+                       data->data[0] = saa711x_read(client, 0x69);
+                       data->data[1] = saa711x_read(client, 0x6a);
                        return 0;
                default:
                        return -EINVAL;
@@ -1492,7 +1412,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
 
                if (reg->i2c_id != I2C_DRIVERID_SAA711X)
                        return -EINVAL;
-               reg->val = saa7115_read(client, reg->reg & 0xff);
+               reg->val = saa711x_read(client, reg->reg & 0xff);
                break;
        }
 
@@ -1504,7 +1424,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
+               saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif
@@ -1522,12 +1442,12 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_saa7115;
+static struct i2c_driver i2c_driver_saa711x;
 
-static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
+static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
 {
        struct i2c_client *client;
-       struct saa7115_state *state;
+       struct saa711x_state *state;
        int     i;
        char    name[17];
        u8 chip_id;
@@ -1541,36 +1461,36 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
-       client->driver = &i2c_driver_saa7115;
+       client->driver = &i2c_driver_saa711x;
        snprintf(client->name, sizeof(client->name) - 1, "saa7115");
 
-       v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
-
-       for (i=0;i<0x0f;i++) {
-               saa7115_write(client, 0, i);
-               name[i] = (saa7115_read(client, 0) &0x0f) +'0';
-               if (name[i]>'9')
-                       name[i]+='a'-'9'-1;
+       for (i = 0; i < 0x0f; i++) {
+               saa711x_write(client, 0, i);
+               name[i] = (saa711x_read(client, 0) & 0x0f) + '0';
+               if (name[i] > '9')
+                       name[i] += 'a' - '9' - 1;
        }
-       name[i]='\0';
+       name[i] = '\0';
 
-       saa7115_write(client, 0, 5);
-       chip_id = saa7115_read(client, 0) & 0x0f;
-       if (chip_id < 3 && chip_id > 5) {
-               v4l_dbg(1, debug, client, "saa7115 not found\n");
-               kfree(client);
+       saa711x_write(client, 0, 5);
+       chip_id = saa711x_read(client, 0) & 0x0f;
+
+       /* Check whether this chip is part of the saa711x series */
+       if (memcmp(name, "1f711", 5)) {
+               v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
+                       address << 1, name);
                return 0;
        }
+
        snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
        v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
 
-       state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
        i2c_set_clientdata(client, state);
        if (state == NULL) {
                kfree(client);
                return -ENOMEM;
        }
-       state->std = V4L2_STD_NTSC;
        state->input = -1;
        state->enable = 1;
        state->radio = 0;
@@ -1605,39 +1525,39 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
        v4l_dbg(1, debug, client, "writing init values\n");
 
        /* init to 60hz/48khz */
-       if (state->ident == V4L2_IDENT_SAA7111 ||
-                       state->ident == V4L2_IDENT_SAA7113) {
-               state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
-               saa7115_writeregs(client, saa7113_init_auto_input);
-       } else {
+       state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
+       switch (state->ident) {
+       case V4L2_IDENT_SAA7111:
+               saa711x_writeregs(client, saa7111_init);
+               break;
+       case V4L2_IDENT_SAA7113:
+               saa711x_writeregs(client, saa7113_init);
+               break;
+       default:
                state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
-               saa7115_writeregs(client, saa7115_init_auto_input);
+               saa711x_writeregs(client, saa7115_init_auto_input);
        }
-       saa7115_writeregs(client, saa7115_init_misc);
-       saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
-       saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
-       saa7115_writeregs(client, saa7115_cfg_60hz_video);
-       saa7115_set_audio_clock_freq(client, state->audclk_freq);
-       saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+       saa711x_writeregs(client, saa7115_init_misc);
+       saa711x_set_v4lstd(client, V4L2_STD_NTSC);
 
        i2c_attach_client(client);
 
        v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
-               saa7115_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
+               saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
 
        return 0;
 }
 
-static int saa7115_probe(struct i2c_adapter *adapter)
+static int saa711x_probe(struct i2c_adapter *adapter)
 {
        if (adapter->class & I2C_CLASS_TV_ANALOG)
-               return i2c_probe(adapter, &addr_data, &saa7115_attach);
+               return i2c_probe(adapter, &addr_data, &saa711x_attach);
        return 0;
 }
 
-static int saa7115_detach(struct i2c_client *client)
+static int saa711x_detach(struct i2c_client *client)
 {
-       struct saa7115_state *state = i2c_get_clientdata(client);
+       struct saa711x_state *state = i2c_get_clientdata(client);
        int err;
 
        err = i2c_detach_client(client);
@@ -1653,26 +1573,26 @@ static int saa7115_detach(struct i2c_client *client)
 /* ----------------------------------------------------------------------- */
 
 /* i2c implementation */
-static struct i2c_driver i2c_driver_saa7115 = {
+static struct i2c_driver i2c_driver_saa711x = {
        .driver = {
                .name = "saa7115",
        },
        .id = I2C_DRIVERID_SAA711X,
-       .attach_adapter = saa7115_probe,
-       .detach_client = saa7115_detach,
-       .command = saa7115_command,
+       .attach_adapter = saa711x_probe,
+       .detach_client = saa711x_detach,
+       .command = saa711x_command,
 };
 
 
-static int __init saa7115_init_module(void)
+static int __init saa711x_init_module(void)
 {
-       return i2c_add_driver(&i2c_driver_saa7115);
+       return i2c_add_driver(&i2c_driver_saa711x);
 }
 
-static void __exit saa7115_cleanup_module(void)
+static void __exit saa711x_cleanup_module(void)
 {
-       i2c_del_driver(&i2c_driver_saa7115);
+       i2c_del_driver(&i2c_driver_saa711x);
 }
 
-module_init(saa7115_init_module);
-module_exit(saa7115_cleanup_module);
+module_init(saa711x_init_module);
+module_exit(saa711x_cleanup_module);