V4L/DVB (10956): cx231xx: First series of manual CodingStyle fixes
[linux-2.6/x86.git] / drivers / media / video / cx231xx / cx231xx-avcore.c
blobbbfc78ebd94ba8a2fca3ff187a69bbd8f2e667c6
1 /*
2 cx231xx_avcore.c - driver for Conexant Cx23100/101/102
3 USB video capture devices
5 Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
7 This program contains the specific code to control the avdecoder chip and
8 other related usb control functions for cx231xx based chipset.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <linux/init.h>
26 #include <linux/list.h>
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/bitmap.h>
30 #include <linux/usb.h>
31 #include <linux/i2c.h>
32 #include <linux/version.h>
33 #include <linux/mm.h>
34 #include <linux/mutex.h>
36 #include <media/v4l2-common.h>
37 #include <media/v4l2-ioctl.h>
38 #include <media/v4l2-chip-ident.h>
40 #include "cx231xx.h"
42 /******************************************************************************
43 * C O L I B R I - B L O C K C O N T R O L functions *
44 ********************************************************************* ********/
45 int cx231xx_colibri_init_super_block(struct cx231xx *dev, u32 ref_count)
47 int status = 0;
48 u8 temp = 0;
49 u32 colibri_power_status = 0;
50 int i = 0;
52 /* super block initialize */
53 temp = (u8) (ref_count & 0xff);
54 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
55 SUP_BLK_TUNE2, 2, temp, 1);
57 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
58 SUP_BLK_TUNE2, 2,
59 &colibri_power_status, 1);
61 temp = (u8) ((ref_count & 0x300) >> 8);
62 temp |= 0x40;
63 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
64 SUP_BLK_TUNE1, 2, temp, 1);
65 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
66 SUP_BLK_PLL2, 2, 0x0f, 1);
68 /* enable pll */
69 while (colibri_power_status != 0x18) {
70 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
71 SUP_BLK_PWRDN, 2, 0x18, 1);
72 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
73 SUP_BLK_PWRDN, 2,
74 &colibri_power_status, 1);
75 colibri_power_status &= 0xff;
76 if (status < 0) {
77 cx231xx_info(": Init Super Block failed in sending/receiving cmds\n");
78 break;
80 i++;
81 if (i == 10) {
82 cx231xx_info(": Init Super Block force break in loop !!!!\n");
83 status = -1;
84 break;
88 if (status < 0)
89 return status;
91 /* start tuning filter */
92 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
93 SUP_BLK_TUNE3, 2, 0x40, 1);
94 msleep(5);
96 /* exit tuning */
97 status =
98 cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS, SUP_BLK_TUNE3,
99 2, 0x00, 1);
101 return status;
104 int cx231xx_colibri_init_channels(struct cx231xx *dev)
106 int status = 0;
108 /* power up all 3 channels, clear pd_buffer */
109 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
110 ADC_PWRDN_CLAMP_CH1, 2, 0x00, 1);
111 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
112 ADC_PWRDN_CLAMP_CH2, 2, 0x00, 1);
113 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
114 ADC_PWRDN_CLAMP_CH3, 2, 0x00, 1);
116 /* Enable quantizer calibration */
117 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
118 ADC_COM_QUANT, 2, 0x02, 1);
120 /* channel initialize, force modulator (fb) reset */
121 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
122 ADC_FB_FRCRST_CH1, 2, 0x17, 1);
123 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
124 ADC_FB_FRCRST_CH2, 2, 0x17, 1);
125 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
126 ADC_FB_FRCRST_CH3, 2, 0x17, 1);
128 /* start quantilizer calibration */
129 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
130 ADC_CAL_ATEST_CH1, 2, 0x10, 1);
131 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
132 ADC_CAL_ATEST_CH2, 2, 0x10, 1);
133 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
134 ADC_CAL_ATEST_CH3, 2, 0x10, 1);
135 msleep(5);
137 /* exit modulator (fb) reset */
138 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
139 ADC_FB_FRCRST_CH1, 2, 0x07, 1);
140 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
141 ADC_FB_FRCRST_CH2, 2, 0x07, 1);
142 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
143 ADC_FB_FRCRST_CH3, 2, 0x07, 1);
145 /* enable the pre_clamp in each channel for single-ended input */
146 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
147 ADC_NTF_PRECLMP_EN_CH1, 2, 0xf0, 1);
148 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
149 ADC_NTF_PRECLMP_EN_CH2, 2, 0xf0, 1);
150 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
151 ADC_NTF_PRECLMP_EN_CH3, 2, 0xf0, 1);
153 /* use diode instead of resistor, so set term_en to 0, res_en to 0 */
154 status = cx231xx_reg_mask_write(dev, Colibri_DEVICE_ADDRESS, 8,
155 ADC_QGAIN_RES_TRM_CH1, 3, 7, 0x00);
156 status = cx231xx_reg_mask_write(dev, Colibri_DEVICE_ADDRESS, 8,
157 ADC_QGAIN_RES_TRM_CH2, 3, 7, 0x00);
158 status = cx231xx_reg_mask_write(dev, Colibri_DEVICE_ADDRESS, 8,
159 ADC_QGAIN_RES_TRM_CH3, 3, 7, 0x00);
161 /* dynamic element matching off */
162 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
163 ADC_DCSERVO_DEM_CH1, 2, 0x03, 1);
164 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
165 ADC_DCSERVO_DEM_CH2, 2, 0x03, 1);
166 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
167 ADC_DCSERVO_DEM_CH3, 2, 0x03, 1);
169 return status;
172 int cx231xx_colibri_setup_AFE_for_baseband(struct cx231xx *dev)
174 u32 c_value = 0;
175 int status = 0;
177 status =
178 cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
179 ADC_PWRDN_CLAMP_CH2, 2, &c_value, 1);
180 c_value &= (~(0x50));
181 status =
182 cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
183 ADC_PWRDN_CLAMP_CH2, 2, c_value, 1);
185 return status;
189 we have 3 channel
190 channel 1 ----- pin 1 to pin4(in reg is 1-4)
191 channel 2 ----- pin 5 to pin8(in reg is 5-8)
192 channel 3 ----- pin 9 to pin 12(in reg is 9-11)
194 int cx231xx_colibri_set_input_mux(struct cx231xx *dev, u32 input_mux)
196 u8 ch1_setting = (u8) input_mux;
197 u8 ch2_setting = (u8) (input_mux >> 8);
198 u8 ch3_setting = (u8) (input_mux >> 16);
199 int status = 0;
200 u32 value = 0;
202 if (ch1_setting != 0) {
203 status =
204 cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
205 ADC_INPUT_CH1, 2, &value, 1);
206 value &= (!INPUT_SEL_MASK);
207 value |= (ch1_setting - 1) << 4;
208 value &= 0xff;
209 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
210 ADC_INPUT_CH1, 2, value, 1);
213 if (ch2_setting != 0) {
214 status =
215 cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
216 ADC_INPUT_CH2, 2, &value, 1);
217 value &= (!INPUT_SEL_MASK);
218 value |= (ch2_setting - 1) << 4;
219 value &= 0xff;
220 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
221 ADC_INPUT_CH2, 2, value, 1);
224 /* For ch3_setting, the value to put in the register is
225 7 less than the input number */
226 if (ch3_setting != 0) {
227 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
228 ADC_INPUT_CH3, 2, &value, 1);
229 value &= (!INPUT_SEL_MASK);
230 value |= (ch3_setting - 1) << 4;
231 value &= 0xff;
232 status = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS,
233 ADC_INPUT_CH3, 2, value, 1);
236 return status;
239 int cx231xx_colibri_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
241 int status = 0;
243 switch (mode) {
244 case AFE_MODE_LOW_IF:
245 /* SetupAFEforLowIF(); */
246 break;
247 case AFE_MODE_BASEBAND:
248 status = cx231xx_colibri_setup_AFE_for_baseband(dev);
249 break;
250 case AFE_MODE_EU_HI_IF:
251 /* SetupAFEforEuHiIF(); */
252 break;
253 case AFE_MODE_US_HI_IF:
254 /* SetupAFEforUsHiIF(); */
255 break;
256 case AFE_MODE_JAPAN_HI_IF:
257 /* SetupAFEforJapanHiIF(); */
258 break;
261 if ((mode != dev->colibri_mode) && (dev->video_input == CX231XX_VMUX_TELEVISION))
262 status = cx231xx_colibri_adjust_ref_count(dev,
263 CX231XX_VMUX_TELEVISION);
265 dev->colibri_mode = mode;
267 return status;
270 /* For power saving in the EVK */
271 int cx231xx_colibri_update_power_control(struct cx231xx *dev, AV_MODE avmode)
273 u32 colibri_power_status = 0;
274 int status = 0;
276 switch (dev->model) {
277 case CX231XX_BOARD_CNXT_RDE_250:
278 case CX231XX_BOARD_CNXT_RDU_250:
280 if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
281 while (colibri_power_status != 0x18) {
282 status = cx231xx_write_i2c_data(dev,
283 Colibri_DEVICE_ADDRESS,
284 SUP_BLK_PWRDN, 2,
285 0x18, 1);
286 status = cx231xx_read_i2c_data(dev,
287 Colibri_DEVICE_ADDRESS,
288 SUP_BLK_PWRDN, 2,
289 &colibri_power_status,
291 if (status < 0)
292 break;
295 status = cx231xx_write_i2c_data(dev,
296 Colibri_DEVICE_ADDRESS,
297 ADC_PWRDN_CLAMP_CH1, 2, 0x00,
299 status = cx231xx_write_i2c_data(dev,
300 Colibri_DEVICE_ADDRESS,
301 ADC_PWRDN_CLAMP_CH2, 2, 0x00,
303 status = cx231xx_write_i2c_data(dev,
304 Colibri_DEVICE_ADDRESS,
305 ADC_PWRDN_CLAMP_CH3, 2, 0x00,
307 } else if (avmode == POLARIS_AVMODE_DIGITAL) {
308 status = cx231xx_write_i2c_data(dev,
309 Colibri_DEVICE_ADDRESS,
310 ADC_PWRDN_CLAMP_CH1, 2, 0x70,
312 status = cx231xx_write_i2c_data(dev,
313 Colibri_DEVICE_ADDRESS,
314 ADC_PWRDN_CLAMP_CH2, 2, 0x70,
316 status = cx231xx_write_i2c_data(dev,
317 Colibri_DEVICE_ADDRESS,
318 ADC_PWRDN_CLAMP_CH3, 2, 0x70,
321 status = cx231xx_read_i2c_data(dev,
322 Colibri_DEVICE_ADDRESS,
323 SUP_BLK_PWRDN, 2,
324 &colibri_power_status, 1);
325 colibri_power_status |= 0x07;
326 status = cx231xx_write_i2c_data(dev,
327 Colibri_DEVICE_ADDRESS,
328 SUP_BLK_PWRDN, 2,
329 colibri_power_status, 1);
330 } else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
332 while (colibri_power_status != 0x18) {
333 status = cx231xx_write_i2c_data(dev,
334 Colibri_DEVICE_ADDRESS,
335 SUP_BLK_PWRDN, 2,
336 0x18, 1);
337 status = cx231xx_read_i2c_data(dev,
338 Colibri_DEVICE_ADDRESS,
339 SUP_BLK_PWRDN, 2,
340 &colibri_power_status,
342 if (status < 0)
343 break;
346 status = cx231xx_write_i2c_data(dev,
347 Colibri_DEVICE_ADDRESS,
348 ADC_PWRDN_CLAMP_CH1, 2, 0x00,
350 status = cx231xx_write_i2c_data(dev,
351 Colibri_DEVICE_ADDRESS,
352 ADC_PWRDN_CLAMP_CH2, 2, 0x00,
354 status = cx231xx_write_i2c_data(dev,
355 Colibri_DEVICE_ADDRESS,
356 ADC_PWRDN_CLAMP_CH3, 2, 0x00,
358 } else {
359 cx231xx_info("Invalid AV mode input\n");
360 status = -1;
362 break;
363 default:
364 if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
365 while (colibri_power_status != 0x18) {
366 status = cx231xx_write_i2c_data(dev,
367 Colibri_DEVICE_ADDRESS,
368 SUP_BLK_PWRDN, 2,
369 0x18, 1);
370 status = cx231xx_read_i2c_data(dev,
371 Colibri_DEVICE_ADDRESS,
372 SUP_BLK_PWRDN, 2,
373 &colibri_power_status,
375 if (status < 0)
376 break;
379 status = cx231xx_write_i2c_data(dev,
380 Colibri_DEVICE_ADDRESS,
381 ADC_PWRDN_CLAMP_CH1, 2,
382 0x40, 1);
383 status = cx231xx_write_i2c_data(dev,
384 Colibri_DEVICE_ADDRESS,
385 ADC_PWRDN_CLAMP_CH2, 2,
386 0x40, 1);
387 status = cx231xx_write_i2c_data(dev,
388 Colibri_DEVICE_ADDRESS,
389 ADC_PWRDN_CLAMP_CH3, 2,
390 0x00, 1);
391 } else if (avmode == POLARIS_AVMODE_DIGITAL) {
392 status = cx231xx_write_i2c_data(dev,
393 Colibri_DEVICE_ADDRESS,
394 ADC_PWRDN_CLAMP_CH1, 2,
395 0x70, 1);
396 status = cx231xx_write_i2c_data(dev,
397 Colibri_DEVICE_ADDRESS,
398 ADC_PWRDN_CLAMP_CH2, 2,
399 0x70, 1);
400 status = cx231xx_write_i2c_data(dev,
401 Colibri_DEVICE_ADDRESS,
402 ADC_PWRDN_CLAMP_CH3, 2,
403 0x70, 1);
405 status = cx231xx_read_i2c_data(dev,
406 Colibri_DEVICE_ADDRESS,
407 SUP_BLK_PWRDN, 2,
408 &colibri_power_status,
410 colibri_power_status |= 0x07;
411 status = cx231xx_write_i2c_data(dev,
412 Colibri_DEVICE_ADDRESS,
413 SUP_BLK_PWRDN, 2,
414 colibri_power_status,
416 } else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
417 while (colibri_power_status != 0x18) {
418 status = cx231xx_write_i2c_data(dev,
419 Colibri_DEVICE_ADDRESS,
420 SUP_BLK_PWRDN, 2,
421 0x18, 1);
422 status = cx231xx_read_i2c_data(dev,
423 Colibri_DEVICE_ADDRESS,
424 SUP_BLK_PWRDN, 2,
425 &colibri_power_status,
427 if (status < 0)
428 break;
431 status = cx231xx_write_i2c_data(dev,
432 Colibri_DEVICE_ADDRESS,
433 ADC_PWRDN_CLAMP_CH1, 2,
434 0x00, 1);
435 status = cx231xx_write_i2c_data(dev,
436 Colibri_DEVICE_ADDRESS,
437 ADC_PWRDN_CLAMP_CH2, 2,
438 0x00, 1);
439 status = cx231xx_write_i2c_data(dev,
440 Colibri_DEVICE_ADDRESS,
441 ADC_PWRDN_CLAMP_CH3, 2,
442 0x40, 1);
443 } else {
444 cx231xx_info("Invalid AV mode input\n");
445 status = -1;
447 } /* switch */
449 return status;
452 int cx231xx_colibri_adjust_ref_count(struct cx231xx *dev, u32 video_input)
454 u32 input_mode = 0;
455 u32 ntf_mode = 0;
456 int status = 0;
458 dev->video_input = video_input;
460 if (video_input == CX231XX_VMUX_TELEVISION) {
461 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
462 ADC_INPUT_CH3, 2, &input_mode, 1);
463 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
464 ADC_NTF_PRECLMP_EN_CH3, 2, &ntf_mode,
466 } else {
467 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
468 ADC_INPUT_CH1, 2, &input_mode, 1);
469 status = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
470 ADC_NTF_PRECLMP_EN_CH1, 2, &ntf_mode,
474 input_mode = (ntf_mode & 0x3) | ((input_mode & 0x6) << 1);
476 switch (input_mode) {
477 case SINGLE_ENDED:
478 dev->colibri_ref_count = 0x23C;
479 break;
480 case LOW_IF:
481 dev->colibri_ref_count = 0x24C;
482 break;
483 case EU_IF:
484 dev->colibri_ref_count = 0x258;
485 break;
486 case US_IF:
487 dev->colibri_ref_count = 0x260;
488 break;
489 default:
490 break;
493 status = cx231xx_colibri_init_super_block(dev, dev->colibri_ref_count);
495 return status;
498 /******************************************************************************
499 * V I D E O / A U D I O D E C O D E R C O N T R O L functions *
500 ******************************************++**********************************/
501 int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
503 int status = 0;
505 switch (INPUT(input)->type) {
506 case CX231XX_VMUX_COMPOSITE1:
507 case CX231XX_VMUX_SVIDEO:
508 if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
509 (dev->power_mode != POLARIS_AVMODE_ENXTERNAL_AV)) {
510 /* External AV */
511 status = cx231xx_set_power_mode(dev,
512 POLARIS_AVMODE_ENXTERNAL_AV);
513 if (status < 0) {
514 cx231xx_errdev("%s: cx231xx_set_power_mode : Failed to set Power - errCode [%d]!\n",
515 __func__, status);
516 return status;
519 status = cx231xx_set_decoder_video_input(dev,
520 INPUT(input)->type,
521 INPUT(input)->vmux);
522 break;
523 case CX231XX_VMUX_TELEVISION:
524 case CX231XX_VMUX_CABLE:
525 if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
526 (dev->power_mode != POLARIS_AVMODE_ANALOGT_TV)) {
527 /* Tuner */
528 status = cx231xx_set_power_mode(dev,
529 POLARIS_AVMODE_ANALOGT_TV);
530 if (status < 0) {
531 cx231xx_errdev("%s: cx231xx_set_power_mode : Failed to set Power - errCode [%d]!\n",
532 __func__, status);
533 return status;
536 status = cx231xx_set_decoder_video_input(dev,
537 CX231XX_VMUX_COMPOSITE1,
538 INPUT(input)->vmux);
539 break;
540 default:
541 cx231xx_errdev("%s: cx231xx_set_power_mode : Unknown Input %d !\n",
542 __func__, INPUT(input)->type);
543 break;
546 /* save the selection */
547 dev->video_input = input;
549 return status;
552 int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input)
554 int status = 0;
555 u32 value = 0;
557 if (pin_type != dev->video_input) {
558 status = cx231xx_colibri_adjust_ref_count(dev, pin_type);
559 if (status < 0) {
560 cx231xx_errdev("%s: cx231xx_colibri_adjust_ref_count :Failed to set Colibri input mux - errCode [%d]!\n",
561 __func__, status);
562 return status;
566 /* call colibri block to set video inputs */
567 status = cx231xx_colibri_set_input_mux(dev, input);
568 if (status < 0) {
569 cx231xx_errdev("%s: cx231xx_colibri_set_input_mux :Failed to set Colibri input mux - errCode [%d]!\n",
570 __func__, status);
571 return status;
574 switch (pin_type) {
575 case CX231XX_VMUX_COMPOSITE1:
576 status = cx231xx_read_i2c_data(dev,
577 HAMMERHEAD_I2C_ADDRESS,
578 AFE_CTRL, 2, &value, 4);
579 value |= (0 << 13) | (1 << 4);
580 value &= ~(1 << 5);
582 value &= (~(0x1ff8000)); /* set [24:23] [22:15] to 0 */
583 value |= 0x1000000; /* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
584 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
585 AFE_CTRL, 2, value, 4);
587 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
588 OUT_CTRL1, 2, &value, 4);
589 value |= (1 << 7);
590 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
591 OUT_CTRL1, 2, value, 4);
593 /* Set vip 1.1 output mode */
594 status = cx231xx_read_modify_write_i2c_dword(dev,
595 HAMMERHEAD_I2C_ADDRESS,
596 OUT_CTRL1,
597 FLD_OUT_MODE,
598 OUT_MODE_VIP11);
600 /* Tell DIF object to go to baseband mode */
601 status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
602 if (status < 0) {
603 cx231xx_errdev("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
604 __func__, status);
605 return status;
608 /* Read the DFE_CTRL1 register */
609 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
610 DFE_CTRL1, 2, &value, 4);
612 /* enable the VBI_GATE_EN */
613 value |= FLD_VBI_GATE_EN;
615 /* Enable the auto-VGA enable */
616 value |= FLD_VGA_AUTO_EN;
618 /* Write it back */
619 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
620 DFE_CTRL1, 2, value, 4);
622 /* Disable auto config of registers */
623 status = cx231xx_read_modify_write_i2c_dword(dev,
624 HAMMERHEAD_I2C_ADDRESS,
625 MODE_CTRL, FLD_ACFG_DIS,
626 cx231xx_set_field(FLD_ACFG_DIS, 1));
628 /* Set CVBS input mode */
629 status = cx231xx_read_modify_write_i2c_dword(dev,
630 HAMMERHEAD_I2C_ADDRESS,
631 MODE_CTRL, FLD_INPUT_MODE,
632 cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
633 break;
634 case CX231XX_VMUX_SVIDEO:
635 /* Disable the use of DIF */
637 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
638 AFE_CTRL, 2, &value, 4);
640 value &= (~(0x1ff8000)); /* set [24:23] [22:15] to 0 */
641 value |= 0x1000010; /* set FUNC_MODE[24:23] = 2
642 IF_MOD[22:15] = 0 DCR_BYP_CH2[4:4] = 1; */
643 status = cx231xx_write_i2c_data(dev,
644 HAMMERHEAD_I2C_ADDRESS,
645 AFE_CTRL, 2, value, 4);
647 /* Tell DIF object to go to baseband mode */
648 status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
649 if (status < 0) {
650 cx231xx_errdev("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
651 __func__, status);
652 return status;
655 /* Read the DFE_CTRL1 register */
656 status = cx231xx_read_i2c_data(dev,
657 HAMMERHEAD_I2C_ADDRESS,
658 DFE_CTRL1, 2, &value, 4);
660 /* enable the VBI_GATE_EN */
661 value |= FLD_VBI_GATE_EN;
663 /* Enable the auto-VGA enable */
664 value |= FLD_VGA_AUTO_EN;
666 /* Write it back */
667 status = cx231xx_write_i2c_data(dev,
668 HAMMERHEAD_I2C_ADDRESS,
669 DFE_CTRL1, 2, value, 4);
671 /* Disable auto config of registers */
672 status = cx231xx_read_modify_write_i2c_dword(dev,
673 HAMMERHEAD_I2C_ADDRESS,
674 MODE_CTRL, FLD_ACFG_DIS,
675 cx231xx_set_field(FLD_ACFG_DIS, 1));
677 /* Set YC input mode */
678 status = cx231xx_read_modify_write_i2c_dword(dev,
679 HAMMERHEAD_I2C_ADDRESS,
680 MODE_CTRL,
681 FLD_INPUT_MODE,
682 cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_YC_1));
684 /* Chroma to ADC2 */
685 status = cx231xx_read_i2c_data(dev,
686 HAMMERHEAD_I2C_ADDRESS,
687 AFE_CTRL, 2, &value, 4);
688 value |= FLD_CHROMA_IN_SEL; /* set the chroma in select */
690 /* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8)
691 This sets them to use video
692 rather than audio. Only one of the two will be in use. */
693 value &= ~(FLD_VGA_SEL_CH2 | FLD_VGA_SEL_CH3);
695 status = cx231xx_write_i2c_data(dev,
696 HAMMERHEAD_I2C_ADDRESS,
697 AFE_CTRL, 2, value, 4);
699 status = cx231xx_colibri_set_mode(dev, AFE_MODE_BASEBAND);
700 break;
701 case CX231XX_VMUX_TELEVISION:
702 case CX231XX_VMUX_CABLE:
703 default:
704 switch (dev->model) {
705 case CX231XX_BOARD_CNXT_RDE_250:
706 case CX231XX_BOARD_CNXT_RDU_250:
707 /* Disable the use of DIF */
709 status = cx231xx_read_i2c_data(dev,
710 HAMMERHEAD_I2C_ADDRESS,
711 AFE_CTRL, 2,
712 &value, 4);
713 value |= (0 << 13) | (1 << 4);
714 value &= ~(1 << 5);
716 value &= (~(0x1FF8000)); /* set [24:23] [22:15] to 0 */
717 value |= 0x1000000; /* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
718 status = cx231xx_write_i2c_data(dev,
719 HAMMERHEAD_I2C_ADDRESS,
720 AFE_CTRL, 2,
721 value, 4);
723 status = cx231xx_read_i2c_data(dev,
724 HAMMERHEAD_I2C_ADDRESS,
725 OUT_CTRL1, 2,
726 &value, 4);
727 value |= (1 << 7);
728 status = cx231xx_write_i2c_data(dev,
729 HAMMERHEAD_I2C_ADDRESS,
730 OUT_CTRL1, 2,
731 value, 4);
733 /* Set vip 1.1 output mode */
734 status = cx231xx_read_modify_write_i2c_dword(dev,
735 HAMMERHEAD_I2C_ADDRESS,
736 OUT_CTRL1, FLD_OUT_MODE,
737 OUT_MODE_VIP11);
739 /* Tell DIF object to go to baseband mode */
740 status = cx231xx_dif_set_standard(dev,
741 DIF_USE_BASEBAND);
742 if (status < 0) {
743 cx231xx_errdev("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
744 __func__, status);
745 return status;
748 /* Read the DFE_CTRL1 register */
749 status = cx231xx_read_i2c_data(dev,
750 HAMMERHEAD_I2C_ADDRESS,
751 DFE_CTRL1, 2,
752 &value, 4);
754 /* enable the VBI_GATE_EN */
755 value |= FLD_VBI_GATE_EN;
757 /* Enable the auto-VGA enable */
758 value |= FLD_VGA_AUTO_EN;
760 /* Write it back */
761 status = cx231xx_write_i2c_data(dev,
762 HAMMERHEAD_I2C_ADDRESS,
763 DFE_CTRL1, 2,
764 value, 4);
766 /* Disable auto config of registers */
767 status = cx231xx_read_modify_write_i2c_dword(dev,
768 HAMMERHEAD_I2C_ADDRESS,
769 MODE_CTRL, FLD_ACFG_DIS,
770 cx231xx_set_field(FLD_ACFG_DIS, 1));
772 /* Set CVBS input mode */
773 status = cx231xx_read_modify_write_i2c_dword(dev,
774 HAMMERHEAD_I2C_ADDRESS,
775 MODE_CTRL, FLD_INPUT_MODE,
776 cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
777 break;
778 default:
779 /* Enable the DIF for the tuner */
781 /* Reinitialize the DIF */
782 status = cx231xx_dif_set_standard(dev, dev->norm);
783 if (status < 0) {
784 cx231xx_errdev("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
785 __func__, status);
786 return status;
789 /* Make sure bypass is cleared */
790 status = cx231xx_read_i2c_data(dev,
791 HAMMERHEAD_I2C_ADDRESS,
792 DIF_MISC_CTRL,
793 2, &value, 4);
795 /* Clear the bypass bit */
796 value &= ~FLD_DIF_DIF_BYPASS;
798 /* Enable the use of the DIF block */
799 status = cx231xx_write_i2c_data(dev,
800 HAMMERHEAD_I2C_ADDRESS,
801 DIF_MISC_CTRL,
802 2, value, 4);
804 /* Read the DFE_CTRL1 register */
805 status = cx231xx_read_i2c_data(dev,
806 HAMMERHEAD_I2C_ADDRESS,
807 DFE_CTRL1, 2,
808 &value, 4);
810 /* Disable the VBI_GATE_EN */
811 value &= ~FLD_VBI_GATE_EN;
813 /* Enable the auto-VGA enable, AGC, and
814 set the skip count to 2 */
815 value |= FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000;
817 /* Write it back */
818 status = cx231xx_write_i2c_data(dev,
819 HAMMERHEAD_I2C_ADDRESS,
820 DFE_CTRL1, 2,
821 value, 4);
823 /* Wait 15 ms */
824 msleep(1);
826 /* Disable the auto-VGA enable AGC */
827 value &= ~(FLD_VGA_AUTO_EN);
829 /* Write it back */
830 status = cx231xx_write_i2c_data(dev,
831 HAMMERHEAD_I2C_ADDRESS,
832 DFE_CTRL1, 2,
833 value, 4);
835 /* Enable Polaris B0 AGC output */
836 status = cx231xx_read_i2c_data(dev,
837 HAMMERHEAD_I2C_ADDRESS,
838 PIN_CTRL, 2,
839 &value, 4);
840 value |= (FLD_OEF_AGC_RF) |
841 (FLD_OEF_AGC_IFVGA) |
842 (FLD_OEF_AGC_IF);
843 status = cx231xx_write_i2c_data(dev,
844 HAMMERHEAD_I2C_ADDRESS,
845 PIN_CTRL, 2,
846 value, 4);
848 /* Set vip 1.1 output mode */
849 status = cx231xx_read_modify_write_i2c_dword(dev,
850 HAMMERHEAD_I2C_ADDRESS,
851 OUT_CTRL1, FLD_OUT_MODE,
852 OUT_MODE_VIP11);
854 /* Disable auto config of registers */
855 status = cx231xx_read_modify_write_i2c_dword(dev,
856 HAMMERHEAD_I2C_ADDRESS,
857 MODE_CTRL, FLD_ACFG_DIS,
858 cx231xx_set_field(FLD_ACFG_DIS, 1));
860 /* Set CVBS input mode */
861 status = cx231xx_read_modify_write_i2c_dword(dev,
862 HAMMERHEAD_I2C_ADDRESS,
863 MODE_CTRL, FLD_INPUT_MODE,
864 cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
866 /* Set some bits in AFE_CTRL so that channel 2 or 3 is ready to receive audio */
867 /* Clear clamp for channels 2 and 3 (bit 16-17) */
868 /* Clear droop comp (bit 19-20) */
869 /* Set VGA_SEL (for audio control) (bit 7-8) */
870 status = cx231xx_read_i2c_data(dev,
871 HAMMERHEAD_I2C_ADDRESS,
872 AFE_CTRL, 2,
873 &value, 4);
875 value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;
877 status = cx231xx_write_i2c_data(dev,
878 HAMMERHEAD_I2C_ADDRESS,
879 AFE_CTRL, 2,
880 value, 4);
881 break;
884 break;
887 /* Set raw VBI mode */
888 status = cx231xx_read_modify_write_i2c_dword(dev,
889 HAMMERHEAD_I2C_ADDRESS,
890 OUT_CTRL1, FLD_VBIHACTRAW_EN,
891 cx231xx_set_field(FLD_VBIHACTRAW_EN, 1));
893 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
894 OUT_CTRL1, 2,
895 &value, 4);
896 if (value & 0x02) {
897 value |= (1 << 19);
898 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
899 OUT_CTRL1, 2, value, 4);
902 return status;
906 * Handle any video-mode specific overrides that are different on a per video standards
907 * basis after touching the MODE_CTRL register which resets many values for autodetect
909 int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
911 int status = 0;
913 cx231xx_info("do_mode_ctrl_overrides : 0x%x\n",
914 (unsigned int)dev->norm);
916 /* Change the DFE_CTRL3 bp_percent to fix flagging */
917 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
918 DFE_CTRL3, 2,
919 0xCD3F0280, 4);
921 if (dev->norm & (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_PAL_M)) {
922 cx231xx_info("do_mode_ctrl_overrides NTSC\n");
924 /* Move the close caption lines out of active video,
925 adjust the active video start point */
926 status = cx231xx_read_modify_write_i2c_dword(dev,
927 HAMMERHEAD_I2C_ADDRESS,
928 VERT_TIM_CTRL,
929 FLD_VBLANK_CNT, 0x18);
930 status = cx231xx_read_modify_write_i2c_dword(dev,
931 HAMMERHEAD_I2C_ADDRESS,
932 VERT_TIM_CTRL,
933 FLD_VACTIVE_CNT,
934 0x1E6000);
935 status = cx231xx_read_modify_write_i2c_dword(dev,
936 HAMMERHEAD_I2C_ADDRESS,
937 VERT_TIM_CTRL,
938 FLD_V656BLANK_CNT,
939 0x1E000000);
941 status = cx231xx_read_modify_write_i2c_dword(dev,
942 HAMMERHEAD_I2C_ADDRESS,
943 HORIZ_TIM_CTRL,
944 FLD_HBLANK_CNT,
945 cx231xx_set_field
946 (FLD_HBLANK_CNT, 0x79));
947 } else if (dev->norm & (V4L2_STD_PAL_B | V4L2_STD_PAL_G |
948 V4L2_STD_PAL_D | V4L2_STD_PAL_I |
949 V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
950 cx231xx_info("do_mode_ctrl_overrides PAL\n");
951 status = cx231xx_read_modify_write_i2c_dword(dev,
952 HAMMERHEAD_I2C_ADDRESS,
953 VERT_TIM_CTRL,
954 FLD_VBLANK_CNT, 0x24);
955 /* Adjust the active video horizontal start point */
956 status = cx231xx_read_modify_write_i2c_dword(dev,
957 HAMMERHEAD_I2C_ADDRESS,
958 HORIZ_TIM_CTRL,
959 FLD_HBLANK_CNT,
960 cx231xx_set_field
961 (FLD_HBLANK_CNT, 0x85));
962 } else if (dev->norm & (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D |
963 V4L2_STD_SECAM_G | V4L2_STD_SECAM_K |
964 V4L2_STD_SECAM_K1 | V4L2_STD_SECAM_L |
965 V4L2_STD_SECAM_LC)) {
966 cx231xx_info("do_mode_ctrl_overrides SECAM\n");
967 status = cx231xx_read_modify_write_i2c_dword(dev,
968 HAMMERHEAD_I2C_ADDRESS,
969 VERT_TIM_CTRL,
970 FLD_VBLANK_CNT, 0x24);
971 /* Adjust the active video horizontal start point */
972 status = cx231xx_read_modify_write_i2c_dword(dev,
973 HAMMERHEAD_I2C_ADDRESS,
974 HORIZ_TIM_CTRL,
975 FLD_HBLANK_CNT,
976 cx231xx_set_field
977 (FLD_HBLANK_CNT, 0x85));
980 return status;
983 int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
985 int status = 0;
986 enum AUDIO_INPUT ainput = AUDIO_INPUT_LINE;
988 switch (INPUT(input)->amux) {
989 case CX231XX_AMUX_VIDEO:
990 ainput = AUDIO_INPUT_TUNER_TV;
991 break;
992 case CX231XX_AMUX_LINE_IN:
993 status = cx231xx_flatiron_set_audio_input(dev, input);
994 ainput = AUDIO_INPUT_LINE;
995 break;
996 default:
997 break;
1000 status = cx231xx_set_audio_decoder_input(dev, ainput);
1002 return status;
1005 int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
1006 enum AUDIO_INPUT audio_input)
1008 u32 dwval;
1009 int status;
1010 u32 gen_ctrl;
1011 u32 value = 0;
1013 /* Put it in soft reset */
1014 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1015 GENERAL_CTL, 2, &gen_ctrl, 1);
1016 gen_ctrl |= 1;
1017 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1018 GENERAL_CTL, 2, gen_ctrl, 1);
1020 switch (audio_input) {
1021 case AUDIO_INPUT_LINE:
1022 /* setup AUD_IO control from Merlin paralle output */
1023 value = cx231xx_set_field(FLD_AUD_CHAN1_SRC,
1024 AUD_CHAN_SRC_PARALLEL);
1025 status = cx231xx_write_i2c_data(dev,
1026 HAMMERHEAD_I2C_ADDRESS,
1027 AUD_IO_CTRL, 2, value, 4);
1029 /* setup input to Merlin, SRC2 connect to AC97
1030 bypass upsample-by-2, slave mode, sony mode, left justify
1031 adr 091c, dat 01000000 */
1032 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1033 AC97_CTL,
1034 2, &dwval, 4);
1036 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1037 AC97_CTL, 2,
1038 (dwval | FLD_AC97_UP2X_BYPASS), 4);
1040 /* select the parallel1 and SRC3 */
1041 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1042 BAND_OUT_SEL, 2,
1043 cx231xx_set_field(FLD_SRC3_IN_SEL, 0x0) |
1044 cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x0) |
1045 cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x0),
1048 /* unmute all, AC97 in, independence mode
1049 adr 08d0, data 0x00063073 */
1050 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1051 PATH1_CTL1, 2, 0x00063073, 4);
1053 /* set AVC maximum threshold, adr 08d4, dat ffff0024 */
1054 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1055 PATH1_VOL_CTL, 2, &dwval, 4);
1056 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1057 PATH1_VOL_CTL, 2,
1058 (dwval | FLD_PATH1_AVC_THRESHOLD),
1061 /* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
1062 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1063 PATH1_SC_CTL, 2, &dwval, 4);
1064 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1065 PATH1_SC_CTL, 2,
1066 (dwval | FLD_PATH1_SC_THRESHOLD), 4);
1067 break;
1069 case AUDIO_INPUT_TUNER_TV:
1070 default:
1072 /* Setup SRC sources and clocks */
1073 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1074 BAND_OUT_SEL, 2,
1075 cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00) |
1076 cx231xx_set_field(FLD_SRC6_CLK_SEL, 0x01) |
1077 cx231xx_set_field(FLD_SRC5_IN_SEL, 0x00) |
1078 cx231xx_set_field(FLD_SRC5_CLK_SEL, 0x02) |
1079 cx231xx_set_field(FLD_SRC4_IN_SEL, 0x02) |
1080 cx231xx_set_field(FLD_SRC4_CLK_SEL, 0x03) |
1081 cx231xx_set_field(FLD_SRC3_IN_SEL, 0x00) |
1082 cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x00) |
1083 cx231xx_set_field(FLD_BASEBAND_BYPASS_CTL, 0x00) |
1084 cx231xx_set_field(FLD_AC97_SRC_SEL, 0x03) |
1085 cx231xx_set_field(FLD_I2S_SRC_SEL, 0x00) |
1086 cx231xx_set_field(FLD_PARALLEL2_SRC_SEL, 0x02) |
1087 cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x01), 4);
1089 /* Setup the AUD_IO control */
1090 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1091 AUD_IO_CTRL, 2,
1092 cx231xx_set_field(FLD_I2S_PORT_DIR, 0x00) |
1093 cx231xx_set_field(FLD_I2S_OUT_SRC, 0x00) |
1094 cx231xx_set_field(FLD_AUD_CHAN3_SRC, 0x00) |
1095 cx231xx_set_field(FLD_AUD_CHAN2_SRC, 0x00) |
1096 cx231xx_set_field(FLD_AUD_CHAN1_SRC, 0x03), 4);
1098 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1099 PATH1_CTL1, 2, 0x1F063870, 4);
1101 /* setAudioStandard(_audio_standard); */
1103 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1104 PATH1_CTL1, 2, 0x00063870, 4);
1105 switch (dev->model) {
1106 case CX231XX_BOARD_CNXT_RDE_250:
1107 case CX231XX_BOARD_CNXT_RDU_250:
1108 status = cx231xx_read_modify_write_i2c_dword(dev,
1109 HAMMERHEAD_I2C_ADDRESS,
1110 CHIP_CTRL,
1111 FLD_SIF_EN,
1112 cx231xx_set_field(FLD_SIF_EN, 1));
1113 break;
1114 default:
1115 break;
1117 break;
1119 case AUDIO_INPUT_TUNER_FM:
1120 /* use SIF for FM radio
1121 setupFM();
1122 setAudioStandard(_audio_standard);
1124 break;
1126 case AUDIO_INPUT_MUTE:
1127 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1128 PATH1_CTL1, 2, 0x1F011012, 4);
1129 break;
1132 /* Take it out of soft reset */
1133 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1134 GENERAL_CTL, 2, &gen_ctrl, 1);
1135 gen_ctrl &= ~1;
1136 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1137 GENERAL_CTL, 2, gen_ctrl, 1);
1139 return status;
1142 /* Set resolution of the video */
1143 int cx231xx_resolution_set(struct cx231xx *dev)
1145 int width, height;
1146 u32 hscale, vscale;
1147 int status = 0;
1149 width = dev->width;
1150 height = dev->height;
1152 get_scale(dev, width, height, &hscale, &vscale);
1154 /* set horzontal scale */
1155 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1156 HSCALE_CTRL, 2, hscale, 4);
1158 /* set vertical scale */
1159 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1160 VSCALE_CTRL, 2, vscale, 4);
1162 return status;
1165 /******************************************************************************
1166 * C H I P Specific C O N T R O L functions *
1167 ******************************************************************************/
1168 int cx231xx_init_ctrl_pin_status(struct cx231xx *dev)
1170 u32 value;
1171 int status = 0;
1173 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, PIN_CTRL,
1174 2, &value, 4);
1175 value |= (~dev->board.ctl_pin_status_mask);
1176 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, PIN_CTRL,
1177 2, value, 4);
1179 return status;
1182 int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
1183 u8 analog_or_digital)
1185 int status = 0;
1187 /* first set the direction to output */
1188 status = cx231xx_set_gpio_direction(dev,
1189 dev->board.
1190 agc_analog_digital_select_gpio, 1);
1192 /* 0 - demod ; 1 - Analog mode */
1193 status = cx231xx_set_gpio_value(dev,
1194 dev->board.agc_analog_digital_select_gpio,
1195 analog_or_digital);
1197 return status;
1200 int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex)
1202 u8 value[4] = { 0, 0, 0, 0 };
1203 int status = 0;
1205 cx231xx_info("Changing the i2c port for tuner to %d\n", I2CIndex);
1207 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
1208 PWR_CTL_EN, value, 4);
1209 if (status < 0)
1210 return status;
1212 if (I2CIndex == I2C_1) {
1213 if (value[0] & I2C_DEMOD_EN) {
1214 value[0] &= ~I2C_DEMOD_EN;
1215 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1216 PWR_CTL_EN, value, 4);
1218 } else {
1219 if (!(value[0] & I2C_DEMOD_EN)) {
1220 value[0] |= I2C_DEMOD_EN;
1221 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1222 PWR_CTL_EN, value, 4);
1226 return status;
1230 /******************************************************************************
1231 * D I F - B L O C K C O N T R O L functions *
1232 ******************************************************************************/
1233 int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
1234 u32 function_mode, u32 standard)
1236 int status = 0;
1238 if (mode == V4L2_TUNER_RADIO) {
1239 /* C2HH */
1240 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1241 AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); /* lo if big signal */
1242 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1243 AFE_CTRL_C2HH_SRC_CTRL, 23, 24, function_mode); /* FUNC_MODE = DIF */
1244 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1245 AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF); /* IF_MODE */
1246 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1247 AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); /* no inv */
1248 } else {
1249 switch (standard) {
1250 case V4L2_STD_NTSC_M: /* 75 IRE Setup */
1251 case V4L2_STD_NTSC_M_JP: /* Japan, 0 IRE Setup */
1252 case V4L2_STD_PAL_M:
1253 case V4L2_STD_PAL_N:
1254 case V4L2_STD_PAL_Nc:
1255 status = cx231xx_reg_mask_write(dev,
1256 HAMMERHEAD_I2C_ADDRESS, 32,
1257 AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); /* lo if big signal */
1258 status = cx231xx_reg_mask_write(dev,
1259 HAMMERHEAD_I2C_ADDRESS, 32,
1260 AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1261 function_mode); /* FUNC_MODE = DIF */
1262 status = cx231xx_reg_mask_write(dev,
1263 HAMMERHEAD_I2C_ADDRESS, 32,
1264 AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb); /* IF_MODE */
1265 status = cx231xx_reg_mask_write(dev,
1266 HAMMERHEAD_I2C_ADDRESS, 32,
1267 AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); /* no inv */
1268 status = cx231xx_reg_mask_write(dev,
1269 HAMMERHEAD_I2C_ADDRESS, 32,
1270 AUD_IO_CTRL, 0, 31, 0x00000003); /* 0x124, AUD_CHAN1_SRC = 0x3 */
1271 break;
1273 case V4L2_STD_PAL_B:
1274 case V4L2_STD_PAL_G:
1275 /* C2HH setup */
1276 status = cx231xx_reg_mask_write(dev,
1277 HAMMERHEAD_I2C_ADDRESS, 32,
1278 AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); /* lo if big signal */
1279 status = cx231xx_reg_mask_write(dev,
1280 HAMMERHEAD_I2C_ADDRESS, 32,
1281 AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1282 function_mode); /* FUNC_MODE = DIF */
1283 status = cx231xx_reg_mask_write(dev,
1284 HAMMERHEAD_I2C_ADDRESS, 32,
1285 AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE); /* IF_MODE */
1286 status = cx231xx_reg_mask_write(dev,
1287 HAMMERHEAD_I2C_ADDRESS, 32,
1288 AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); /* no inv */
1289 break;
1291 case V4L2_STD_PAL_D:
1292 case V4L2_STD_PAL_I:
1293 case V4L2_STD_SECAM_L:
1294 case V4L2_STD_SECAM_LC:
1295 case V4L2_STD_SECAM_B:
1296 case V4L2_STD_SECAM_D:
1297 case V4L2_STD_SECAM_G:
1298 case V4L2_STD_SECAM_K:
1299 case V4L2_STD_SECAM_K1:
1300 /* C2HH setup */
1301 status = cx231xx_reg_mask_write(dev,
1302 HAMMERHEAD_I2C_ADDRESS, 32,
1303 AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); /* lo if big signal */
1304 status = cx231xx_reg_mask_write(dev,
1305 HAMMERHEAD_I2C_ADDRESS, 32,
1306 AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1307 function_mode); /* FUNC_MODE = DIF */
1308 status = cx231xx_reg_mask_write(dev,
1309 HAMMERHEAD_I2C_ADDRESS, 32,
1310 AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF); /* IF_MODE */
1311 status = cx231xx_reg_mask_write(dev,
1312 HAMMERHEAD_I2C_ADDRESS, 32,
1313 AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); /* no inv */
1314 break;
1316 case DIF_USE_BASEBAND:
1317 default:
1318 /* do nothing to config C2HH for baseband */
1319 break;
1323 return status;
1326 int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
1328 int status = 0;
1329 u32 dif_misc_ctrl_value = 0;
1330 u32 func_mode = 0;
1332 cx231xx_info("%s: setStandard to %x\n", __func__, standard);
1334 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1335 DIF_MISC_CTRL, 2, &dif_misc_ctrl_value,
1337 if (standard != DIF_USE_BASEBAND)
1338 dev->norm = standard;
1340 switch (dev->model) {
1341 case CX231XX_BOARD_CNXT_RDE_250:
1342 case CX231XX_BOARD_CNXT_RDU_250:
1343 func_mode = 0x03;
1344 break;
1345 default:
1346 func_mode = 0x01;
1349 status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
1350 func_mode, standard);
1352 if (standard == DIF_USE_BASEBAND) { /* base band */
1353 /* There is a different SRC_PHASE_INC value
1354 for baseband vs. DIF */
1355 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1356 DIF_SRC_PHASE_INC, 2, 0xDF7DF83,
1358 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1359 DIF_MISC_CTRL, 2,
1360 &dif_misc_ctrl_value, 4);
1361 dif_misc_ctrl_value |= FLD_DIF_DIF_BYPASS;
1362 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1363 DIF_MISC_CTRL, 2,
1364 dif_misc_ctrl_value, 4);
1366 } else if (standard & (V4L2_STD_PAL_B | V4L2_STD_PAL_G)) {
1368 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1369 DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1370 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1371 DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1372 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1373 DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1374 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1375 DIF_PLL_CTRL3, 0, 31, 0x00008800);
1376 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1377 DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1378 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1379 DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1380 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1381 DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1382 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1383 DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1384 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1385 DIF_AGC_IF_INT_CURRENT, 0, 31,
1386 0x26001700);
1387 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1388 DIF_AGC_RF_CURRENT, 0, 31,
1389 0x00002660);
1390 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1391 DIF_VIDEO_AGC_CTRL, 0, 31,
1392 0x72500800);
1393 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1394 DIF_VID_AUD_OVERRIDE, 0, 31,
1395 0x27000100);
1396 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1397 DIF_AV_SEP_CTRL, 0, 31, 0x3F3530EC);
1398 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1399 DIF_COMP_FLT_CTRL, 0, 31,
1400 0x00A653A8);
1401 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1402 DIF_SRC_PHASE_INC, 0, 31,
1403 0x1befbf06);
1404 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1405 DIF_SRC_GAIN_CONTROL, 0, 31,
1406 0x000035e8);
1407 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1408 DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1409 /* Save the Spec Inversion value */
1410 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1411 dif_misc_ctrl_value |= 0x3a013F11;
1413 } else if (standard & V4L2_STD_PAL_D) {
1414 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1415 DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1416 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1417 DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1418 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1419 DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1420 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1421 DIF_PLL_CTRL3, 0, 31, 0x00008800);
1422 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1423 DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1424 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1425 DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1426 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1427 DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1428 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1429 DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1430 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1431 DIF_AGC_IF_INT_CURRENT, 0, 31,
1432 0x26001700);
1433 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1434 DIF_AGC_RF_CURRENT, 0, 31,
1435 0x00002660);
1436 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1437 DIF_VIDEO_AGC_CTRL, 0, 31,
1438 0x72500800);
1439 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1440 DIF_VID_AUD_OVERRIDE, 0, 31,
1441 0x27000100);
1442 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1443 DIF_AV_SEP_CTRL, 0, 31, 0x3F3934EA);
1444 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1445 DIF_COMP_FLT_CTRL, 0, 31,
1446 0x00000000);
1447 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1448 DIF_SRC_PHASE_INC, 0, 31,
1449 0x1befbf06);
1450 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1451 DIF_SRC_GAIN_CONTROL, 0, 31,
1452 0x000035e8);
1453 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1454 DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1455 /* Save the Spec Inversion value */
1456 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1457 dif_misc_ctrl_value |= 0x3a023F11;
1459 } else if (standard & V4L2_STD_PAL_I) {
1461 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1462 DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1463 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1464 DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1465 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1466 DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1467 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1468 DIF_PLL_CTRL3, 0, 31, 0x00008800);
1469 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1470 DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1471 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1472 DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1473 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1474 DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1475 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1476 DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1477 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1478 DIF_AGC_IF_INT_CURRENT, 0, 31,
1479 0x26001700);
1480 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1481 DIF_AGC_RF_CURRENT, 0, 31,
1482 0x00002660);
1483 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1484 DIF_VIDEO_AGC_CTRL, 0, 31,
1485 0x72500800);
1486 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1487 DIF_VID_AUD_OVERRIDE, 0, 31,
1488 0x27000100);
1489 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1490 DIF_AV_SEP_CTRL, 0, 31, 0x5F39A934);
1491 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1492 DIF_COMP_FLT_CTRL, 0, 31,
1493 0x00000000);
1494 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1495 DIF_SRC_PHASE_INC, 0, 31,
1496 0x1befbf06);
1497 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1498 DIF_SRC_GAIN_CONTROL, 0, 31,
1499 0x000035e8);
1500 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1501 DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1502 /* Save the Spec Inversion value */
1503 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1504 dif_misc_ctrl_value |= 0x3a033F11;
1506 } else if (standard & V4L2_STD_PAL_M) {
1507 /* improved Low Frequency Phase Noise */
1508 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1509 DIF_PLL_CTRL, 2, 0xFF01FF0C, 4);
1510 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1511 DIF_PLL_CTRL1, 2, 0xbd038c85,
1513 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1514 DIF_PLL_CTRL2, 2, 0x1db4640a, 4);
1515 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1516 DIF_PLL_CTRL3, 2, 0x00008800, 4);
1517 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1518 DIF_AGC_IF_REF, 2, 0x444C1380, 4);
1519 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1520 DIF_AGC_IF_INT_CURRENT, 2,
1521 0x26001700, 4);
1522 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1523 DIF_AGC_RF_CURRENT, 2, 0x00002660,
1525 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1526 DIF_VIDEO_AGC_CTRL, 2, 0x72500800,
1528 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1529 DIF_VID_AUD_OVERRIDE, 2, 0x27000100,
1531 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1532 DIF_AV_SEP_CTRL, 2, 0x012c405d, 4);
1533 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1534 DIF_COMP_FLT_CTRL, 2, 0x009f50c1, 4);
1535 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1536 DIF_SRC_PHASE_INC, 2, 0x1befbf06, 4);
1537 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1538 DIF_SRC_GAIN_CONTROL, 2, 0x000035e8,
1540 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1541 DIF_SOFT_RST_CTRL_REVB, 2,
1542 0x00000000, 4);
1544 /* Save the Spec Inversion value */
1545 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1546 dif_misc_ctrl_value |= 0x3A0A3F10;
1548 } else if (standard & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
1550 /* improved Low Frequency Phase Noise */
1551 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1552 DIF_PLL_CTRL, 2, 0xFF01FF0C, 4);
1553 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1554 DIF_PLL_CTRL1, 2, 0xbd038c85, 4);
1555 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1556 DIF_PLL_CTRL2, 2, 0x1db4640a, 4);
1557 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1558 DIF_PLL_CTRL3, 2, 0x00008800, 4);
1559 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1560 DIF_AGC_IF_REF, 2, 0x444C1380, 4);
1561 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1562 DIF_AGC_IF_INT_CURRENT, 2,
1563 0x26001700, 4);
1564 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1565 DIF_AGC_RF_CURRENT, 2, 0x00002660,
1567 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1568 DIF_VIDEO_AGC_CTRL, 2, 0x72500800,
1570 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1571 DIF_VID_AUD_OVERRIDE, 2, 0x27000100,
1573 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1574 DIF_AV_SEP_CTRL, 2, 0x012c405d, 4);
1575 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1576 DIF_COMP_FLT_CTRL, 2, 0x009f50c1, 4);
1577 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1578 DIF_SRC_PHASE_INC, 2, 0x1befbf06, 4);
1579 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1580 DIF_SRC_GAIN_CONTROL, 2, 0x000035e8,
1582 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1583 DIF_SOFT_RST_CTRL_REVB, 2,
1584 0x00000000, 4);
1586 /* Save the Spec Inversion value */
1587 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1588 dif_misc_ctrl_value = 0x3A093F10;
1590 } else if (standard &
1591 (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
1592 V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)) {
1594 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1595 DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1596 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1597 DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1598 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1599 DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1600 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1601 DIF_PLL_CTRL3, 0, 31, 0x00008800);
1602 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1603 DIF_AGC_IF_REF, 0, 31, 0x888C0380);
1604 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1605 DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
1606 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1607 DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
1608 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1609 DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
1610 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1611 DIF_AGC_IF_INT_CURRENT, 0, 31,
1612 0x26001700);
1613 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1614 DIF_AGC_RF_CURRENT, 0, 31,
1615 0x00002660);
1616 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1617 DIF_VID_AUD_OVERRIDE, 0, 31,
1618 0x27000100);
1619 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1620 DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
1621 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1622 DIF_COMP_FLT_CTRL, 0, 31,
1623 0x00000000);
1624 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1625 DIF_SRC_PHASE_INC, 0, 31,
1626 0x1befbf06);
1627 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1628 DIF_SRC_GAIN_CONTROL, 0, 31,
1629 0x000035e8);
1630 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1631 DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1632 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1633 DIF_VIDEO_AGC_CTRL, 0, 31,
1634 0xf4000000);
1636 /* Save the Spec Inversion value */
1637 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1638 dif_misc_ctrl_value |= 0x3a023F11;
1640 } else if (standard & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) {
1642 /* Is it SECAM_L1? */
1643 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1644 DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1645 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1646 DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1647 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1648 DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1649 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1650 DIF_PLL_CTRL3, 0, 31, 0x00008800);
1651 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1652 DIF_AGC_IF_REF, 0, 31, 0x888C0380);
1653 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1654 DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
1655 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1656 DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
1657 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1658 DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
1659 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1660 DIF_AGC_IF_INT_CURRENT, 0, 31,
1661 0x26001700);
1662 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1663 DIF_AGC_RF_CURRENT, 0, 31,
1664 0x00002660);
1665 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1666 DIF_VID_AUD_OVERRIDE, 0, 31,
1667 0x27000100);
1668 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1669 DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
1670 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1671 DIF_COMP_FLT_CTRL, 0, 31,
1672 0x00000000);
1673 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1674 DIF_SRC_PHASE_INC, 0, 31,
1675 0x1befbf06);
1676 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1677 DIF_SRC_GAIN_CONTROL, 0, 31,
1678 0x000035e8);
1679 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1680 DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1681 status = cx231xx_reg_mask_write(dev, HAMMERHEAD_I2C_ADDRESS, 32,
1682 DIF_VIDEO_AGC_CTRL, 0, 31,
1683 0xf2560000);
1685 /* Save the Spec Inversion value */
1686 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1687 dif_misc_ctrl_value |= 0x3a023F11;
1689 } else {
1690 /* V4L2_STD_NTSC_M (75 IRE Setup) Or
1691 V4L2_STD_NTSC_M_JP (Japan, 0 IRE Setup) */
1693 /* For NTSC the centre frequency of video coming out of
1694 sidewinder is around 7.1MHz or 3.6MHz depending on the
1695 spectral inversion. so for a non spectrally inverted channel
1696 the pll freq word is 0x03420c49
1699 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1700 DIF_PLL_CTRL, 2, 0x6503BC0C, 4);
1701 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1702 DIF_PLL_CTRL1, 2, 0xBD038C85, 4);
1703 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1704 DIF_PLL_CTRL2, 2, 0x1DB4640A, 4);
1705 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1706 DIF_PLL_CTRL3, 2, 0x00008800, 4);
1707 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1708 DIF_AGC_IF_REF, 2, 0x444C0380, 4);
1709 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1710 DIF_AGC_IF_INT_CURRENT, 2,
1711 0x26001700, 4);
1712 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1713 DIF_AGC_RF_CURRENT, 2, 0x00002660,
1715 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1716 DIF_VIDEO_AGC_CTRL, 2, 0x04000800,
1718 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1719 DIF_VID_AUD_OVERRIDE, 2, 0x27000100,
1721 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1722 DIF_AV_SEP_CTRL, 2, 0x01296e1f, 4);
1724 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1725 DIF_COMP_FLT_CTRL, 2, 0x009f50c1, 4);
1726 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1727 DIF_SRC_PHASE_INC, 2, 0x1befbf06, 4);
1728 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1729 DIF_SRC_GAIN_CONTROL, 2, 0x000035e8,
1732 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1733 DIF_AGC_CTRL_IF, 2, 0xC2262600, 4);
1734 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1735 DIF_AGC_CTRL_INT, 2, 0xC2262600, 4);
1736 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1737 DIF_AGC_CTRL_RF, 2, 0xC2262600, 4);
1739 /* Save the Spec Inversion value */
1740 dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
1741 dif_misc_ctrl_value |= 0x3a003F10;
1745 /* The AGC values should be the same for all standards,
1746 AUD_SRC_SEL[19] should always be disabled */
1747 dif_misc_ctrl_value &= ~FLD_DIF_AUD_SRC_SEL;
1749 /* It is still possible to get Set Standard calls even when we
1750 are in FM mode.
1751 This is done to override the value for FM. */
1752 if (dev->active_mode == V4L2_TUNER_RADIO)
1753 dif_misc_ctrl_value = 0x7a080000;
1755 /* Write the calculated value for misc ontrol register */
1756 status =
1757 cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, DIF_MISC_CTRL,
1758 2, dif_misc_ctrl_value, 4);
1760 return status;
1763 int cx231xx_tuner_pre_channel_change(struct cx231xx *dev)
1765 int status = 0;
1766 u32 dwval;
1768 /* Set the RF and IF k_agc values to 3 */
1769 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1770 DIF_AGC_IF_REF, 2, &dwval, 4);
1771 dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
1772 dwval |= 0x33000000;
1774 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1775 DIF_AGC_IF_REF, 2, dwval, 4);
1777 return status;
1780 int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
1782 int status = 0;
1783 u32 dwval;
1785 /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for SECAM */
1786 status = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1787 DIF_AGC_IF_REF, 2, &dwval, 4);
1788 dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
1790 if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
1791 V4L2_STD_SECAM_D))
1792 dwval |= 0x88000000;
1793 else
1794 dwval |= 0x44000000;
1796 status = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
1797 DIF_AGC_IF_REF, 2, dwval, 4);
1799 return status;
1802 /******************************************************************************
1803 * F L A T I R O N - B L O C K C O N T R O L functions *
1804 ******************************************************************************/
1805 int cx231xx_flatiron_initialize(struct cx231xx *dev)
1807 int status = 0;
1808 u32 value;
1810 status = cx231xx_read_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1811 CH_PWR_CTRL1, 1, &value, 1);
1812 /* enables clock to delta-sigma and decimation filter */
1813 value |= 0x80;
1814 status = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1815 CH_PWR_CTRL1, 1, value, 1);
1816 /* power up all channel */
1817 status = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1818 CH_PWR_CTRL2, 1, 0x00, 1);
1820 return status;
1823 int cx231xx_flatiron_update_power_control(struct cx231xx *dev, AV_MODE avmode)
1825 int status = 0;
1826 u32 value = 0;
1828 if (avmode != POLARIS_AVMODE_ENXTERNAL_AV) {
1829 status = cx231xx_read_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1830 CH_PWR_CTRL2, 1, &value, 1);
1831 value |= 0xfe;
1832 status = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1833 CH_PWR_CTRL2, 1, value, 1);
1834 } else {
1835 status = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1836 CH_PWR_CTRL2, 1, 0x00, 1);
1839 return status;
1842 /* set flatiron for audio input types */
1843 int cx231xx_flatiron_set_audio_input(struct cx231xx *dev, u8 audio_input)
1845 int status = 0;
1847 switch (audio_input) {
1848 case CX231XX_AMUX_LINE_IN:
1849 status = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1850 CH_PWR_CTRL2, 1, 0x00, 1);
1851 status = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
1852 CH_PWR_CTRL1, 1, 0x80, 1);
1853 break;
1854 case CX231XX_AMUX_VIDEO:
1855 default:
1856 break;
1859 dev->ctl_ainput = audio_input;
1861 return status;
1864 /******************************************************************************
1865 * P O W E R C O N T R O L functions *
1866 ******************************************************************************/
1867 int cx231xx_set_power_mode(struct cx231xx *dev, AV_MODE mode)
1869 u8 value[4] = { 0, 0, 0, 0 };
1870 u32 tmp = 0;
1871 int status = 0;
1873 if (dev->power_mode != mode)
1874 dev->power_mode = mode;
1875 else {
1876 cx231xx_info(" setPowerMode::mode = %d, No Change req.\n",
1877 mode);
1878 return 0;
1881 cx231xx_info(" setPowerMode::mode = %d\n", mode);
1883 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
1885 if (status < 0)
1886 return status;
1888 tmp = *((u32 *) value);
1890 switch (mode) {
1891 case POLARIS_AVMODE_ENXTERNAL_AV:
1893 tmp &= (~PWR_MODE_MASK);
1895 tmp |= PWR_AV_EN;
1896 value[0] = (u8) tmp;
1897 value[1] = (u8) (tmp >> 8);
1898 value[2] = (u8) (tmp >> 16);
1899 value[3] = (u8) (tmp >> 24);
1900 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1901 PWR_CTL_EN, value, 4);
1902 msleep(PWR_SLEEP_INTERVAL);
1904 tmp |= PWR_ISO_EN;
1905 value[0] = (u8) tmp;
1906 value[1] = (u8) (tmp >> 8);
1907 value[2] = (u8) (tmp >> 16);
1908 value[3] = (u8) (tmp >> 24);
1909 status =
1910 cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
1911 value, 4);
1912 msleep(PWR_SLEEP_INTERVAL);
1914 tmp |= POLARIS_AVMODE_ENXTERNAL_AV;
1915 value[0] = (u8) tmp;
1916 value[1] = (u8) (tmp >> 8);
1917 value[2] = (u8) (tmp >> 16);
1918 value[3] = (u8) (tmp >> 24);
1919 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1920 PWR_CTL_EN, value, 4);
1922 dev->xc_fw_load_done = 0; /* reset state of xceive tuner */
1923 break;
1925 case POLARIS_AVMODE_ANALOGT_TV:
1927 tmp &= (~PWR_DEMOD_EN);
1928 tmp |= (I2C_DEMOD_EN);
1929 value[0] = (u8) tmp;
1930 value[1] = (u8) (tmp >> 8);
1931 value[2] = (u8) (tmp >> 16);
1932 value[3] = (u8) (tmp >> 24);
1933 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1934 PWR_CTL_EN, value, 4);
1935 msleep(PWR_SLEEP_INTERVAL);
1937 if (!(tmp & PWR_TUNER_EN)) {
1938 tmp |= (PWR_TUNER_EN);
1939 value[0] = (u8) tmp;
1940 value[1] = (u8) (tmp >> 8);
1941 value[2] = (u8) (tmp >> 16);
1942 value[3] = (u8) (tmp >> 24);
1943 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1944 PWR_CTL_EN, value, 4);
1945 msleep(PWR_SLEEP_INTERVAL);
1948 if (!(tmp & PWR_AV_EN)) {
1949 tmp |= PWR_AV_EN;
1950 value[0] = (u8) tmp;
1951 value[1] = (u8) (tmp >> 8);
1952 value[2] = (u8) (tmp >> 16);
1953 value[3] = (u8) (tmp >> 24);
1954 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1955 PWR_CTL_EN, value, 4);
1956 msleep(PWR_SLEEP_INTERVAL);
1958 if (!(tmp & PWR_ISO_EN)) {
1959 tmp |= PWR_ISO_EN;
1960 value[0] = (u8) tmp;
1961 value[1] = (u8) (tmp >> 8);
1962 value[2] = (u8) (tmp >> 16);
1963 value[3] = (u8) (tmp >> 24);
1964 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1965 PWR_CTL_EN, value, 4);
1966 msleep(PWR_SLEEP_INTERVAL);
1969 if (!(tmp & POLARIS_AVMODE_ANALOGT_TV)) {
1970 tmp |= POLARIS_AVMODE_ANALOGT_TV;
1971 value[0] = (u8) tmp;
1972 value[1] = (u8) (tmp >> 8);
1973 value[2] = (u8) (tmp >> 16);
1974 value[3] = (u8) (tmp >> 24);
1975 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1976 PWR_CTL_EN, value, 4);
1977 msleep(PWR_SLEEP_INTERVAL);
1980 if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
1981 (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
1982 /* tuner path to channel 1 from port 3 */
1983 cx231xx_enable_i2c_for_tuner(dev, I2C_3);
1985 if (dev->cx231xx_reset_analog_tuner)
1986 dev->cx231xx_reset_analog_tuner(dev);
1988 break;
1990 case POLARIS_AVMODE_DIGITAL:
1991 if (!(tmp & PWR_TUNER_EN)) {
1992 tmp |= (PWR_TUNER_EN);
1993 value[0] = (u8) tmp;
1994 value[1] = (u8) (tmp >> 8);
1995 value[2] = (u8) (tmp >> 16);
1996 value[3] = (u8) (tmp >> 24);
1997 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1998 PWR_CTL_EN, value, 4);
1999 msleep(PWR_SLEEP_INTERVAL);
2001 if (!(tmp & PWR_AV_EN)) {
2002 tmp |= PWR_AV_EN;
2003 value[0] = (u8) tmp;
2004 value[1] = (u8) (tmp >> 8);
2005 value[2] = (u8) (tmp >> 16);
2006 value[3] = (u8) (tmp >> 24);
2007 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
2008 PWR_CTL_EN, value, 4);
2009 msleep(PWR_SLEEP_INTERVAL);
2011 if (!(tmp & PWR_ISO_EN)) {
2012 tmp |= PWR_ISO_EN;
2013 value[0] = (u8) tmp;
2014 value[1] = (u8) (tmp >> 8);
2015 value[2] = (u8) (tmp >> 16);
2016 value[3] = (u8) (tmp >> 24);
2017 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
2018 PWR_CTL_EN, value, 4);
2019 msleep(PWR_SLEEP_INTERVAL);
2022 tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN;
2023 value[0] = (u8) tmp;
2024 value[1] = (u8) (tmp >> 8);
2025 value[2] = (u8) (tmp >> 16);
2026 value[3] = (u8) (tmp >> 24);
2027 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
2028 PWR_CTL_EN, value, 4);
2029 msleep(PWR_SLEEP_INTERVAL);
2031 if (!(tmp & PWR_DEMOD_EN)) {
2032 tmp |= PWR_DEMOD_EN;
2033 value[0] = (u8) tmp;
2034 value[1] = (u8) (tmp >> 8);
2035 value[2] = (u8) (tmp >> 16);
2036 value[3] = (u8) (tmp >> 24);
2037 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
2038 PWR_CTL_EN, value, 4);
2039 msleep(PWR_SLEEP_INTERVAL);
2042 if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
2043 (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
2044 /* tuner path to channel 1 from port 3 */
2045 cx231xx_enable_i2c_for_tuner(dev, I2C_3);
2047 if (dev->cx231xx_reset_analog_tuner)
2048 dev->cx231xx_reset_analog_tuner(dev);
2050 break;
2052 default:
2053 break;
2056 msleep(PWR_SLEEP_INTERVAL);
2058 /* For power saving, only enable Pwr_resetout_n
2059 when digital TV is selected. */
2060 if (mode == POLARIS_AVMODE_DIGITAL) {
2061 tmp |= PWR_RESETOUT_EN;
2062 value[0] = (u8) tmp;
2063 value[1] = (u8) (tmp >> 8);
2064 value[2] = (u8) (tmp >> 16);
2065 value[3] = (u8) (tmp >> 24);
2066 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
2067 PWR_CTL_EN, value, 4);
2068 msleep(PWR_SLEEP_INTERVAL);
2071 /* update power control for colibri */
2072 status = cx231xx_colibri_update_power_control(dev, mode);
2074 /* update power control for flatiron */
2075 status = cx231xx_flatiron_update_power_control(dev, mode);
2077 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
2079 cx231xx_info(" The data of PWR_CTL_EN register 0x74=0x%0x,0x%0x,0x%0x,0x%0x\n",
2080 value[0], value[1], value[2], value[3]);
2082 return status;
2085 int cx231xx_power_suspend(struct cx231xx *dev)
2087 u8 value[4] = { 0, 0, 0, 0 };
2088 u32 tmp = 0;
2089 int status = 0;
2091 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
2092 value, 4);
2093 if (status > 0)
2094 return status;
2096 tmp = *((u32 *) value);
2097 tmp &= (~PWR_MODE_MASK);
2099 value[0] = (u8) tmp;
2100 value[1] = (u8) (tmp >> 8);
2101 value[2] = (u8) (tmp >> 16);
2102 value[3] = (u8) (tmp >> 24);
2103 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
2104 value, 4);
2106 return status;
2109 /******************************************************************************
2110 * S T R E A M C O N T R O L functions *
2111 ******************************************************************************/
2112 int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask)
2114 u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
2115 u32 tmp = 0;
2116 int status = 0;
2118 cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask);
2119 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
2120 value, 4);
2121 if (status < 0)
2122 return status;
2124 tmp = *((u32 *) value);
2125 tmp |= ep_mask;
2126 value[0] = (u8) tmp;
2127 value[1] = (u8) (tmp >> 8);
2128 value[2] = (u8) (tmp >> 16);
2129 value[3] = (u8) (tmp >> 24);
2131 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
2132 value, 4);
2134 return status;
2137 int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
2139 u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
2140 u32 tmp = 0;
2141 int status = 0;
2143 cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask);
2144 status =
2145 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4);
2146 if (status < 0)
2147 return status;
2149 tmp = *((u32 *) value);
2150 tmp &= (~ep_mask);
2151 value[0] = (u8) tmp;
2152 value[1] = (u8) (tmp >> 8);
2153 value[2] = (u8) (tmp >> 16);
2154 value[3] = (u8) (tmp >> 24);
2156 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
2157 value, 4);
2159 return status;
2162 int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
2164 int status = 0;
2166 if (dev->udev->speed == USB_SPEED_HIGH) {
2167 switch (media_type) {
2168 case 81: /* audio */
2169 cx231xx_info("%s: Audio enter HANC\n", __func__);
2170 status =
2171 cx231xx_mode_register(dev, TS_MODE_REG, 0x9300);
2172 break;
2174 case 2: /* vbi */
2175 cx231xx_info("%s: set vanc registers\n", __func__);
2176 status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300);
2177 break;
2179 case 3: /* sliced cc */
2180 cx231xx_info("%s: set hanc registers\n", __func__);
2181 status =
2182 cx231xx_mode_register(dev, TS_MODE_REG, 0x1300);
2183 break;
2185 case 0: /* video */
2186 cx231xx_info("%s: set video registers\n", __func__);
2187 status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
2188 break;
2190 case 4: /* ts1 */
2191 cx231xx_info("%s: set ts1 registers\n", __func__);
2192 status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
2193 status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
2194 break;
2195 case 6: /* ts1 parallel mode */
2196 cx231xx_info("%s: set ts1 parrallel mode registers\n",
2197 __func__);
2198 status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
2199 status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
2200 break;
2202 } else {
2203 status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
2206 return status;
2209 int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
2211 int rc;
2212 u32 ep_mask = -1;
2213 PPCB_CONFIG pcb_config;
2215 /* get EP for media type */
2216 pcb_config = &dev->current_pcb_config;
2218 if (pcb_config->config_num == 1) {
2219 switch (media_type) {
2220 case 0: /* Video */
2221 ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
2222 break;
2223 case 1: /* Audio */
2224 ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
2225 break;
2226 case 2: /* Vbi */
2227 ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
2228 break;
2229 case 3: /* Sliced_cc */
2230 ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
2231 break;
2232 case 4: /* ts1 */
2233 case 6: /* ts1 parallel mode */
2234 ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
2235 break;
2236 case 5: /* ts2 */
2237 ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
2238 break;
2241 } else if (pcb_config->config_num > 1) {
2242 switch (media_type) {
2243 case 0: /* Video */
2244 ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
2245 break;
2246 case 1: /* Audio */
2247 ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
2248 break;
2249 case 2: /* Vbi */
2250 ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
2251 break;
2252 case 3: /* Sliced_cc */
2253 ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
2254 break;
2255 case 4: /* ts1 */
2256 case 6: /* ts1 parallel mode */
2257 ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
2258 break;
2259 case 5: /* ts2 */
2260 ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
2261 break;
2266 if (start) {
2267 rc = cx231xx_initialize_stream_xfer(dev, media_type);
2269 if (rc < 0)
2270 return rc;
2272 /* enable video capture */
2273 if (ep_mask > 0)
2274 rc = cx231xx_start_stream(dev, ep_mask);
2275 } else {
2276 /* disable video capture */
2277 if (ep_mask > 0)
2278 rc = cx231xx_stop_stream(dev, ep_mask);
2282 return rc;
2284 EXPORT_SYMBOL_GPL(cx231xx_capture_start);
2286 /*****************************************************************************
2287 * G P I O B I T control functions *
2288 ******************************************************************************/
2289 int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
2291 int status = 0;
2293 status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0);
2295 return status;
2298 int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
2300 int status = 0;
2302 status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1);
2304 return status;
2308 * cx231xx_set_gpio_direction
2309 * Sets the direction of the GPIO pin to input or output
2311 * Parameters :
2312 * pin_number : The GPIO Pin number to program the direction for
2313 * from 0 to 31
2314 * pin_value : The Direction of the GPIO Pin under reference.
2315 * 0 = Input direction
2316 * 1 = Output direction
2318 int cx231xx_set_gpio_direction(struct cx231xx *dev,
2319 int pin_number, int pin_value)
2321 int status = 0;
2322 u32 value = 0;
2324 /* Check for valid pin_number - if 32 , bail out */
2325 if (pin_number >= 32)
2326 return -EINVAL;
2328 /* input */
2329 if (pin_value == 0)
2330 value = dev->gpio_dir & (~(1 << pin_number)); /* clear */
2331 else
2332 value = dev->gpio_dir | (1 << pin_number);
2334 status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val);
2336 /* cache the value for future */
2337 dev->gpio_dir = value;
2339 return status;
2343 * SetGpioPinLogicValue
2344 * Sets the value of the GPIO pin to Logic high or low. The Pin under
2345 * reference should ALREADY BE SET IN OUTPUT MODE !!!!!!!!!
2347 * Parameters :
2348 * pin_number : The GPIO Pin number to program the direction for
2349 * pin_value : The value of the GPIO Pin under reference.
2350 * 0 = set it to 0
2351 * 1 = set it to 1
2353 int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value)
2355 int status = 0;
2356 u32 value = 0;
2358 /* Check for valid pin_number - if 0xFF , bail out */
2359 if (pin_number >= 32)
2360 return -EINVAL;
2362 /* first do a sanity check - if the Pin is not output, make it output */
2363 if ((dev->gpio_dir & (1 << pin_number)) == 0x00) {
2364 /* It was in input mode */
2365 value = dev->gpio_dir | (1 << pin_number);
2366 dev->gpio_dir = value;
2367 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2368 (u8 *) &dev->gpio_val);
2369 value = 0;
2372 if (pin_value == 0)
2373 value = dev->gpio_val & (~(1 << pin_number));
2374 else
2375 value = dev->gpio_val | (1 << pin_number);
2377 /* store the value */
2378 dev->gpio_val = value;
2380 /* toggle bit0 of GP_IO */
2381 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2383 return status;
2386 /*****************************************************************************
2387 * G P I O I2C related functions *
2388 ******************************************************************************/
2389 int cx231xx_gpio_i2c_start(struct cx231xx *dev)
2391 int status = 0;
2393 /* set SCL to output 1 ; set SDA to output 1 */
2394 dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
2395 dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2396 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2397 dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
2399 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2400 if (status < 0)
2401 return -EINVAL;
2403 /* set SCL to output 1; set SDA to output 0 */
2404 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2405 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2407 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2408 if (status < 0)
2409 return -EINVAL;
2411 /* set SCL to output 0; set SDA to output 0 */
2412 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2413 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2415 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2416 if (status < 0)
2417 return -EINVAL;
2419 return status;
2422 int cx231xx_gpio_i2c_end(struct cx231xx *dev)
2424 int status = 0;
2426 /* set SCL to output 0; set SDA to output 0 */
2427 dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
2428 dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2430 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2431 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2433 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2434 if (status < 0)
2435 return -EINVAL;
2437 /* set SCL to output 1; set SDA to output 0 */
2438 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2439 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2441 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2442 if (status < 0)
2443 return -EINVAL;
2445 /* set SCL to input ,release SCL cable control
2446 set SDA to input ,release SDA cable control */
2447 dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
2448 dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2450 status =
2451 cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2452 if (status < 0)
2453 return -EINVAL;
2455 return status;
2458 int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
2460 int status = 0;
2461 u8 i;
2463 /* set SCL to output ; set SDA to output */
2464 dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
2465 dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2467 for (i = 0; i < 8; i++) {
2468 if (((data << i) & 0x80) == 0) {
2469 /* set SCL to output 0; set SDA to output 0 */
2470 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2471 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2472 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2473 (u8 *)&dev->gpio_val);
2475 /* set SCL to output 1; set SDA to output 0 */
2476 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2477 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2478 (u8 *)&dev->gpio_val);
2480 /* set SCL to output 0; set SDA to output 0 */
2481 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2482 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2483 (u8 *)&dev->gpio_val);
2484 } else {
2485 /* set SCL to output 0; set SDA to output 1 */
2486 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2487 dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
2488 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2489 (u8 *)&dev->gpio_val);
2491 /* set SCL to output 1; set SDA to output 1 */
2492 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2493 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2494 (u8 *)&dev->gpio_val);
2496 /* set SCL to output 0; set SDA to output 1 */
2497 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2498 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2499 (u8 *)&dev->gpio_val);
2502 return status;
2505 int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf)
2507 u8 value = 0;
2508 int status = 0;
2509 u32 gpio_logic_value = 0;
2510 u8 i;
2512 /* read byte */
2513 for (i = 0; i < 8; i++) { /* send write I2c addr */
2515 /* set SCL to output 0; set SDA to input */
2516 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2517 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2518 (u8 *)&dev->gpio_val);
2520 /* set SCL to output 1; set SDA to input */
2521 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2522 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
2523 (u8 *)&dev->gpio_val);
2525 /* get SDA data bit */
2526 gpio_logic_value = dev->gpio_val;
2527 status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
2528 (u8 *)&dev->gpio_val);
2529 if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0)
2530 value |= (1 << (8 - i - 1));
2532 dev->gpio_val = gpio_logic_value;
2535 /* set SCL to output 0,finish the read latest SCL signal.
2536 !!!set SDA to input, never to modify SDA direction at
2537 the same times */
2538 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2539 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2541 /* store the value */
2542 *buf = value & 0xff;
2544 return status;
2547 int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev)
2549 int status = 0;
2550 u32 gpio_logic_value = 0;
2551 int nCnt = 10;
2552 int nInit = nCnt;
2554 /* clock stretch; set SCL to input; set SDA to input;
2555 get SCL value till SCL = 1 */
2556 dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2557 dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
2559 gpio_logic_value = dev->gpio_val;
2560 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2562 do {
2563 msleep(2);
2564 status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
2565 (u8 *)&dev->gpio_val);
2566 nCnt--;
2567 } while (((dev->gpio_val & (1 << dev->board.tuner_scl_gpio)) == 0) && (nCnt > 0));
2569 if (nCnt == 0)
2570 cx231xx_info("No ACK after %d msec for clock stretch. GPIO I2C operation failed!",
2571 nInit * 10);
2573 /* readAck
2574 throuth clock stretch ,slave has given a SCL signal,
2575 so the SDA data can be directly read. */
2576 status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2578 if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
2579 dev->gpio_val = gpio_logic_value;
2580 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2581 status = 0;
2582 } else {
2583 dev->gpio_val = gpio_logic_value;
2584 dev->gpio_val |= (1 << dev->board.tuner_sda_gpio);
2587 /* read SDA end, set the SCL to output 0, after this operation,
2588 SDA direction can be changed. */
2589 dev->gpio_val = gpio_logic_value;
2590 dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio);
2591 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2592 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2594 return status;
2597 int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev)
2599 int status = 0;
2601 /* set SDA to ouput */
2602 dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2603 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2605 /* set SCL = 0 (output); set SDA = 0 (output) */
2606 dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2607 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2608 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2610 /* set SCL = 1 (output); set SDA = 0 (output) */
2611 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2612 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2614 /* set SCL = 0 (output); set SDA = 0 (output) */
2615 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2616 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2618 /* set SDA to input,and then the slave will read data from SDA. */
2619 dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2620 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2622 return status;
2625 int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
2627 int status = 0;
2629 /* set scl to output ; set sda to input */
2630 dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
2631 dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2632 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2634 /* set scl to output 0; set sda to input */
2635 dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2636 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2638 /* set scl to output 1; set sda to input */
2639 dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2640 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2642 return status;
2645 /*****************************************************************************
2646 * G P I O I2C related functions *
2647 ******************************************************************************/
2648 /* cx231xx_gpio_i2c_read
2649 * Function to read data from gpio based I2C interface
2651 int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
2653 int status = 0;
2654 int i = 0;
2656 /* get the lock */
2657 mutex_lock(&dev->gpio_i2c_lock);
2659 /* start */
2660 status = cx231xx_gpio_i2c_start(dev);
2662 /* write dev_addr */
2663 status = cx231xx_gpio_i2c_write_byte(dev, (dev_addr << 1) + 1);
2665 /* readAck */
2666 status = cx231xx_gpio_i2c_read_ack(dev);
2668 /* read data */
2669 for (i = 0; i < len; i++) {
2670 /* read data */
2671 buf[i] = 0;
2672 status = cx231xx_gpio_i2c_read_byte(dev, &buf[i]);
2674 if ((i + 1) != len) {
2675 /* only do write ack if we more length */
2676 status = cx231xx_gpio_i2c_write_ack(dev);
2680 /* write NAK - inform reads are complete */
2681 status = cx231xx_gpio_i2c_write_nak(dev);
2683 /* write end */
2684 status = cx231xx_gpio_i2c_end(dev);
2686 /* release the lock */
2687 mutex_unlock(&dev->gpio_i2c_lock);
2689 return status;
2692 /* cx231xx_gpio_i2c_write
2693 * Function to write data to gpio based I2C interface
2695 int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
2697 int status = 0;
2698 int i = 0;
2700 /* get the lock */
2701 mutex_lock(&dev->gpio_i2c_lock);
2703 /* start */
2704 status = cx231xx_gpio_i2c_start(dev);
2706 /* write dev_addr */
2707 status = cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1);
2709 /* read Ack */
2710 status = cx231xx_gpio_i2c_read_ack(dev);
2712 for (i = 0; i < len; i++) {
2713 /* Write data */
2714 status = cx231xx_gpio_i2c_write_byte(dev, buf[i]);
2716 /* read Ack */
2717 status = cx231xx_gpio_i2c_read_ack(dev);
2720 /* write End */
2721 status = cx231xx_gpio_i2c_end(dev);
2723 /* release the lock */
2724 mutex_unlock(&dev->gpio_i2c_lock);
2726 return 0;