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

source code of linux/drivers/media/pci/cx25821/cx25821-medusa-video.c