V4L/DVB (12732): cx25821: fix bad whitespacing
[linux-2.6-block.git] / drivers / staging / cx25821 / cx25821-medusa-video.c
CommitLineData
02b20b0b
MCC
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
bb4c9a74 4 * Copyright (C) 2009 Conexant Systems Inc.
02b20b0b
MCC
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24#include "cx25821-medusa-video.h"
25#include "cx25821-biffuncs.h"
26
27
28/////////////////////////////////////////////////////////////////////////////////////////
29//medusa_enable_bluefield_output()
30//
31// Enable the generation of blue filed output if no video
32//
33static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel, int enable)
34{
35 int ret_val = 1;
36 u32 value = 0;
37 u32 tmp = 0;
38 int out_ctrl = OUT_CTRL1;
39 int out_ctrl_ns = OUT_CTRL_NS;
40
bb4c9a74 41
02b20b0b
MCC
42 switch (channel)
43 {
bb4c9a74
MCC
44 default:
45 case VDEC_A:
46 break;
47 case VDEC_B:
48 out_ctrl = VDEC_B_OUT_CTRL1;
49 out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
50 break;
51 case VDEC_C:
52 out_ctrl = VDEC_C_OUT_CTRL1;
53 out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
54 break;
55 case VDEC_D:
56 out_ctrl = VDEC_D_OUT_CTRL1;
57 out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
58 break;
59 case VDEC_E:
60 out_ctrl = VDEC_E_OUT_CTRL1;
61 out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
62 return;
63 case VDEC_F:
64 out_ctrl = VDEC_F_OUT_CTRL1;
65 out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
66 return;
67 case VDEC_G:
68 out_ctrl = VDEC_G_OUT_CTRL1;
69 out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
70 return;
71 case VDEC_H:
72 out_ctrl = VDEC_H_OUT_CTRL1;
73 out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
74 return;
02b20b0b
MCC
75 }
76
77 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
78 value &= 0xFFFFFF7F; // clear BLUE_FIELD_EN
79 if (enable)
bb4c9a74 80 value |= 0x00000080; // set BLUE_FIELD_EN
02b20b0b
MCC
81 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
82
83 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
84 value &= 0xFFFFFF7F;
85 if (enable)
bb4c9a74 86 value |= 0x00000080; // set BLUE_FIELD_EN
02b20b0b
MCC
87 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
88}
89
90
91static int medusa_initialize_ntsc(struct cx25821_dev *dev)
92{
93 int ret_val = 0;
94 int i = 0;
95 u32 value = 0;
96 u32 tmp = 0;
97
98 mutex_lock(&dev->lock);
99
bb4c9a74 100
02b20b0b
MCC
101 for (i=0; i < MAX_DECODERS; i++)
102 {
bb4c9a74
MCC
103 // set video format NTSC-M
104 value = cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), &tmp);
105 value &= 0xFFFFFFF0;
106 value |= 0x10001; // enable the fast locking mode bit[16]
107 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), value);
108
109 // resolution NTSC 720x480
110 value = cx25821_i2c_read(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), &tmp);
111 value &= 0x00C00C00;
112 value |= 0x612D0074;
113 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), value);
114
115 value = cx25821_i2c_read(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), &tmp);
116 value &= 0x00C00C00;
117 value |= 0x1C1E001A; // vblank_cnt + 2 to get camera ID
118 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), value);
119
120 // chroma subcarrier step size
121 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], SC_STEP_SIZE+(0x200*i), 0x43E00000);
122
123 // enable VIP optional active
124 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), &tmp);
125 value &= 0xFFFBFFFF;
126 value |= 0x00040000;
127 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), value);
128
129 // enable VIP optional active (VIP_OPT_AL) for direct output.
130 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), &tmp);
131 value &= 0xFFFBFFFF;
132 value |= 0x00040000;
133 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), value);
134
135 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
136 // when the input switching rate < 16 fields
137 //
138 value = cx25821_i2c_read(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), &tmp);
139 value = setBitAtPos(value, 14); // disable special play detection
140 value = clearBitAtPos(value, 15);
141 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), value);
142
143 // set vbi_gate_en to 0
144 value = cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), &tmp);
145 value = clearBitAtPos(value, 29);
146 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), value);
147
148 // Enable the generation of blue field output if no video
149 medusa_enable_bluefield_output(dev, i, 1);
02b20b0b
MCC
150 }
151
152
153 for (i=0; i < MAX_ENCODERS; i++)
154 {
bb4c9a74
MCC
155 // NTSC hclock
156 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), &tmp);
157 value &= 0xF000FC00;
158 value |= 0x06B402D0;
159 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), value);
160
161 // burst begin and burst end
162 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), &tmp);
163 value &= 0xFF000000;
164 value |= 0x007E9054;
165 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), value);
166
167 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), &tmp);
168 value &= 0xFC00FE00;
169 value |= 0x00EC00F0;
170 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), value);
171
172 // set NTSC vblank, no phase alternation, 7.5 IRE pedestal
173 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), &tmp);
174 value &= 0x00FCFFFF;
175 value |= 0x13020000;
176 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), value);
177
178 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), &tmp);
179 value &= 0xFFFF0000;
180 value |= 0x0000E575;
181 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), value);
182
183 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_6+(0x100*i), 0x009A89C1);
184
185 // Subcarrier Increment
186 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_7+(0x100*i), 0x21F07C1F);
02b20b0b
MCC
187 }
188
189
190 //set picture resolutions
191 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
192 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 480
193
194 // set Bypass input format to NTSC 525 lines
195 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
196 value |= 0x00080200;
197 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
198
199 mutex_unlock(&dev->lock);
200
201 return ret_val;
202}
203
204
205static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
206{
207 int ret_val = -1;
208 u32 value = 0, tmp = 0;
bb4c9a74 209
02b20b0b
MCC
210 // Setup for 2D threshold
211 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG+(0x200*dec), 0x20002861);
bb4c9a74
MCC
212 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG+(0x200*dec), 0x20002861);
213 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG+(0x200*dec), 0x200A1023);
214
215 // Setup flat chroma and luma thresholds
02b20b0b 216 value = cx25821_i2c_read(&dev->i2c_bus[0], COMB_FLAT_THRESH_CTRL+(0x200*dec), &tmp);
bb4c9a74 217 value &= 0x06230000;
02b20b0b 218 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_FLAT_THRESH_CTRL+(0x200*dec), value);
bb4c9a74
MCC
219
220 // set comb 2D blend
02b20b0b 221 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND+(0x200*dec), 0x210F0F0F);
bb4c9a74
MCC
222
223 // COMB MISC CONTROL
02b20b0b 224 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL+(0x200*dec), 0x41120A7F);
bb4c9a74 225
02b20b0b
MCC
226 return ret_val;
227}
228
229
230static int medusa_initialize_pal(struct cx25821_dev *dev)
231{
232 int ret_val = 0;
233 int i = 0;
234 u32 value = 0;
235 u32 tmp = 0;
236
237 mutex_lock(&dev->lock);
bb4c9a74 238
02b20b0b
MCC
239 for (i=0; i < MAX_DECODERS; i++)
240 {
bb4c9a74
MCC
241 // set video format PAL-BDGHI
242 value = cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), &tmp);
243 value &= 0xFFFFFFF0;
244 value |= 0x10004; // enable the fast locking mode bit[16]
245 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL+(0x200*i), value);
246
247
248 // resolution PAL 720x576
249 value = cx25821_i2c_read(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), &tmp);
250 value &= 0x00C00C00;
251 value |= 0x632D007D;
252 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HORIZ_TIM_CTRL+(0x200*i), value);
253
254 // vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24
255 value = cx25821_i2c_read(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), &tmp);
256 value &= 0x00C00C00;
257 value |= 0x28240026; // vblank_cnt + 2 to get camera ID
258 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VERT_TIM_CTRL+(0x200*i), value);
259
260 // chroma subcarrier step size
261 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], SC_STEP_SIZE+(0x200*i), 0x5411E2D0);
262
263 // enable VIP optional active
264 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), &tmp);
265 value &= 0xFFFBFFFF;
266 value |= 0x00040000;
267 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL_NS+(0x200*i), value);
268
269 // enable VIP optional active (VIP_OPT_AL) for direct output.
270 value = cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), &tmp);
271 value &= 0xFFFBFFFF;
272 value |= 0x00040000;
273 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1+(0x200*i), value);
274
275 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
276 // when the input switching rate < 16 fields
277 value = cx25821_i2c_read(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), &tmp);
278 value = setBitAtPos(value, 14); // disable special play detection
279 value = clearBitAtPos(value, 15);
280 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MISC_TIM_CTRL+(0x200*i), value);
281
282 // set vbi_gate_en to 0
283 value = cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), &tmp);
284 value = clearBitAtPos(value, 29);
285 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1+(0x200*i), value);
286
287 medusa_PALCombInit(dev, i);
288
289 // Enable the generation of blue field output if no video
290 medusa_enable_bluefield_output(dev, i, 1);
291 }
292
293
294 for (i=0; i < MAX_ENCODERS; i++)
295 {
296 // PAL hclock
297 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), &tmp);
298 value &= 0xF000FC00;
299 value |= 0x06C002D0;
300 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_1+(0x100*i), value);
301
302 // burst begin and burst end
303 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), &tmp);
304 value &= 0xFF000000;
305 value |= 0x007E9754;
306 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_2+(0x100*i), value);
307
308 // hblank and vactive
309 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), &tmp);
310 value &= 0xFC00FE00;
311 value |= 0x00FC0120;
312 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_3+(0x100*i), value);
313
314 // set PAL vblank, phase alternation, 0 IRE pedestal
315 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), &tmp);
316 value &= 0x00FCFFFF;
317 value |= 0x14010000;
318 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4+(0x100*i), value);
319
320
321 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), &tmp);
322 value &= 0xFFFF0000;
323 value |= 0x0000F078;
324 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_5+(0x100*i), value);
325
326 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_6+(0x100*i), 0x00A493CF);
327
328 // Subcarrier Increment
329 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_7+(0x100*i), 0x2A098ACB);
330 }
331
332
333 //set picture resolutions
02b20b0b
MCC
334 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
335 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 576
bb4c9a74
MCC
336
337 // set Bypass input format to PAL 625 lines
02b20b0b
MCC
338 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
339 value &= 0xFFF7FDFF;
340 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
bb4c9a74 341
02b20b0b
MCC
342 mutex_unlock(&dev->lock);
343
344 return ret_val;
345}
346
347
348int medusa_set_videostandard(struct cx25821_dev *dev)
349{
350 int status = STATUS_SUCCESS;
351 u32 value = 0, tmp = 0;
352
bb4c9a74 353
02b20b0b
MCC
354 if(dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
355 {
bb4c9a74 356 status = medusa_initialize_pal(dev);
02b20b0b
MCC
357 }
358 else
359 {
bb4c9a74 360 status = medusa_initialize_ntsc(dev);
02b20b0b 361 }
bb4c9a74 362
02b20b0b
MCC
363 // Enable DENC_A output
364 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
365 value = setBitAtPos(value, 4);
366 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
bb4c9a74 367
02b20b0b
MCC
368 // Enable DENC_B output
369 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
370 value = setBitAtPos(value, 4);
371 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
bb4c9a74 372
02b20b0b
MCC
373 return status;
374}
375
376
377void medusa_set_resolution(struct cx25821_dev *dev, int width, int decoder_select)
378{
379 int decoder = 0;
380 int decoder_count = 0;
381 int ret_val = 0;
382 u32 hscale = 0x0;
bb4c9a74 383 u32 vscale = 0x0;
02b20b0b
MCC
384 const int MAX_WIDTH = 720;
385
386 mutex_lock(&dev->lock);
387
388 // validate the width - cannot be negative
389 if (width > MAX_WIDTH)
390 {
bb4c9a74
MCC
391 printk("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n", __func__, width, MAX_WIDTH);
392 width = MAX_WIDTH;
393 }
394
02b20b0b
MCC
395 if( decoder_select <= 7 && decoder_select >= 0 )
396 {
bb4c9a74
MCC
397 decoder = decoder_select;
398 decoder_count = decoder_select + 1;
02b20b0b
MCC
399 }
400 else
401 {
bb4c9a74
MCC
402 decoder = 0;
403 decoder_count = _num_decoders;
02b20b0b 404 }
02b20b0b 405
02b20b0b 406
bb4c9a74
MCC
407 switch( width )
408 {
409 case 320:
410 hscale = 0x13E34B;
411 vscale = 0x0;
412 break;
413
414 case 352:
415 hscale = 0x10A273;
416 vscale = 0x0;
417 break;
418
419 case 176:
420 hscale = 0x3115B2;
421 vscale = 0x1E00;
422 break;
423
424 case 160:
425 hscale = 0x378D84;
426 vscale = 0x1E00;
427 break;
428
429 default: //720
430 hscale = 0x0;
431 vscale = 0x0;
432 break;
433 }
02b20b0b
MCC
434
435 for( ; decoder < decoder_count; decoder++)
436 {
bb4c9a74
MCC
437 // write scaling values for each decoder
438 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL+(0x200*decoder), hscale);
439 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL+(0x200*decoder), vscale);
02b20b0b
MCC
440 }
441
442 mutex_unlock(&dev->lock);
443}
444
445static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, int duration)
446{
447 int ret_val = 0;
448 u32 fld_cnt = 0;
449 u32 tmp = 0;
450 u32 disp_cnt_reg = DISP_AB_CNT;
bb4c9a74 451
02b20b0b
MCC
452 mutex_lock(&dev->lock);
453
bb4c9a74 454 // no support
02b20b0b
MCC
455 if (decoder < VDEC_A && decoder > VDEC_H)
456 {
bb4c9a74
MCC
457 mutex_unlock(&dev->lock);
458 return;
02b20b0b
MCC
459 }
460
461 switch (decoder)
462 {
bb4c9a74
MCC
463 default:
464 break;
465 case VDEC_C:
466 case VDEC_D:
467 disp_cnt_reg = DISP_CD_CNT;
468 break;
469 case VDEC_E:
470 case VDEC_F:
471 disp_cnt_reg = DISP_EF_CNT;
472 break;
473 case VDEC_G:
474 case VDEC_H:
475 disp_cnt_reg = DISP_GH_CNT;
476 break;
02b20b0b
MCC
477 }
478
479 _display_field_cnt[decoder] = duration;
480
481 // update hardware
482 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
bb4c9a74 483
02b20b0b
MCC
484 if (!(decoder % 2)) // EVEN decoder
485 {
bb4c9a74
MCC
486 fld_cnt &= 0xFFFF0000;
487 fld_cnt |= duration;
02b20b0b
MCC
488 }
489 else
490 {
bb4c9a74
MCC
491 fld_cnt &= 0x0000FFFF;
492 fld_cnt |= ((u32)duration) << 16;
02b20b0b
MCC
493 }
494
495 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
bb4c9a74 496
02b20b0b
MCC
497 mutex_unlock(&dev->lock);
498}
499
500/////////////////////////////////////////////////////////////////////////////////////////
501// Map to Medusa register setting
502static int mapM(
503 int srcMin,
504 int srcMax,
505 int srcVal,
506 int dstMin,
507 int dstMax,
508 int* dstVal
509)
510{
511 int numerator;
512 int denominator;
513 int quotient;
514
515 if((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
516 {
bb4c9a74 517 return -1;
02b20b0b
MCC
518 }
519
520 // This is the overall expression used:
521 // *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
522 // but we need to account for rounding so below we use the modulus
523 // operator to find the remainder and increment if necessary.
524 numerator = (srcVal - srcMin)*(dstMax - dstMin);
525 denominator = srcMax - srcMin;
526 quotient = numerator/denominator;
527
528 if(2 * ( numerator % denominator ) >= denominator)
529 {
bb4c9a74 530 quotient++;
02b20b0b
MCC
531 }
532
533 *dstVal = quotient + dstMin;
534
535 return 0;
536}
537
538static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
539{
540 unsigned char temp;
541
542 if (numeric >= 0)
bb4c9a74 543 return numeric;
02b20b0b
MCC
544 else
545 {
bb4c9a74
MCC
546 temp = ~(abs(numeric) & 0xFF);
547 temp += 1;
548 return temp;
02b20b0b
MCC
549 }
550}
551/////////////////////////////////////////////////////////////////////////////////////////
552int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
553{
554 int ret_val = 0;
555 int value = 0;
556 u32 val = 0, tmp = 0;
557
558 mutex_lock(&dev->lock);
559 if((brightness > VIDEO_PROCAMP_MAX) || (brightness < VIDEO_PROCAMP_MIN))
560 {
bb4c9a74
MCC
561 mutex_unlock(&dev->lock);
562 return -1;
02b20b0b
MCC
563 }
564 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
565 value = convert_to_twos(value, 8);
566 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_BRITE_CTRL+(0x200*decoder), &tmp);
567 val &= 0xFFFFFF00;
568 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_BRITE_CTRL+(0x200*decoder), val | value);
569 mutex_unlock(&dev->lock);
570 return ret_val;
571}
572
573/////////////////////////////////////////////////////////////////////////////////////////
574int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
575{
576 int ret_val = 0;
577 int value = 0;
578 u32 val = 0, tmp = 0;
579
580 mutex_lock(&dev->lock);
bb4c9a74 581
02b20b0b
MCC
582 if((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN))
583 {
bb4c9a74
MCC
584 mutex_unlock(&dev->lock);
585 return -1;
02b20b0b
MCC
586 }
587
588 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
589 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_CNTRST_CTRL+(0x200*decoder), &tmp);
590 val &= 0xFFFFFF00;
591 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_CNTRST_CTRL+(0x200*decoder), val | value);
592
593 mutex_unlock(&dev->lock);
594 return ret_val;
595}
596
597/////////////////////////////////////////////////////////////////////////////////////////
598int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
599{
600 int ret_val = 0;
601 int value = 0;
602 u32 val = 0, tmp = 0;
603
604 mutex_lock(&dev->lock);
bb4c9a74 605
02b20b0b
MCC
606 if((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN))
607 {
bb4c9a74
MCC
608 mutex_unlock(&dev->lock);
609 return -1;
02b20b0b
MCC
610 }
611
612 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
bb4c9a74 613
02b20b0b
MCC
614 value = convert_to_twos(value, 8);
615 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_HUE_CTRL+(0x200*decoder), &tmp);
616 val &= 0xFFFFFF00;
617
618 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_HUE_CTRL+(0x200*decoder), val | value);
619
620 mutex_unlock(&dev->lock);
621 return ret_val;
622}
623
624
625/////////////////////////////////////////////////////////////////////////////////////////
626int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
627{
628 int ret_val = 0;
629 int value = 0;
630 u32 val = 0, tmp = 0;
bb4c9a74 631
02b20b0b 632 mutex_lock(&dev->lock);
bb4c9a74 633
02b20b0b
MCC
634 if((saturation > VIDEO_PROCAMP_MAX) || (saturation < VIDEO_PROCAMP_MIN))
635 {
bb4c9a74
MCC
636 mutex_unlock(&dev->lock);
637 return -1;
02b20b0b
MCC
638 }
639
640 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
bb4c9a74 641
02b20b0b 642 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_USAT_CTRL+(0x200*decoder), &tmp);
bb4c9a74 643 val &= 0xFFFFFF00;
02b20b0b
MCC
644 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_USAT_CTRL+(0x200*decoder), val | value);
645
646 val = cx25821_i2c_read(&dev->i2c_bus[0], VDEC_A_VSAT_CTRL+(0x200*decoder), &tmp);
bb4c9a74 647 val &= 0xFFFFFF00;
02b20b0b 648 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_VSAT_CTRL+(0x200*decoder), val | value);
bb4c9a74 649
02b20b0b
MCC
650 mutex_unlock(&dev->lock);
651 return ret_val;
652}
653
654
655/////////////////////////////////////////////////////////////////////////////////////////
656// Program the display sequence and monitor output.
657//
658int medusa_video_init(struct cx25821_dev *dev)
659{
660 u32 value = 0, tmp = 0;
661 int ret_val = 0;
662 int i=0;
bb4c9a74 663
02b20b0b 664 mutex_lock(&dev->lock);
bb4c9a74 665
02b20b0b 666 _num_decoders = dev->_max_num_decoders;
bb4c9a74
MCC
667
668
669 // disable Auto source selection on all video decoders
02b20b0b
MCC
670 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
671 value &= 0xFFFFF0FF;
672 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
bb4c9a74 673
02b20b0b
MCC
674 if (ret_val < 0)
675 {
bb4c9a74
MCC
676 mutex_unlock(&dev->lock);
677 return -EINVAL;
02b20b0b 678 }
bb4c9a74 679
02b20b0b
MCC
680 // Turn off Master source switch enable
681 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
682 value &= 0xFFFFFFDF;
683 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
bb4c9a74 684
02b20b0b
MCC
685 if (ret_val < 0)
686 {
bb4c9a74
MCC
687 mutex_unlock(&dev->lock);
688 return -EINVAL;
02b20b0b
MCC
689 }
690
691 mutex_unlock(&dev->lock);
692
693 for (i=0; i < _num_decoders; i++)
694 {
bb4c9a74 695 medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
02b20b0b 696 }
bb4c9a74 697
02b20b0b
MCC
698 mutex_lock(&dev->lock);
699
bb4c9a74 700 // Select monitor as DENC A input, power up the DAC
02b20b0b
MCC
701 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
702 value &= 0xFF70FF70;
bb4c9a74 703 value |= 0x00090008; // set en_active
02b20b0b 704 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
bb4c9a74 705
02b20b0b
MCC
706 if (ret_val < 0)
707 {
bb4c9a74
MCC
708 mutex_unlock(&dev->lock);
709 return -EINVAL;
02b20b0b
MCC
710 }
711
712 // enable input is VIP/656
713 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
714 value |= 0x00040100; // enable VIP
715 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
bb4c9a74 716
02b20b0b
MCC
717 if (ret_val < 0)
718 {
bb4c9a74
MCC
719 mutex_unlock(&dev->lock);
720 return -EINVAL;
02b20b0b
MCC
721 }
722
bb4c9a74 723 // select AFE clock to output mode
02b20b0b
MCC
724 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
725 value &= 0x83FFFFFF;
bb4c9a74
MCC
726 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, value | 0x10000000);
727
02b20b0b
MCC
728 if (ret_val < 0)
729 {
bb4c9a74
MCC
730 mutex_unlock(&dev->lock);
731 return -EINVAL;
02b20b0b
MCC
732 }
733
734 // Turn on all of the data out and control output pins.
735 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
736 value &= 0xFEF0FE00;
737 if (_num_decoders == MAX_DECODERS)
738 {
bb4c9a74
MCC
739 // Note: The octal board does not support control pins(bit16-19).
740 // These bits are ignored in the octal board.
741 value |= 0x010001F8; // disable VDEC A-C port, default to Mobilygen Interface
02b20b0b
MCC
742 }
743 else
744 {
bb4c9a74 745 value |= 0x010F0108; // disable VDEC A-C port, default to Mobilygen Interface
02b20b0b 746 }
bb4c9a74 747
02b20b0b
MCC
748 value |= 7;
749 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
750 if (ret_val < 0)
751 {
bb4c9a74
MCC
752 mutex_unlock(&dev->lock);
753 return -EINVAL;
02b20b0b
MCC
754 }
755
756 mutex_unlock(&dev->lock);
757
bb4c9a74 758
02b20b0b
MCC
759 ret_val = medusa_set_videostandard(dev);
760
bb4c9a74 761
02b20b0b
MCC
762 if (ret_val < 0)
763 {
bb4c9a74
MCC
764 mutex_unlock(&dev->lock);
765 return -EINVAL;
766 }
767
02b20b0b
MCC
768 return 1;
769}