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