OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [saa7115.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* saa711x - Philips SAA711x video decoder driver
2
 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
3
 *                           saa7115 and saa7118.
4
 *
5
 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
6
 * the saa7111 driver by Dave Perks.
7
 *
8
 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9
 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
10
 *
11
 * Slight changes for video timing and attachment output by
12
 * Wolfgang Scherr <scherr@net4you.net>
13
 *
14
 * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
15
 * by Ronald Bultje <rbultje@ronald.bitfreak.net>
16
 *
17
 * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
18
 * (2/17/2003)
19
 *
20
 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
21
 *
22
 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23
 *      SAA7111, SAA7113 and SAA7118 support
24
 *
25
 * This program is free software; you can redistribute it and/or
26
 * modify it under the terms of the GNU General Public License
27
 * as published by the Free Software Foundation; either version 2
28
 * of the License, or (at your option) any later version.
29
 *
30
 * This program is distributed in the hope that it will be useful,
31
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33
 * GNU General Public License for more details.
34
 *
35
 * You should have received a copy of the GNU General Public License
36
 * along with this program; if not, write to the Free Software
37
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
38
 */
39
 
40
#include "saa711x_regs.h"
41
 
42
#include <linux/kernel.h>
43
#include <linux/module.h>
44
#include <linux/slab.h>
45
#include <linux/i2c.h>
46
#include <linux/videodev2.h>
47
#include <media/v4l2-common.h>
48
#include <media/v4l2-chip-ident.h>
49
#include <media/saa7115.h>
50
#include <asm/div64.h>
51
 
52
#define VRES_60HZ       (480+16)
53
 
54
MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
55
MODULE_AUTHOR(  "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
56
                "Hans Verkuil, Mauro Carvalho Chehab");
57
MODULE_LICENSE("GPL");
58
 
59
static int debug = 0;
60
module_param(debug, bool, 0644);
61
 
62
MODULE_PARM_DESC(debug, "Debug level (0-1)");
63
 
64
static unsigned short normal_i2c[] = {
65
                0x4a >> 1, 0x48 >> 1,   /* SAA7111, SAA7111A and SAA7113 */
66
                0x42 >> 1, 0x40 >> 1,   /* SAA7114, SAA7115 and SAA7118 */
67
                I2C_CLIENT_END };
68
 
69
 
70
I2C_CLIENT_INSMOD;
71
 
72
struct saa711x_state {
73
        v4l2_std_id std;
74
        int input;
75
        int output;
76
        int enable;
77
        int radio;
78
        int bright;
79
        int contrast;
80
        int hue;
81
        int sat;
82
        int width;
83
        int height;
84
        u32 ident;
85
        u32 audclk_freq;
86
        u32 crystal_freq;
87
        u8 ucgc;
88
        u8 cgcdiv;
89
        u8 apll;
90
};
91
 
92
/* ----------------------------------------------------------------------- */
93
 
94
static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value)
95
{
96
        return i2c_smbus_write_byte_data(client, reg, value);
97
}
98
 
99
/* Sanity routine to check if a register is present */
100
static int saa711x_has_reg(const int id, const u8 reg)
101
{
102
        if (id == V4L2_IDENT_SAA7111)
103
                return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
104
                       (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
105
 
106
        /* common for saa7113/4/5/8 */
107
        if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
108
            reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
109
            reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
110
            reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
111
                return 0;
112
 
113
        switch (id) {
114
        case V4L2_IDENT_SAA7113:
115
                return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
116
                       reg != 0x5d && reg < 0x63;
117
        case V4L2_IDENT_SAA7114:
118
                return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
119
                       (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
120
                       reg != 0x81 && reg < 0xf0;
121
        case V4L2_IDENT_SAA7115:
122
                return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
123
        case V4L2_IDENT_SAA7118:
124
                return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
125
                       (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
126
                       (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
127
        }
128
        return 1;
129
}
130
 
131
static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs)
132
{
133
        struct saa711x_state *state = i2c_get_clientdata(client);
134
        unsigned char reg, data;
135
 
136
        while (*regs != 0x00) {
137
                reg = *(regs++);
138
                data = *(regs++);
139
 
140
                /* According with datasheets, reserved regs should be
141
                   filled with 0 - seems better not to touch on they */
142
                if (saa711x_has_reg(state->ident,reg)) {
143
                        if (saa711x_write(client, reg, data) < 0)
144
                                return -1;
145
                } else {
146
                        v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg);
147
                }
148
        }
149
        return 0;
150
}
151
 
152
static inline int saa711x_read(struct i2c_client *client, u8 reg)
153
{
154
        return i2c_smbus_read_byte_data(client, reg);
155
}
156
 
157
/* ----------------------------------------------------------------------- */
158
 
159
/* SAA7111 initialization table */
160
static const unsigned char saa7111_init[] = {
161
        R_01_INC_DELAY, 0x00,           /* reserved */
162
 
163
        /*front end */
164
        R_02_INPUT_CNTL_1, 0xd0,        /* FUSE=3, GUDL=2, MODE=0 */
165
        R_03_INPUT_CNTL_2, 0x23,        /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
166
                                         * GAFIX=0, GAI1=256, GAI2=256 */
167
        R_04_INPUT_CNTL_3, 0x00,        /* GAI1=256 */
168
        R_05_INPUT_CNTL_4, 0x00,        /* GAI2=256 */
169
 
170
        /* decoder */
171
        R_06_H_SYNC_START, 0xf3,        /* HSB at  13(50Hz) /  17(60Hz)
172
                                         * pixels after end of last line */
173
        R_07_H_SYNC_STOP, 0xe8,         /* HSS seems to be needed to
174
                                         * work with NTSC, too */
175
        R_08_SYNC_CNTL, 0xc8,           /* AUFD=1, FSEL=1, EXFIL=0,
176
                                         * VTRC=1, HPLL=0, VNOI=0 */
177
        R_09_LUMA_CNTL, 0x01,           /* BYPS=0, PREF=0, BPSS=0,
178
                                         * VBLB=0, UPTCV=0, APER=1 */
179
        R_0A_LUMA_BRIGHT_CNTL, 0x80,
180
        R_0B_LUMA_CONTRAST_CNTL, 0x47,  /* 0b - CONT=1.109 */
181
        R_0C_CHROMA_SAT_CNTL, 0x40,
182
        R_0D_CHROMA_HUE_CNTL, 0x00,
183
        R_0E_CHROMA_CNTL_1, 0x01,       /* 0e - CDTO=0, CSTD=0, DCCF=0,
184
                                         * FCTC=0, CHBW=1 */
185
        R_0F_CHROMA_GAIN_CNTL, 0x00,    /* reserved */
186
        R_10_CHROMA_CNTL_2, 0x48,       /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
187
        R_11_MODE_DELAY_CNTL, 0x1c,     /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
188
                                         * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
189
        R_12_RT_SIGNAL_CNTL, 0x00,      /* 12 - output control 2 */
190
        R_13_RT_X_PORT_OUT_CNTL, 0x00,  /* 13 - output control 3 */
191
        R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
192
        R_15_VGATE_START_FID_CHG, 0x00,
193
        R_16_VGATE_STOP, 0x00,
194
        R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
195
 
196
        0x00, 0x00
197
};
198
 
199
/* SAA7113 init codes */
200
static const unsigned char saa7113_init[] = {
201
        R_01_INC_DELAY, 0x08,
202
        R_02_INPUT_CNTL_1, 0xc2,
203
        R_03_INPUT_CNTL_2, 0x30,
204
        R_04_INPUT_CNTL_3, 0x00,
205
        R_05_INPUT_CNTL_4, 0x00,
206
        R_06_H_SYNC_START, 0x89,
207
        R_07_H_SYNC_STOP, 0x0d,
208
        R_08_SYNC_CNTL, 0x88,
209
        R_09_LUMA_CNTL, 0x01,
210
        R_0A_LUMA_BRIGHT_CNTL, 0x80,
211
        R_0B_LUMA_CONTRAST_CNTL, 0x47,
212
        R_0C_CHROMA_SAT_CNTL, 0x40,
213
        R_0D_CHROMA_HUE_CNTL, 0x00,
214
        R_0E_CHROMA_CNTL_1, 0x01,
215
        R_0F_CHROMA_GAIN_CNTL, 0x2a,
216
        R_10_CHROMA_CNTL_2, 0x08,
217
        R_11_MODE_DELAY_CNTL, 0x0c,
218
        R_12_RT_SIGNAL_CNTL, 0x07,
219
        R_13_RT_X_PORT_OUT_CNTL, 0x00,
220
        R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
221
        R_15_VGATE_START_FID_CHG, 0x00,
222
        R_16_VGATE_STOP, 0x00,
223
        R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
224
 
225
        0x00, 0x00
226
};
227
 
228
/* If a value differs from the Hauppauge driver values, then the comment starts with
229
   'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
230
   Hauppauge driver sets. */
231
 
232
/* SAA7114 and SAA7115 initialization table */
233
static const unsigned char saa7115_init_auto_input[] = {
234
                /* Front-End Part */
235
        R_01_INC_DELAY, 0x48,                   /* white peak control disabled */
236
        R_03_INPUT_CNTL_2, 0x20,                /* was 0x30. 0x20: long vertical blanking */
237
        R_04_INPUT_CNTL_3, 0x90,                /* analog gain set to 0 */
238
        R_05_INPUT_CNTL_4, 0x90,                /* analog gain set to 0 */
239
                /* Decoder Part */
240
        R_06_H_SYNC_START, 0xeb,                /* horiz sync begin = -21 */
241
        R_07_H_SYNC_STOP, 0xe0,                 /* horiz sync stop = -17 */
242
        R_09_LUMA_CNTL, 0x53,                   /* 0x53, was 0x56 for 60hz. luminance control */
243
        R_0A_LUMA_BRIGHT_CNTL, 0x80,            /* was 0x88. decoder brightness, 0x80 is itu standard */
244
        R_0B_LUMA_CONTRAST_CNTL, 0x44,          /* was 0x48. decoder contrast, 0x44 is itu standard */
245
        R_0C_CHROMA_SAT_CNTL, 0x40,             /* was 0x47. decoder saturation, 0x40 is itu standard */
246
        R_0D_CHROMA_HUE_CNTL, 0x00,
247
        R_0F_CHROMA_GAIN_CNTL, 0x00,            /* use automatic gain  */
248
        R_10_CHROMA_CNTL_2, 0x06,               /* chroma: active adaptive combfilter */
249
        R_11_MODE_DELAY_CNTL, 0x00,
250
        R_12_RT_SIGNAL_CNTL, 0x9d,              /* RTS0 output control: VGATE */
251
        R_13_RT_X_PORT_OUT_CNTL, 0x80,          /* ITU656 standard mode, RTCO output enable RTCE */
252
        R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
253
        R_18_RAW_DATA_GAIN_CNTL, 0x40,          /* gain 0x00 = nominal */
254
        R_19_RAW_DATA_OFF_CNTL, 0x80,
255
        R_1A_COLOR_KILL_LVL_CNTL, 0x77,         /* recommended value */
256
        R_1B_MISC_TVVCRDET, 0x42,               /* recommended value */
257
        R_1C_ENHAN_COMB_CTRL1, 0xa9,            /* recommended value */
258
        R_1D_ENHAN_COMB_CTRL2, 0x01,            /* recommended value */
259
 
260
 
261
        R_80_GLOBAL_CNTL_1, 0x0,                /* No tasks enabled at init */
262
 
263
                /* Power Device Control */
264
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,    /* reset device */
265
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,    /* set device programmed, all in operational mode */
266
        0x00, 0x00
267
};
268
 
269
/* Used to reset saa7113, saa7114 and saa7115 */
270
static const unsigned char saa7115_cfg_reset_scaler[] = {
271
        R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,    /* disable I-port output */
272
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
273
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
274
        R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* enable I-port output */
275
        0x00, 0x00
276
};
277
 
278
/* ============== SAA7715 VIDEO templates =============  */
279
 
280
static const unsigned char saa7115_cfg_60hz_video[] = {
281
        R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
282
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
283
 
284
        R_15_VGATE_START_FID_CHG, 0x03,
285
        R_16_VGATE_STOP, 0x11,
286
        R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
287
 
288
        R_08_SYNC_CNTL, 0x68,                   /* 0xBO: auto detection, 0x68 = NTSC */
289
        R_0E_CHROMA_CNTL_1, 0x07,               /* video autodetection is on */
290
 
291
        R_5A_V_OFF_FOR_SLICER, 0x06,            /* standard 60hz value for ITU656 line counting */
292
 
293
        /* Task A */
294
        R_90_A_TASK_HANDLING_CNTL, 0x80,
295
        R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
296
        R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
297
        R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
298
 
299
        /* hoffset low (input), 0x0002 is minimum */
300
        R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
301
        R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
302
 
303
        /* hsize low (input), 0x02d0 = 720 */
304
        R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
305
        R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
306
 
307
        R_98_A_VERT_INPUT_WINDOW_START, 0x05,
308
        R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
309
 
310
        R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
311
        R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
312
 
313
        R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
314
        R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
315
 
316
        R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
317
        R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
318
 
319
        /* Task B */
320
        R_C0_B_TASK_HANDLING_CNTL, 0x00,
321
        R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
322
        R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
323
        R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
324
 
325
        /* 0x0002 is minimum */
326
        R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
327
        R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
328
 
329
        /* 0x02d0 = 720 */
330
        R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
331
        R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
332
 
333
        /* vwindow start 0x12 = 18 */
334
        R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
335
        R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
336
 
337
        /* vwindow length 0xf8 = 248 */
338
        R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
339
        R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
340
 
341
        /* hwindow 0x02d0 = 720 */
342
        R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
343
        R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
344
 
345
        R_F0_LFCO_PER_LINE, 0xad,               /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
346
        R_F1_P_I_PARAM_SELECT, 0x05,            /* low bit with 0xF0 */
347
        R_F5_PULSGEN_LINE_LENGTH, 0xad,
348
        R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
349
 
350
        0x00, 0x00
351
};
352
 
353
static const unsigned char saa7115_cfg_50hz_video[] = {
354
        R_80_GLOBAL_CNTL_1, 0x00,
355
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,    /* reset scaler */
356
 
357
        R_15_VGATE_START_FID_CHG, 0x37,         /* VGATE start */
358
        R_16_VGATE_STOP, 0x16,
359
        R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
360
 
361
        R_08_SYNC_CNTL, 0x28,                   /* 0x28 = PAL */
362
        R_0E_CHROMA_CNTL_1, 0x07,
363
 
364
        R_5A_V_OFF_FOR_SLICER, 0x03,            /* standard 50hz value */
365
 
366
        /* Task A */
367
        R_90_A_TASK_HANDLING_CNTL, 0x81,
368
        R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
369
        R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
370
        R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
371
 
372
        /* This is weird: the datasheet says that you should use 2 as the minimum value, */
373
        /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
374
        /* hoffset low (input), 0x0002 is minimum */
375
        R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
376
        R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
377
 
378
        /* hsize low (input), 0x02d0 = 720 */
379
        R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
380
        R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
381
 
382
        R_98_A_VERT_INPUT_WINDOW_START, 0x03,
383
        R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
384
 
385
        /* vsize 0x12 = 18 */
386
        R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
387
        R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
388
 
389
        /* hsize 0x05a0 = 1440 */
390
        R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
391
        R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,    /* hsize hi (output) */
392
        R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12,         /* vsize low (output), 0x12 = 18 */
393
        R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,     /* vsize hi (output) */
394
 
395
        /* Task B */
396
        R_C0_B_TASK_HANDLING_CNTL, 0x00,
397
        R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
398
        R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
399
        R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
400
 
401
        /* This is weird: the datasheet says that you should use 2 as the minimum value, */
402
        /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
403
        /* hoffset low (input), 0x0002 is minimum. See comment above. */
404
        R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
405
        R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
406
 
407
        /* hsize 0x02d0 = 720 */
408
        R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
409
        R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
410
 
411
        /* voffset 0x16 = 22 */
412
        R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
413
        R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
414
 
415
        /* vsize 0x0120 = 288 */
416
        R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
417
        R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
418
 
419
        /* hsize 0x02d0 = 720 */
420
        R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
421
        R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
422
 
423
        R_F0_LFCO_PER_LINE, 0xb0,               /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
424
        R_F1_P_I_PARAM_SELECT, 0x05,            /* low bit with 0xF0, (was 0x05) */
425
        R_F5_PULSGEN_LINE_LENGTH, 0xb0,
426
        R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
427
 
428
        0x00, 0x00
429
};
430
 
431
/* ============== SAA7715 VIDEO templates (end) =======  */
432
 
433
static const unsigned char saa7115_cfg_vbi_on[] = {
434
        R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
435
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
436
        R_80_GLOBAL_CNTL_1, 0x30,                       /* Activate both tasks */
437
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
438
        R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
439
 
440
        0x00, 0x00
441
};
442
 
443
static const unsigned char saa7115_cfg_vbi_off[] = {
444
        R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
445
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
446
        R_80_GLOBAL_CNTL_1, 0x20,                       /* Activate only task "B" */
447
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
448
        R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
449
 
450
        0x00, 0x00
451
};
452
 
453
 
454
static const unsigned char saa7115_init_misc[] = {
455
        R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
456
        R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
457
        R_84_I_PORT_SIGNAL_DEF, 0x20,
458
        R_85_I_PORT_SIGNAL_POLAR, 0x21,
459
        R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
460
        R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
461
 
462
        /* Task A */
463
        R_A0_A_HORIZ_PRESCALING, 0x01,
464
        R_A1_A_ACCUMULATION_LENGTH, 0x00,
465
        R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
466
 
467
        /* Configure controls at nominal value*/
468
        R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
469
        R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
470
        R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
471
 
472
        /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
473
        R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
474
        R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
475
 
476
        R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
477
 
478
        /* must be horiz lum scaling / 2 */
479
        R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
480
        R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
481
 
482
        /* must be offset luma / 2 */
483
        R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
484
 
485
        R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
486
        R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
487
 
488
        R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
489
        R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
490
 
491
        R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
492
 
493
        R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
494
        R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
495
        R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
496
        R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
497
 
498
        R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
499
        R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
500
        R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
501
        R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
502
 
503
        /* Task B */
504
        R_D0_B_HORIZ_PRESCALING, 0x01,
505
        R_D1_B_ACCUMULATION_LENGTH, 0x00,
506
        R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
507
 
508
        /* Configure controls at nominal value*/
509
        R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
510
        R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
511
        R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
512
 
513
        /* hor lum scaling 0x0400 = 1 */
514
        R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
515
        R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
516
 
517
        R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
518
 
519
        /* must be hor lum scaling / 2 */
520
        R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
521
        R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
522
 
523
        /* must be offset luma / 2 */
524
        R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
525
 
526
        R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
527
        R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
528
 
529
        R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
530
        R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
531
 
532
        R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
533
 
534
        R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
535
        R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
536
        R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
537
        R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
538
 
539
        R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
540
        R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
541
        R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
542
        R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
543
 
544
        R_F2_NOMINAL_PLL2_DTO, 0x50,            /* crystal clock = 24.576 MHz, target = 27MHz */
545
        R_F3_PLL_INCREMENT, 0x46,
546
        R_F4_PLL2_STATUS, 0x00,
547
        R_F7_PULSE_A_POS_MSB, 0x4b,             /* not the recommended settings! */
548
        R_F8_PULSE_B_POS, 0x00,
549
        R_F9_PULSE_B_POS_MSB, 0x4b,
550
        R_FA_PULSE_C_POS, 0x00,
551
        R_FB_PULSE_C_POS_MSB, 0x4b,
552
 
553
        /* PLL2 lock detection settings: 71 lines 50% phase error */
554
        R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
555
 
556
        /* Turn off VBI */
557
        R_40_SLICER_CNTL_1, 0x20,             /* No framing code errors allowed. */
558
        R_41_LCR_BASE, 0xff,
559
        R_41_LCR_BASE+1, 0xff,
560
        R_41_LCR_BASE+2, 0xff,
561
        R_41_LCR_BASE+3, 0xff,
562
        R_41_LCR_BASE+4, 0xff,
563
        R_41_LCR_BASE+5, 0xff,
564
        R_41_LCR_BASE+6, 0xff,
565
        R_41_LCR_BASE+7, 0xff,
566
        R_41_LCR_BASE+8, 0xff,
567
        R_41_LCR_BASE+9, 0xff,
568
        R_41_LCR_BASE+10, 0xff,
569
        R_41_LCR_BASE+11, 0xff,
570
        R_41_LCR_BASE+12, 0xff,
571
        R_41_LCR_BASE+13, 0xff,
572
        R_41_LCR_BASE+14, 0xff,
573
        R_41_LCR_BASE+15, 0xff,
574
        R_41_LCR_BASE+16, 0xff,
575
        R_41_LCR_BASE+17, 0xff,
576
        R_41_LCR_BASE+18, 0xff,
577
        R_41_LCR_BASE+19, 0xff,
578
        R_41_LCR_BASE+20, 0xff,
579
        R_41_LCR_BASE+21, 0xff,
580
        R_41_LCR_BASE+22, 0xff,
581
        R_58_PROGRAM_FRAMING_CODE, 0x40,
582
        R_59_H_OFF_FOR_SLICER, 0x47,
583
        R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
584
        R_5D_DID, 0xbd,
585
        R_5E_SDID, 0x35,
586
 
587
        R_02_INPUT_CNTL_1, 0x84,                /* input tuner -> input 4, amplifier active */
588
 
589
        R_80_GLOBAL_CNTL_1, 0x20,               /* enable task B */
590
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
591
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
592
        0x00, 0x00
593
};
594
 
595
static int saa711x_odd_parity(u8 c)
596
{
597
        c ^= (c >> 4);
598
        c ^= (c >> 2);
599
        c ^= (c >> 1);
600
 
601
        return c & 1;
602
}
603
 
604
static int saa711x_decode_vps(u8 * dst, u8 * p)
605
{
606
        static const u8 biphase_tbl[] = {
607
                0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
608
                0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
609
                0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
610
                0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
611
                0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
612
                0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
613
                0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
614
                0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
615
                0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
616
                0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
617
                0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
618
                0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
619
                0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
620
                0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
621
                0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
622
                0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
623
                0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
624
                0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
625
                0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
626
                0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
627
                0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
628
                0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
629
                0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
630
                0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
631
                0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
632
                0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
633
                0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
634
                0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
635
                0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
636
                0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
637
                0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
638
                0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
639
        };
640
        int i;
641
        u8 c, err = 0;
642
 
643
        for (i = 0; i < 2 * 13; i += 2) {
644
                err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
645
                c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
646
                dst[i / 2] = c;
647
        }
648
        return err & 0xf0;
649
}
650
 
651
static int saa711x_decode_wss(u8 * p)
652
{
653
        static const int wss_bits[8] = {
654
                0, 0, 0, 1, 0, 1, 1, 1
655
        };
656
        unsigned char parity;
657
        int wss = 0;
658
        int i;
659
 
660
        for (i = 0; i < 16; i++) {
661
                int b1 = wss_bits[p[i] & 7];
662
                int b2 = wss_bits[(p[i] >> 3) & 7];
663
 
664
                if (b1 == b2)
665
                        return -1;
666
                wss |= b2 << i;
667
        }
668
        parity = wss & 15;
669
        parity ^= parity >> 2;
670
        parity ^= parity >> 1;
671
 
672
        if (!(parity & 1))
673
                return -1;
674
 
675
        return wss;
676
}
677
 
678
static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
679
{
680
        struct saa711x_state *state = i2c_get_clientdata(client);
681
        u32 acpf;
682
        u32 acni;
683
        u32 hz;
684
        u64 f;
685
        u8 acc = 0;      /* reg 0x3a, audio clock control */
686
 
687
        /* Checks for chips that don't have audio clock (saa7111, saa7113) */
688
        if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
689
                return 0;
690
 
691
        v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
692
 
693
        /* sanity check */
694
        if (freq < 32000 || freq > 48000)
695
                return -EINVAL;
696
 
697
        /* hz is the refresh rate times 100 */
698
        hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
699
        /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
700
        acpf = (25600 * freq) / hz;
701
        /* acni = (256 * freq * 2^23) / crystal_frequency =
702
                  (freq * 2^(8+23)) / crystal_frequency =
703
                  (freq << 31) / crystal_frequency */
704
        f = freq;
705
        f = f << 31;
706
        do_div(f, state->crystal_freq);
707
        acni = f;
708
        if (state->ucgc) {
709
                acpf = acpf * state->cgcdiv / 16;
710
                acni = acni * state->cgcdiv / 16;
711
                acc = 0x80;
712
                if (state->cgcdiv == 3)
713
                        acc |= 0x40;
714
        }
715
        if (state->apll)
716
                acc |= 0x08;
717
 
718
        saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
719
        saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
720
        saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
721
 
722
        saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
723
        saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
724
                                                        (acpf >> 8) & 0xff);
725
        saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
726
                                                        (acpf >> 16) & 0x03);
727
 
728
        saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
729
        saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
730
        saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
731
        state->audclk_freq = freq;
732
        return 0;
733
}
734
 
735
static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
736
{
737
        struct saa711x_state *state = i2c_get_clientdata(client);
738
 
739
        switch (ctrl->id) {
740
        case V4L2_CID_BRIGHTNESS:
741
                if (ctrl->value < 0 || ctrl->value > 255) {
742
                        v4l_err(client, "invalid brightness setting %d\n", ctrl->value);
743
                        return -ERANGE;
744
                }
745
 
746
                state->bright = ctrl->value;
747
                saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
748
                break;
749
 
750
        case V4L2_CID_CONTRAST:
751
                if (ctrl->value < 0 || ctrl->value > 127) {
752
                        v4l_err(client, "invalid contrast setting %d\n", ctrl->value);
753
                        return -ERANGE;
754
                }
755
 
756
                state->contrast = ctrl->value;
757
                saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
758
                break;
759
 
760
        case V4L2_CID_SATURATION:
761
                if (ctrl->value < 0 || ctrl->value > 127) {
762
                        v4l_err(client, "invalid saturation setting %d\n", ctrl->value);
763
                        return -ERANGE;
764
                }
765
 
766
                state->sat = ctrl->value;
767
                saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
768
                break;
769
 
770
        case V4L2_CID_HUE:
771
                if (ctrl->value < -127 || ctrl->value > 127) {
772
                        v4l_err(client, "invalid hue setting %d\n", ctrl->value);
773
                        return -ERANGE;
774
                }
775
 
776
                state->hue = ctrl->value;
777
                saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
778
                break;
779
 
780
        default:
781
                return -EINVAL;
782
        }
783
 
784
        return 0;
785
}
786
 
787
static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
788
{
789
        struct saa711x_state *state = i2c_get_clientdata(client);
790
 
791
        switch (ctrl->id) {
792
        case V4L2_CID_BRIGHTNESS:
793
                ctrl->value = state->bright;
794
                break;
795
        case V4L2_CID_CONTRAST:
796
                ctrl->value = state->contrast;
797
                break;
798
        case V4L2_CID_SATURATION:
799
                ctrl->value = state->sat;
800
                break;
801
        case V4L2_CID_HUE:
802
                ctrl->value = state->hue;
803
                break;
804
        default:
805
                return -EINVAL;
806
        }
807
 
808
        return 0;
809
}
810
 
811
static int saa711x_set_size(struct i2c_client *client, int width, int height)
812
{
813
        struct saa711x_state *state = i2c_get_clientdata(client);
814
        int HPSC, HFSC;
815
        int VSCY;
816
        int res;
817
        int is_50hz = state->std & V4L2_STD_625_50;
818
        int Vsrc = is_50hz ? 576 : 480;
819
 
820
        v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height);
821
 
822
        /* FIXME need better bounds checking here */
823
        if ((width < 1) || (width > 1440))
824
                return -EINVAL;
825
        if ((height < 1) || (height > Vsrc))
826
                return -EINVAL;
827
 
828
        if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
829
                /* Decoder only supports 720 columns and 480 or 576 lines */
830
                if (width != 720)
831
                        return -EINVAL;
832
                if (height != Vsrc)
833
                        return -EINVAL;
834
        }
835
 
836
        state->width = width;
837
        state->height = height;
838
 
839
        if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
840
                return 0;
841
 
842
        /* probably have a valid size, let's set it */
843
        /* Set output width/height */
844
        /* width */
845
 
846
        saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
847
                                        (u8) (width & 0xff));
848
        saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
849
                                        (u8) ((width >> 8) & 0xff));
850
 
851
        /* Vertical Scaling uses height/2 */
852
        res=height/2;
853
 
854
        /* On 60Hz, it is using a higher Vertical Output Size */
855
        if (!is_50hz)
856
                res += (VRES_60HZ - 480) >> 1;
857
 
858
                /* height */
859
        saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
860
                                        (u8) (res & 0xff));
861
        saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
862
                                        (u8) ((res >> 8) & 0xff));
863
 
864
        /* Scaling settings */
865
        /* Hprescaler is floor(inres/outres) */
866
        HPSC = (int)(720 / width);
867
        /* 0 is not allowed (div. by zero) */
868
        HPSC = HPSC ? HPSC : 1;
869
        HFSC = (int)((1024 * 720) / (HPSC * width));
870
        /* FIXME hardcodes to "Task B"
871
         * write H prescaler integer */
872
        saa711x_write(client, R_D0_B_HORIZ_PRESCALING,
873
                                (u8) (HPSC & 0x3f));
874
 
875
        v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
876
        /* write H fine-scaling (luminance) */
877
        saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
878
                                (u8) (HFSC & 0xff));
879
        saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
880
                                (u8) ((HFSC >> 8) & 0xff));
881
        /* write H fine-scaling (chrominance)
882
         * must be lum/2, so i'll just bitshift :) */
883
        saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
884
                                (u8) ((HFSC >> 1) & 0xff));
885
        saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
886
                                (u8) ((HFSC >> 9) & 0xff));
887
 
888
        VSCY = (int)((1024 * Vsrc) / height);
889
        v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
890
 
891
        /* Correct Contrast and Luminance */
892
        saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
893
                                        (u8) (64 * 1024 / VSCY));
894
        saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
895
                                        (u8) (64 * 1024 / VSCY));
896
 
897
                /* write V fine-scaling (luminance) */
898
        saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
899
                                        (u8) (VSCY & 0xff));
900
        saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
901
                                        (u8) ((VSCY >> 8) & 0xff));
902
                /* write V fine-scaling (chrominance) */
903
        saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
904
                                        (u8) (VSCY & 0xff));
905
        saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
906
                                        (u8) ((VSCY >> 8) & 0xff));
907
 
908
        saa711x_writeregs(client, saa7115_cfg_reset_scaler);
909
 
910
        /* Activates task "B" */
911
        saa711x_write(client, R_80_GLOBAL_CNTL_1,
912
                                saa711x_read(client,R_80_GLOBAL_CNTL_1) | 0x20);
913
 
914
        return 0;
915
}
916
 
917
static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
918
{
919
        struct saa711x_state *state = i2c_get_clientdata(client);
920
 
921
        /* Prevent unnecessary standard changes. During a standard
922
           change the I-Port is temporarily disabled. Any devices
923
           reading from that port can get confused.
924
           Note that VIDIOC_S_STD is also used to switch from
925
           radio to TV mode, so if a VIDIOC_S_STD is broadcast to
926
           all I2C devices then you do not want to have an unwanted
927
           side-effect here. */
928
        if (std == state->std)
929
                return;
930
 
931
        state->std = std;
932
 
933
        // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
934
        if (std & V4L2_STD_525_60) {
935
                v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
936
                saa711x_writeregs(client, saa7115_cfg_60hz_video);
937
                saa711x_set_size(client, 720, 480);
938
        } else {
939
                v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
940
                saa711x_writeregs(client, saa7115_cfg_50hz_video);
941
                saa711x_set_size(client, 720, 576);
942
        }
943
 
944
        /* Register 0E - Bits D6-D4 on NO-AUTO mode
945
                (SAA7111 and SAA7113 doesn't have auto mode)
946
            50 Hz / 625 lines           60 Hz / 525 lines
947
        000 PAL BGDHI (4.43Mhz)         NTSC M (3.58MHz)
948
        001 NTSC 4.43 (50 Hz)           PAL 4.43 (60 Hz)
949
        010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
950
        011 NTSC N (3.58MHz)            PAL M (3.58MHz)
951
        100 reserved                    NTSC-Japan (3.58MHz)
952
        */
953
        if (state->ident == V4L2_IDENT_SAA7111 ||
954
            state->ident == V4L2_IDENT_SAA7113) {
955
                u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
956
 
957
                if (std == V4L2_STD_PAL_M) {
958
                        reg |= 0x30;
959
                } else if (std == V4L2_STD_PAL_N) {
960
                        reg |= 0x20;
961
                } else if (std == V4L2_STD_PAL_60) {
962
                        reg |= 0x10;
963
                } else if (std == V4L2_STD_NTSC_M_JP) {
964
                        reg |= 0x40;
965
                } else if (std & V4L2_STD_SECAM) {
966
                        reg |= 0x50;
967
                }
968
                saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
969
        } else {
970
                /* restart task B if needed */
971
                int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
972
 
973
                if (taskb && state->ident == V4L2_IDENT_SAA7114) {
974
                        saa711x_writeregs(client, saa7115_cfg_vbi_on);
975
                }
976
 
977
                /* switch audio mode too! */
978
                saa711x_set_audio_clock_freq(client, state->audclk_freq);
979
        }
980
}
981
 
982
static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
983
{
984
        struct saa711x_state *state = i2c_get_clientdata(client);
985
 
986
        return state->std;
987
}
988
 
989
static void saa711x_log_status(struct i2c_client *client)
990
{
991
        struct saa711x_state *state = i2c_get_clientdata(client);
992
        int reg1e, reg1f;
993
        int signalOk;
994
        int vcr;
995
 
996
        v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
997
        if (state->ident != V4L2_IDENT_SAA7115) {
998
                /* status for the saa7114 */
999
                reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1000
                signalOk = (reg1f & 0xc1) == 0x81;
1001
                v4l_info(client, "Video signal:    %s\n", signalOk ? "ok" : "bad");
1002
                v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1003
                return;
1004
        }
1005
 
1006
        /* status for the saa7115 */
1007
        reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
1008
        reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1009
 
1010
        signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1011
        vcr = !(reg1f & 0x10);
1012
 
1013
        if (state->input >= 6) {
1014
                v4l_info(client, "Input:           S-Video %d\n", state->input - 6);
1015
        } else {
1016
                v4l_info(client, "Input:           Composite %d\n", state->input);
1017
        }
1018
        v4l_info(client, "Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1019
        v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1020
 
1021
        switch (reg1e & 0x03) {
1022
                case 1:
1023
                        v4l_info(client, "Detected format: NTSC\n");
1024
                        break;
1025
                case 2:
1026
                        v4l_info(client, "Detected format: PAL\n");
1027
                        break;
1028
                case 3:
1029
                        v4l_info(client, "Detected format: SECAM\n");
1030
                        break;
1031
                default:
1032
                        v4l_info(client, "Detected format: BW/No color\n");
1033
                        break;
1034
        }
1035
        v4l_info(client, "Width, Height:   %d, %d\n", state->width, state->height);
1036
}
1037
 
1038
/* setup the sliced VBI lcr registers according to the sliced VBI format */
1039
static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
1040
{
1041
        struct saa711x_state *state = i2c_get_clientdata(client);
1042
        int is_50hz = (state->std & V4L2_STD_625_50);
1043
        u8 lcr[24];
1044
        int i, x;
1045
 
1046
#if 1
1047
        /* saa7113/7114/7118 VBI support are experimental */
1048
        if (!saa711x_has_reg(state->ident,R_41_LCR_BASE))
1049
                return;
1050
 
1051
#else
1052
        /* SAA7113 and SAA7118 also should support VBI - Need testing */
1053
        if (state->ident != V4L2_IDENT_SAA7115)
1054
                return;
1055
#endif
1056
 
1057
        for (i = 0; i <= 23; i++)
1058
                lcr[i] = 0xff;
1059
 
1060
        if (fmt->service_set == 0) {
1061
                /* raw VBI */
1062
                if (is_50hz)
1063
                        for (i = 6; i <= 23; i++)
1064
                                lcr[i] = 0xdd;
1065
                else
1066
                        for (i = 10; i <= 21; i++)
1067
                                lcr[i] = 0xdd;
1068
        } else {
1069
                /* sliced VBI */
1070
                /* first clear lines that cannot be captured */
1071
                if (is_50hz) {
1072
                        for (i = 0; i <= 5; i++)
1073
                                fmt->service_lines[0][i] =
1074
                                        fmt->service_lines[1][i] = 0;
1075
                }
1076
                else {
1077
                        for (i = 0; i <= 9; i++)
1078
                                fmt->service_lines[0][i] =
1079
                                        fmt->service_lines[1][i] = 0;
1080
                        for (i = 22; i <= 23; i++)
1081
                                fmt->service_lines[0][i] =
1082
                                        fmt->service_lines[1][i] = 0;
1083
                }
1084
 
1085
                /* Now set the lcr values according to the specified service */
1086
                for (i = 6; i <= 23; i++) {
1087
                        lcr[i] = 0;
1088
                        for (x = 0; x <= 1; x++) {
1089
                                switch (fmt->service_lines[1-x][i]) {
1090
                                        case 0:
1091
                                                lcr[i] |= 0xf << (4 * x);
1092
                                                break;
1093
                                        case V4L2_SLICED_TELETEXT_B:
1094
                                                lcr[i] |= 1 << (4 * x);
1095
                                                break;
1096
                                        case V4L2_SLICED_CAPTION_525:
1097
                                                lcr[i] |= 4 << (4 * x);
1098
                                                break;
1099
                                        case V4L2_SLICED_WSS_625:
1100
                                                lcr[i] |= 5 << (4 * x);
1101
                                                break;
1102
                                        case V4L2_SLICED_VPS:
1103
                                                lcr[i] |= 7 << (4 * x);
1104
                                                break;
1105
                                }
1106
                        }
1107
                }
1108
        }
1109
 
1110
        /* write the lcr registers */
1111
        for (i = 2; i <= 23; i++) {
1112
                saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
1113
        }
1114
 
1115
        /* enable/disable raw VBI capturing */
1116
        saa711x_writeregs(client, fmt->service_set == 0 ?
1117
                                saa7115_cfg_vbi_on :
1118
                                saa7115_cfg_vbi_off);
1119
}
1120
 
1121
static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
1122
{
1123
        static u16 lcr2vbi[] = {
1124
                0, V4L2_SLICED_TELETEXT_B, 0,     /* 1 */
1125
                0, V4L2_SLICED_CAPTION_525,      /* 4 */
1126
                V4L2_SLICED_WSS_625, 0,          /* 5 */
1127
                V4L2_SLICED_VPS, 0, 0, 0, 0,        /* 7 */
1128
                0, 0, 0, 0
1129
        };
1130
        struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
1131
        int i;
1132
 
1133
        if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1134
                return -EINVAL;
1135
        memset(sliced, 0, sizeof(*sliced));
1136
        /* done if using raw VBI */
1137
        if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
1138
                return 0;
1139
        for (i = 2; i <= 23; i++) {
1140
                u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE);
1141
 
1142
                sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1143
                sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1144
                sliced->service_set |=
1145
                        sliced->service_lines[0][i] | sliced->service_lines[1][i];
1146
        }
1147
        return 0;
1148
}
1149
 
1150
static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
1151
{
1152
        if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1153
                saa711x_set_lcr(client, &fmt->fmt.sliced);
1154
                return 0;
1155
        }
1156
        if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1157
                return -EINVAL;
1158
 
1159
        return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height);
1160
}
1161
 
1162
/* Decode the sliced VBI data stream as created by the saa7115.
1163
   The format is described in the saa7115 datasheet in Tables 25 and 26
1164
   and in Figure 33.
1165
   The current implementation uses SAV/EAV codes and not the ancillary data
1166
   headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1167
   code. */
1168
static void saa711x_decode_vbi_line(struct i2c_client *client,
1169
                                    struct v4l2_decode_vbi_line *vbi)
1170
{
1171
        static const char vbi_no_data_pattern[] = {
1172
                0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1173
        };
1174
        struct saa711x_state *state = i2c_get_clientdata(client);
1175
        u8 *p = vbi->p;
1176
        u32 wss;
1177
        int id1, id2;   /* the ID1 and ID2 bytes from the internal header */
1178
 
1179
        vbi->type = 0;  /* mark result as a failure */
1180
        id1 = p[2];
1181
        id2 = p[3];
1182
        /* Note: the field bit is inverted for 60 Hz video */
1183
        if (state->std & V4L2_STD_525_60)
1184
                id1 ^= 0x40;
1185
 
1186
        /* Skip internal header, p now points to the start of the payload */
1187
        p += 4;
1188
        vbi->p = p;
1189
 
1190
        /* calculate field and line number of the VBI packet (1-23) */
1191
        vbi->is_second_field = ((id1 & 0x40) != 0);
1192
        vbi->line = (id1 & 0x3f) << 3;
1193
        vbi->line |= (id2 & 0x70) >> 4;
1194
 
1195
        /* Obtain data type */
1196
        id2 &= 0xf;
1197
 
1198
        /* If the VBI slicer does not detect any signal it will fill up
1199
           the payload buffer with 0xa0 bytes. */
1200
        if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1201
                return;
1202
 
1203
        /* decode payloads */
1204
        switch (id2) {
1205
        case 1:
1206
                vbi->type = V4L2_SLICED_TELETEXT_B;
1207
                break;
1208
        case 4:
1209
                if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1210
                        return;
1211
                vbi->type = V4L2_SLICED_CAPTION_525;
1212
                break;
1213
        case 5:
1214
                wss = saa711x_decode_wss(p);
1215
                if (wss == -1)
1216
                        return;
1217
                p[0] = wss & 0xff;
1218
                p[1] = wss >> 8;
1219
                vbi->type = V4L2_SLICED_WSS_625;
1220
                break;
1221
        case 7:
1222
                if (saa711x_decode_vps(p, p) != 0)
1223
                        return;
1224
                vbi->type = V4L2_SLICED_VPS;
1225
                break;
1226
        default:
1227
                return;
1228
        }
1229
}
1230
 
1231
/* ============ SAA7115 AUDIO settings (end) ============= */
1232
 
1233
static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
1234
{
1235
        struct saa711x_state *state = i2c_get_clientdata(client);
1236
 
1237
        /* ioctls to allow direct access to the saa7115 registers for testing */
1238
        switch (cmd) {
1239
        case VIDIOC_S_FMT:
1240
                return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
1241
 
1242
        case VIDIOC_G_FMT:
1243
                return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg);
1244
 
1245
        case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1246
                return saa711x_set_audio_clock_freq(client, *(u32 *)arg);
1247
 
1248
        case VIDIOC_G_TUNER:
1249
        {
1250
                struct v4l2_tuner *vt = arg;
1251
                int status;
1252
 
1253
                if (state->radio)
1254
                        break;
1255
                status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1256
 
1257
                v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
1258
                vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1259
                break;
1260
        }
1261
 
1262
        case VIDIOC_LOG_STATUS:
1263
                saa711x_log_status(client);
1264
                break;
1265
 
1266
        case VIDIOC_G_CTRL:
1267
                return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg);
1268
 
1269
        case VIDIOC_S_CTRL:
1270
                return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg);
1271
 
1272
        case VIDIOC_QUERYCTRL:
1273
        {
1274
                struct v4l2_queryctrl *qc = arg;
1275
 
1276
                switch (qc->id) {
1277
                        case V4L2_CID_BRIGHTNESS:
1278
                        case V4L2_CID_CONTRAST:
1279
                        case V4L2_CID_SATURATION:
1280
                        case V4L2_CID_HUE:
1281
                                return v4l2_ctrl_query_fill_std(qc);
1282
                        default:
1283
                                return -EINVAL;
1284
                }
1285
        }
1286
 
1287
        case VIDIOC_G_STD:
1288
                *(v4l2_std_id *)arg = saa711x_get_v4lstd(client);
1289
                break;
1290
 
1291
        case VIDIOC_S_STD:
1292
                state->radio = 0;
1293
                saa711x_set_v4lstd(client, *(v4l2_std_id *)arg);
1294
                break;
1295
 
1296
        case AUDC_SET_RADIO:
1297
                state->radio = 1;
1298
                break;
1299
 
1300
        case VIDIOC_INT_G_VIDEO_ROUTING:
1301
        {
1302
                struct v4l2_routing *route = arg;
1303
 
1304
                route->input = state->input;
1305
                route->output = state->output;
1306
                break;
1307
        }
1308
 
1309
        case VIDIOC_INT_S_VIDEO_ROUTING:
1310
        {
1311
                struct v4l2_routing *route = arg;
1312
 
1313
                v4l_dbg(1, debug, client, "decoder set input %d output %d\n", route->input, route->output);
1314
                /* saa7113 does not have these inputs */
1315
                if (state->ident == V4L2_IDENT_SAA7113 &&
1316
                    (route->input == SAA7115_COMPOSITE4 ||
1317
                     route->input == SAA7115_COMPOSITE5)) {
1318
                        return -EINVAL;
1319
                }
1320
                if (route->input > SAA7115_SVIDEO3)
1321
                        return -EINVAL;
1322
                if (route->output > SAA7115_IPORT_ON)
1323
                        return -EINVAL;
1324
                if (state->input == route->input && state->output == route->output)
1325
                        break;
1326
                v4l_dbg(1, debug, client, "now setting %s input %s output\n",
1327
                        (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite", (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1328
                state->input = route->input;
1329
 
1330
                /* select mode */
1331
                saa711x_write(client, R_02_INPUT_CNTL_1,
1332
                              (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
1333
                               state->input);
1334
 
1335
                /* bypass chrominance trap for S-Video modes */
1336
                saa711x_write(client, R_09_LUMA_CNTL,
1337
                              (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) |
1338
                               (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1339
 
1340
                state->output = route->output;
1341
                if (state->ident == V4L2_IDENT_SAA7114 ||
1342
                        state->ident == V4L2_IDENT_SAA7115) {
1343
                        saa711x_write(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1344
                              (saa711x_read(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1345
                               (state->output & 0x01));
1346
                }
1347
                break;
1348
        }
1349
 
1350
        case VIDIOC_STREAMON:
1351
        case VIDIOC_STREAMOFF:
1352
                v4l_dbg(1, debug, client, "%s output\n",
1353
                        (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
1354
 
1355
                if (state->enable != (cmd == VIDIOC_STREAMON)) {
1356
                        state->enable = (cmd == VIDIOC_STREAMON);
1357
                        saa711x_write(client,
1358
                                R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1359
                                state->enable);
1360
                }
1361
                break;
1362
 
1363
        case VIDIOC_INT_S_CRYSTAL_FREQ:
1364
        {
1365
                struct v4l2_crystal_freq *freq = arg;
1366
 
1367
                if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1368
                    freq->freq != SAA7115_FREQ_24_576_MHZ)
1369
                        return -EINVAL;
1370
                state->crystal_freq = freq->freq;
1371
                state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1372
                state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1373
                state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1374
                saa711x_set_audio_clock_freq(client, state->audclk_freq);
1375
                break;
1376
        }
1377
 
1378
        case VIDIOC_INT_DECODE_VBI_LINE:
1379
                saa711x_decode_vbi_line(client, arg);
1380
                break;
1381
 
1382
        case VIDIOC_INT_RESET:
1383
                v4l_dbg(1, debug, client, "decoder RESET\n");
1384
                saa711x_writeregs(client, saa7115_cfg_reset_scaler);
1385
                break;
1386
 
1387
        case VIDIOC_INT_G_VBI_DATA:
1388
        {
1389
                struct v4l2_sliced_vbi_data *data = arg;
1390
 
1391
                /* Note: the internal field ID is inverted for NTSC,
1392
                   so data->field 0 maps to the saa7115 even field,
1393
                   whereas for PAL it maps to the saa7115 odd field. */
1394
                switch (data->id) {
1395
                case V4L2_SLICED_WSS_625:
1396
                        if (saa711x_read(client, 0x6b) & 0xc0)
1397
                                return -EIO;
1398
                        data->data[0] = saa711x_read(client, 0x6c);
1399
                        data->data[1] = saa711x_read(client, 0x6d);
1400
                        return 0;
1401
                case V4L2_SLICED_CAPTION_525:
1402
                        if (data->field == 0) {
1403
                                /* CC */
1404
                                if (saa711x_read(client, 0x66) & 0x30)
1405
                                        return -EIO;
1406
                                data->data[0] = saa711x_read(client, 0x69);
1407
                                data->data[1] = saa711x_read(client, 0x6a);
1408
                                return 0;
1409
                        }
1410
                        /* XDS */
1411
                        if (saa711x_read(client, 0x66) & 0xc0)
1412
                                return -EIO;
1413
                        data->data[0] = saa711x_read(client, 0x67);
1414
                        data->data[1] = saa711x_read(client, 0x68);
1415
                        return 0;
1416
                default:
1417
                        return -EINVAL;
1418
                }
1419
                break;
1420
        }
1421
 
1422
#ifdef CONFIG_VIDEO_ADV_DEBUG
1423
        case VIDIOC_DBG_G_REGISTER:
1424
        case VIDIOC_DBG_S_REGISTER:
1425
        {
1426
                struct v4l2_register *reg = arg;
1427
 
1428
                if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1429
                        return -EINVAL;
1430
                if (!capable(CAP_SYS_ADMIN))
1431
                        return -EPERM;
1432
                if (cmd == VIDIOC_DBG_G_REGISTER)
1433
                        reg->val = saa711x_read(client, reg->reg & 0xff);
1434
                else
1435
                        saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
1436
                break;
1437
        }
1438
#endif
1439
 
1440
        case VIDIOC_G_CHIP_IDENT:
1441
                return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0);
1442
 
1443
        default:
1444
                return -EINVAL;
1445
        }
1446
 
1447
        return 0;
1448
}
1449
 
1450
/* ----------------------------------------------------------------------- */
1451
 
1452
static struct i2c_driver i2c_driver_saa711x;
1453
 
1454
static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1455
{
1456
        struct i2c_client *client;
1457
        struct saa711x_state *state;
1458
        int     i;
1459
        char    name[17];
1460
        u8 chip_id;
1461
 
1462
        /* Check if the adapter supports the needed features */
1463
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1464
                return 0;
1465
 
1466
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1467
        if (client == 0)
1468
                return -ENOMEM;
1469
        client->addr = address;
1470
        client->adapter = adapter;
1471
        client->driver = &i2c_driver_saa711x;
1472
        snprintf(client->name, sizeof(client->name) - 1, "saa7115");
1473
 
1474
        for (i = 0; i < 0x0f; i++) {
1475
                saa711x_write(client, 0, i);
1476
                name[i] = (saa711x_read(client, 0) & 0x0f) + '0';
1477
                if (name[i] > '9')
1478
                        name[i] += 'a' - '9' - 1;
1479
        }
1480
        name[i] = '\0';
1481
 
1482
        saa711x_write(client, 0, 5);
1483
        chip_id = saa711x_read(client, 0) & 0x0f;
1484
 
1485
        /* Check whether this chip is part of the saa711x series */
1486
        if (memcmp(name, "1f711", 5)) {
1487
                v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
1488
                        address << 1, name);
1489
                kfree(client);
1490
                return 0;
1491
        }
1492
 
1493
        snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
1494
        v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
1495
 
1496
        state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1497
        i2c_set_clientdata(client, state);
1498
        if (state == NULL) {
1499
                kfree(client);
1500
                return -ENOMEM;
1501
        }
1502
        state->input = -1;
1503
        state->output = SAA7115_IPORT_ON;
1504
        state->enable = 1;
1505
        state->radio = 0;
1506
        state->bright = 128;
1507
        state->contrast = 64;
1508
        state->hue = 0;
1509
        state->sat = 64;
1510
        switch (chip_id) {
1511
        case 1:
1512
                state->ident = V4L2_IDENT_SAA7111;
1513
                break;
1514
        case 3:
1515
                state->ident = V4L2_IDENT_SAA7113;
1516
                break;
1517
        case 4:
1518
                state->ident = V4L2_IDENT_SAA7114;
1519
                break;
1520
        case 5:
1521
                state->ident = V4L2_IDENT_SAA7115;
1522
                break;
1523
        case 8:
1524
                state->ident = V4L2_IDENT_SAA7118;
1525
                break;
1526
        default:
1527
                state->ident = V4L2_IDENT_SAA7111;
1528
                v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n");
1529
 
1530
        }
1531
 
1532
        state->audclk_freq = 48000;
1533
 
1534
        v4l_dbg(1, debug, client, "writing init values\n");
1535
 
1536
        /* init to 60hz/48khz */
1537
        state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1538
        switch (state->ident) {
1539
        case V4L2_IDENT_SAA7111:
1540
                saa711x_writeregs(client, saa7111_init);
1541
                break;
1542
        case V4L2_IDENT_SAA7113:
1543
                saa711x_writeregs(client, saa7113_init);
1544
                break;
1545
        default:
1546
                state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1547
                saa711x_writeregs(client, saa7115_init_auto_input);
1548
        }
1549
        saa711x_writeregs(client, saa7115_init_misc);
1550
        saa711x_set_v4lstd(client, V4L2_STD_NTSC);
1551
 
1552
        i2c_attach_client(client);
1553
 
1554
        v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1555
                saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
1556
 
1557
        return 0;
1558
}
1559
 
1560
static int saa711x_probe(struct i2c_adapter *adapter)
1561
{
1562
        if (adapter->class & I2C_CLASS_TV_ANALOG || adapter->class & I2C_CLASS_TV_DIGITAL)
1563
                return i2c_probe(adapter, &addr_data, &saa711x_attach);
1564
        return 0;
1565
}
1566
 
1567
static int saa711x_detach(struct i2c_client *client)
1568
{
1569
        struct saa711x_state *state = i2c_get_clientdata(client);
1570
        int err;
1571
 
1572
        err = i2c_detach_client(client);
1573
        if (err) {
1574
                return err;
1575
        }
1576
 
1577
        kfree(state);
1578
        kfree(client);
1579
        return 0;
1580
}
1581
 
1582
/* ----------------------------------------------------------------------- */
1583
 
1584
/* i2c implementation */
1585
static struct i2c_driver i2c_driver_saa711x = {
1586
        .driver = {
1587
                .name = "saa7115",
1588
        },
1589
        .id = I2C_DRIVERID_SAA711X,
1590
        .attach_adapter = saa711x_probe,
1591
        .detach_client = saa711x_detach,
1592
        .command = saa711x_command,
1593
};
1594
 
1595
 
1596
static int __init saa711x_init_module(void)
1597
{
1598
        return i2c_add_driver(&i2c_driver_saa711x);
1599
}
1600
 
1601
static void __exit saa711x_cleanup_module(void)
1602
{
1603
        i2c_del_driver(&i2c_driver_saa711x);
1604
}
1605
 
1606
module_init(saa711x_init_module);
1607
module_exit(saa711x_cleanup_module);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.