cx231xx-avcore.c 75.4 KB
Newer Older
1
/*
2 3
   cx231xx_avcore.c - driver for Conexant Cx23100/101/102
		      USB video capture devices
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>

   This program contains the specific code to control the avdecoder chip and
   other related usb control functions for cx231xx based chipset.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/bitmap.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/mm.h>
#include <linux/mutex.h>

#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>

#include "cx231xx.h"

41
/******************************************************************************
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
			-: BLOCK ARRANGEMENT :-
	I2S block ----------------------|
	[I2S audio]			|
					|
	Analog Front End --> Direct IF -|-> Cx25840 --> Audio
	[video & audio]			|   [Audio]
					|
					|-> Cx25840 --> Video
					    [Video]

*******************************************************************************/

/******************************************************************************
 *                    A F E - B L O C K    C O N T R O L   functions          *
 * 				[ANALOG FRONT END]			      *
57
 ******************************************************************************/
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
static int afe_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
{
	return cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
					saddr, 2, data, 1);
}

static int afe_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
{
	int status;
	u32 temp = 0;

	status = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
					saddr, 2, &temp, 1);
	*data = (u8) temp;
	return status;
}

int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count)
76
{
77 78
	int status = 0;
	u8 temp = 0;
79
	u8 afe_power_status = 0;
80 81 82 83
	int i = 0;

	/* super block initialize */
	temp = (u8) (ref_count & 0xff);
84
	status = afe_write_byte(dev, SUP_BLK_TUNE2, temp);
85 86
	if (status < 0)
		return status;
87

88
	status = afe_read_byte(dev, SUP_BLK_TUNE2, &afe_power_status);
89 90
	if (status < 0)
		return status;
91 92 93

	temp = (u8) ((ref_count & 0x300) >> 8);
	temp |= 0x40;
94
	status = afe_write_byte(dev, SUP_BLK_TUNE1, temp);
95 96 97
	if (status < 0)
		return status;

98
	status = afe_write_byte(dev, SUP_BLK_PLL2, 0x0f);
99 100
	if (status < 0)
		return status;
101 102

	/* enable pll     */
103 104
	while (afe_power_status != 0x18) {
		status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18);
105 106 107 108 109 110
		if (status < 0) {
			cx231xx_info(
			": Init Super Block failed in send cmd\n");
			break;
		}

111 112
		status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status);
		afe_power_status &= 0xff;
113
		if (status < 0) {
114
			cx231xx_info(
115
			": Init Super Block failed in receive cmd\n");
116 117 118 119
			break;
		}
		i++;
		if (i == 10) {
120 121
			cx231xx_info(
			": Init Super Block force break in loop !!!!\n");
122 123 124 125 126 127 128 129 130
			status = -1;
			break;
		}
	}

	if (status < 0)
		return status;

	/* start tuning filter */
131
	status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x40);
132 133 134
	if (status < 0)
		return status;

135 136 137
	msleep(5);

	/* exit tuning */
138
	status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x00);
139 140

	return status;
141 142
}

143
int cx231xx_afe_init_channels(struct cx231xx *dev)
144
{
145 146 147
	int status = 0;

	/* power up all 3 channels, clear pd_buffer */
148 149 150
	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1, 0x00);
	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, 0x00);
	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00);
151 152

	/* Enable quantizer calibration */
153
	status = afe_write_byte(dev, ADC_COM_QUANT, 0x02);
154 155

	/* channel initialize, force modulator (fb) reset */
156 157 158
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x17);
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x17);
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x17);
159 160

	/* start quantilizer calibration  */
161 162 163
	status = afe_write_byte(dev, ADC_CAL_ATEST_CH1, 0x10);
	status = afe_write_byte(dev, ADC_CAL_ATEST_CH2, 0x10);
	status = afe_write_byte(dev, ADC_CAL_ATEST_CH3, 0x10);
164 165 166
	msleep(5);

	/* exit modulator (fb) reset */
167 168 169
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x07);
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x07);
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x07);
170 171

	/* enable the pre_clamp in each channel for single-ended input */
172 173 174
	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH1, 0xf0);
	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH2, 0xf0);
	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, 0xf0);
175 176

	/* use diode instead of resistor, so set term_en to 0, res_en to 0  */
177
	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
178
				   ADC_QGAIN_RES_TRM_CH1, 3, 7, 0x00);
179
	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
180
				   ADC_QGAIN_RES_TRM_CH2, 3, 7, 0x00);
181
	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
182 183 184
				   ADC_QGAIN_RES_TRM_CH3, 3, 7, 0x00);

	/* dynamic element matching off */
185 186 187
	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH1, 0x03);
	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH2, 0x03);
	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, 0x03);
188 189

	return status;
190 191
}

192
int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev)
193
{
194
	u8 c_value = 0;
195
	int status = 0;
196

197
	status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH2, &c_value);
198
	c_value &= (~(0x50));
199
	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, c_value);
200

201
	return status;
202 203 204
}

/*
205 206 207 208
	The Analog Front End in Cx231xx has 3 channels. These
	channels are used to share between different inputs
	like tuner, s-video and composite inputs.

209 210 211 212
	channel 1 ----- pin 1  to pin4(in reg is 1-4)
	channel 2 ----- pin 5  to pin8(in reg is 5-8)
	channel 3 ----- pin 9 to pin 12(in reg is 9-11)
*/
213
int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
214
{
215 216 217 218
	u8 ch1_setting = (u8) input_mux;
	u8 ch2_setting = (u8) (input_mux >> 8);
	u8 ch3_setting = (u8) (input_mux >> 16);
	int status = 0;
219
	u8 value = 0;
220 221

	if (ch1_setting != 0) {
222
		status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
223 224 225
		value &= (!INPUT_SEL_MASK);
		value |= (ch1_setting - 1) << 4;
		value &= 0xff;
226
		status = afe_write_byte(dev, ADC_INPUT_CH1, value);
227 228 229
	}

	if (ch2_setting != 0) {
230
		status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
231 232 233
		value &= (!INPUT_SEL_MASK);
		value |= (ch2_setting - 1) << 4;
		value &= 0xff;
234
		status = afe_write_byte(dev, ADC_INPUT_CH2, value);
235 236
	}

237 238
	/* For ch3_setting, the value to put in the register is
	   7 less than the input number */
239
	if (ch3_setting != 0) {
240
		status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
241 242 243
		value &= (!INPUT_SEL_MASK);
		value |= (ch3_setting - 1) << 4;
		value &= 0xff;
244
		status = afe_write_byte(dev, ADC_INPUT_CH3, value);
245 246 247
	}

	return status;
248 249
}

250
int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
251
{
252 253
	int status = 0;

254 255 256 257 258
	/*
	* FIXME: We need to implement the AFE code for LOW IF and for HI IF.
	* Currently, only baseband works.
	*/

259 260 261 262 263
	switch (mode) {
	case AFE_MODE_LOW_IF:
		/* SetupAFEforLowIF();  */
		break;
	case AFE_MODE_BASEBAND:
264
		status = cx231xx_afe_setup_AFE_for_baseband(dev);
265 266 267 268 269 270 271 272 273 274 275 276
		break;
	case AFE_MODE_EU_HI_IF:
		/* SetupAFEforEuHiIF(); */
		break;
	case AFE_MODE_US_HI_IF:
		/* SetupAFEforUsHiIF(); */
		break;
	case AFE_MODE_JAPAN_HI_IF:
		/* SetupAFEforJapanHiIF(); */
		break;
	}

277
	if ((mode != dev->afe_mode) &&
278
		(dev->video_input == CX231XX_VMUX_TELEVISION))
279
		status = cx231xx_afe_adjust_ref_count(dev,
280 281
						     CX231XX_VMUX_TELEVISION);

282
	dev->afe_mode = mode;
283 284

	return status;
285 286
}

287
int cx231xx_afe_update_power_control(struct cx231xx *dev,
288
					enum AV_MODE avmode)
289
{
290
	u8 afe_power_status = 0;
291 292 293 294 295 296
	int status = 0;

	switch (dev->model) {
	case CX231XX_BOARD_CNXT_RDE_250:
	case CX231XX_BOARD_CNXT_RDU_250:
		if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
297
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
298
						FLD_PWRDN_ENABLE_PLL)) {
299
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
300
							FLD_PWRDN_TUNING_BIAS |
301 302 303
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
304 305 306 307
				if (status < 0)
					break;
			}

308 309 310 311 312 313
			status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
							0x00);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
							0x00);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
							0x00);
314
		} else if (avmode == POLARIS_AVMODE_DIGITAL) {
315 316 317 318 319 320 321 322 323 324
			status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
							0x70);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
							0x70);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
							0x70);

			status |= afe_read_byte(dev, SUP_BLK_PWRDN,
						  &afe_power_status);
			afe_power_status |= FLD_PWRDN_PD_BANDGAP |
325 326
						FLD_PWRDN_PD_BIAS |
						FLD_PWRDN_PD_TUNECK;
327 328
			status |= afe_write_byte(dev, SUP_BLK_PWRDN,
						   afe_power_status);
329
		} else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
330
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
331
						FLD_PWRDN_ENABLE_PLL)) {
332
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
333
							FLD_PWRDN_TUNING_BIAS |
334 335 336
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
337 338 339 340
				if (status < 0)
					break;
			}

341 342 343 344 345 346
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
						0x00);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
						0x00);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
						0x00);
347 348 349 350 351 352 353
		} else {
			cx231xx_info("Invalid AV mode input\n");
			status = -1;
		}
		break;
	default:
		if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
354
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
355
						FLD_PWRDN_ENABLE_PLL)) {
356
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
357
							FLD_PWRDN_TUNING_BIAS |
358 359 360
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
361 362 363 364
				if (status < 0)
					break;
			}

365 366 367 368 369 370
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
							0x40);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
							0x40);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
							0x00);
371
		} else if (avmode == POLARIS_AVMODE_DIGITAL) {
372 373 374 375 376 377 378 379 380 381
			status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
							0x70);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
							0x70);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
							0x70);

			status |= afe_read_byte(dev, SUP_BLK_PWRDN,
						       &afe_power_status);
			afe_power_status |= FLD_PWRDN_PD_BANDGAP |
382 383
						FLD_PWRDN_PD_BIAS |
						FLD_PWRDN_PD_TUNECK;
384 385
			status |= afe_write_byte(dev, SUP_BLK_PWRDN,
							afe_power_status);
386
		} else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
387
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
388
						FLD_PWRDN_ENABLE_PLL)) {
389
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
390
							FLD_PWRDN_TUNING_BIAS |
391 392 393
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
394 395 396 397
				if (status < 0)
					break;
			}

398 399 400 401 402 403
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
							0x00);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
							0x00);
			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
							0x40);
404 405 406 407 408 409 410
		} else {
			cx231xx_info("Invalid AV mode input\n");
			status = -1;
		}
	}			/* switch  */

	return status;
411 412
}

413
int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input)
414
{
415 416
	u8 input_mode = 0;
	u8 ntf_mode = 0;
417 418 419 420 421
	int status = 0;

	dev->video_input = video_input;

	if (video_input == CX231XX_VMUX_TELEVISION) {
422 423 424
		status = afe_read_byte(dev, ADC_INPUT_CH3, &input_mode);
		status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3,
					&ntf_mode);
425
	} else {
426 427 428
		status = afe_read_byte(dev, ADC_INPUT_CH1, &input_mode);
		status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH1,
					&ntf_mode);
429
	}
430

431 432 433 434
	input_mode = (ntf_mode & 0x3) | ((input_mode & 0x6) << 1);

	switch (input_mode) {
	case SINGLE_ENDED:
435
		dev->afe_ref_count = 0x23C;
436 437
		break;
	case LOW_IF:
438
		dev->afe_ref_count = 0x24C;
439 440
		break;
	case EU_IF:
441
		dev->afe_ref_count = 0x258;
442 443
		break;
	case US_IF:
444
		dev->afe_ref_count = 0x260;
445 446 447 448 449
		break;
	default:
		break;
	}

450
	status = cx231xx_afe_init_super_block(dev, dev->afe_ref_count);
451

452 453
	return status;
}
454

455 456
/******************************************************************************
 *     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    *
457
 ******************************************************************************/
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
static int vid_blk_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
{
	return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
					saddr, 2, data, 1);
}

static int vid_blk_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
{
	int status;
	u32 temp = 0;

	status = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
					saddr, 2, &temp, 1);
	*data = (u8) temp;
	return status;
}

static int vid_blk_write_word(struct cx231xx *dev, u16 saddr, u32 data)
{
	return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
					saddr, 2, data, 4);
}

static int vid_blk_read_word(struct cx231xx *dev, u16 saddr, u32 *data)
{
	return cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
					saddr, 2, data, 4);
}

487 488
int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
{
489 490 491 492 493 494 495
	int status = 0;

	switch (INPUT(input)->type) {
	case CX231XX_VMUX_COMPOSITE1:
	case CX231XX_VMUX_SVIDEO:
		if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
		    (dev->power_mode != POLARIS_AVMODE_ENXTERNAL_AV)) {
496 497 498
			/* External AV */
			status = cx231xx_set_power_mode(dev,
					POLARIS_AVMODE_ENXTERNAL_AV);
499
			if (status < 0) {
500 501 502
				cx231xx_errdev("%s: set_power_mode : Failed to"
						" set Power - errCode [%d]!\n",
						__func__, status);
503 504 505
				return status;
			}
		}
506 507 508
		status = cx231xx_set_decoder_video_input(dev,
							 INPUT(input)->type,
							 INPUT(input)->vmux);
509 510 511 512 513
		break;
	case CX231XX_VMUX_TELEVISION:
	case CX231XX_VMUX_CABLE:
		if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
		    (dev->power_mode != POLARIS_AVMODE_ANALOGT_TV)) {
514 515 516
			/* Tuner */
			status = cx231xx_set_power_mode(dev,
						POLARIS_AVMODE_ANALOGT_TV);
517
			if (status < 0) {
518 519 520
				cx231xx_errdev("%s: set_power_mode:Failed"
					" to set Power - errCode [%d]!\n",
					__func__, status);
521 522 523
				return status;
			}
		}
524 525 526
		status = cx231xx_set_decoder_video_input(dev,
							CX231XX_VMUX_COMPOSITE1,
							INPUT(input)->vmux);
527 528
		break;
	default:
529
		cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n",
530 531 532 533 534 535 536 537
		     __func__, INPUT(input)->type);
		break;
	}

	/* save the selection */
	dev->video_input = input;

	return status;
538 539
}

540 541
int cx231xx_set_decoder_video_input(struct cx231xx *dev,
				u8 pin_type, u8 input)
542
{
543 544 545 546
	int status = 0;
	u32 value = 0;

	if (pin_type != dev->video_input) {
547
		status = cx231xx_afe_adjust_ref_count(dev, pin_type);
548
		if (status < 0) {
549
			cx231xx_errdev("%s: adjust_ref_count :Failed to set"
550
				"AFE input mux - errCode [%d]!\n",
551
				__func__, status);
552 553 554
			return status;
		}
	}
555

556 557
	/* call afe block to set video inputs */
	status = cx231xx_afe_set_input_mux(dev, input);
558
	if (status < 0) {
559
		cx231xx_errdev("%s: set_input_mux :Failed to set"
560
				" AFE input mux - errCode [%d]!\n",
561
				__func__, status);
562 563 564 565 566
		return status;
	}

	switch (pin_type) {
	case CX231XX_VMUX_COMPOSITE1:
567
		status = vid_blk_read_word(dev, AFE_CTRL, &value);
568 569 570
		value |= (0 << 13) | (1 << 4);
		value &= ~(1 << 5);

571 572 573 574
		/* set [24:23] [22:15] to 0  */
		value &= (~(0x1ff8000));
		/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0  */
		value |= 0x1000000;
575
		status = vid_blk_write_word(dev, AFE_CTRL, value);
576

577
		status = vid_blk_read_word(dev, OUT_CTRL1, &value);
578
		value |= (1 << 7);
579
		status = vid_blk_write_word(dev, OUT_CTRL1, value);
580 581 582

		/* Set vip 1.1 output mode */
		status = cx231xx_read_modify_write_i2c_dword(dev,
583
							VID_BLK_I2C_ADDRESS,
584 585 586 587 588 589 590
							OUT_CTRL1,
							FLD_OUT_MODE,
							OUT_MODE_VIP11);

		/* Tell DIF object to go to baseband mode  */
		status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
		if (status < 0) {
591 592
			cx231xx_errdev("%s: cx231xx_dif set to By pass"
						   " mode- errCode [%d]!\n",
593 594 595 596 597
				__func__, status);
			return status;
		}

		/* Read the DFE_CTRL1 register */
598
		status = vid_blk_read_word(dev, DFE_CTRL1, &value);
599 600 601 602 603 604 605 606

		/* enable the VBI_GATE_EN */
		value |= FLD_VBI_GATE_EN;

		/* Enable the auto-VGA enable */
		value |= FLD_VGA_AUTO_EN;

		/* Write it back */
607
		status = vid_blk_write_word(dev, DFE_CTRL1, value);
608 609 610

		/* Disable auto config of registers */
		status = cx231xx_read_modify_write_i2c_dword(dev,
611
					VID_BLK_I2C_ADDRESS,
612 613 614 615 616
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));

		/* Set CVBS input mode */
		status = cx231xx_read_modify_write_i2c_dword(dev,
617
			VID_BLK_I2C_ADDRESS,
618 619 620 621 622 623
			MODE_CTRL, FLD_INPUT_MODE,
			cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
		break;
	case CX231XX_VMUX_SVIDEO:
		/* Disable the use of  DIF */

624
		status = vid_blk_read_word(dev, AFE_CTRL, &value);
625

626 627 628 629 630
		/* set [24:23] [22:15] to 0 */
		value &= (~(0x1ff8000));
		/* set FUNC_MODE[24:23] = 2
		IF_MOD[22:15] = 0 DCR_BYP_CH2[4:4] = 1; */
		value |= 0x1000010;
631
		status = vid_blk_write_word(dev, AFE_CTRL, value);
632 633 634 635

		/* Tell DIF object to go to baseband mode */
		status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
		if (status < 0) {
636 637
			cx231xx_errdev("%s: cx231xx_dif set to By pass"
						   " mode- errCode [%d]!\n",
638 639 640 641 642
				__func__, status);
			return status;
		}

		/* Read the DFE_CTRL1 register */
643
		status = vid_blk_read_word(dev, DFE_CTRL1, &value);
644 645 646 647 648 649 650 651

		/* enable the VBI_GATE_EN */
		value |= FLD_VBI_GATE_EN;

		/* Enable the auto-VGA enable */
		value |= FLD_VGA_AUTO_EN;

		/* Write it back */
652
		status = vid_blk_write_word(dev, DFE_CTRL1, value);
653 654 655

		/* Disable auto config of registers  */
		status =  cx231xx_read_modify_write_i2c_dword(dev,
656
					VID_BLK_I2C_ADDRESS,
657 658 659 660 661
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));

		/* Set YC input mode */
		status = cx231xx_read_modify_write_i2c_dword(dev,
662
			VID_BLK_I2C_ADDRESS,
663 664 665 666 667
			MODE_CTRL,
			FLD_INPUT_MODE,
			cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_YC_1));

		/* Chroma to ADC2 */
668
		status = vid_blk_read_word(dev, AFE_CTRL, &value);
669 670 671 672 673 674 675
		value |= FLD_CHROMA_IN_SEL;	/* set the chroma in select */

		/* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8)
		   This sets them to use video
		   rather than audio.  Only one of the two will be in use. */
		value &= ~(FLD_VGA_SEL_CH2 | FLD_VGA_SEL_CH3);

676
		status = vid_blk_write_word(dev, AFE_CTRL, value);
677

678
		status = cx231xx_afe_set_mode(dev, AFE_MODE_BASEBAND);
679 680 681 682 683 684 685 686 687
		break;
	case CX231XX_VMUX_TELEVISION:
	case CX231XX_VMUX_CABLE:
	default:
		switch (dev->model) {
		case CX231XX_BOARD_CNXT_RDE_250:
		case CX231XX_BOARD_CNXT_RDU_250:
			/* Disable the use of  DIF   */

688
			status = vid_blk_read_word(dev, AFE_CTRL, &value);
689 690 691
			value |= (0 << 13) | (1 << 4);
			value &= ~(1 << 5);

692 693 694 695
			/* set [24:23] [22:15] to 0 */
			value &= (~(0x1FF8000));
			/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
			value |= 0x1000000;
696 697 698
			status = vid_blk_write_word(dev, AFE_CTRL, value);

			status = vid_blk_read_word(dev, OUT_CTRL1, &value);
699
			value |= (1 << 7);
700
			status = vid_blk_write_word(dev, OUT_CTRL1, value);
701 702

			/* Set vip 1.1 output mode */
703
			status = cx231xx_read_modify_write_i2c_dword(dev,
704
							VID_BLK_I2C_ADDRESS,
705 706
							OUT_CTRL1, FLD_OUT_MODE,
							OUT_MODE_VIP11);
707

708 709 710
			/* Tell DIF object to go to baseband mode */
			status = cx231xx_dif_set_standard(dev,
							  DIF_USE_BASEBAND);
711
			if (status < 0) {
712 713 714
				cx231xx_errdev("%s: cx231xx_dif set to By pass"
						" mode- errCode [%d]!\n",
						__func__, status);
715 716 717 718
				return status;
			}

			/* Read the DFE_CTRL1 register */
719
			status = vid_blk_read_word(dev, DFE_CTRL1, &value);
720 721 722 723 724 725 726 727

			/* enable the VBI_GATE_EN */
			value |= FLD_VBI_GATE_EN;

			/* Enable the auto-VGA enable */
			value |= FLD_VGA_AUTO_EN;

			/* Write it back */
728
			status = vid_blk_write_word(dev, DFE_CTRL1, value);
729 730

			/* Disable auto config of registers */
731
			status = cx231xx_read_modify_write_i2c_dword(dev,
732
					VID_BLK_I2C_ADDRESS,
733 734
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));
735 736

			/* Set CVBS input mode */
737
			status = cx231xx_read_modify_write_i2c_dword(dev,
738
				VID_BLK_I2C_ADDRESS,
739
				MODE_CTRL, FLD_INPUT_MODE,
740 741
				cx231xx_set_field(FLD_INPUT_MODE,
						INPUT_MODE_CVBS_0));
742 743 744
			break;
		default:
			/* Enable the DIF for the tuner */
745

746 747
			/* Reinitialize the DIF */
			status = cx231xx_dif_set_standard(dev, dev->norm);
748
			if (status < 0) {
749 750 751
				cx231xx_errdev("%s: cx231xx_dif set to By pass"
						" mode- errCode [%d]!\n",
						__func__, status);
752 753 754
				return status;
			}

755
			/* Make sure bypass is cleared */
756
			status = vid_blk_read_word(dev, DIF_MISC_CTRL, &value);
757 758 759 760 761

			/* Clear the bypass bit */
			value &= ~FLD_DIF_DIF_BYPASS;

			/* Enable the use of the DIF block */
762
			status = vid_blk_write_word(dev, DIF_MISC_CTRL, value);
763

764
			/* Read the DFE_CTRL1 register */
765
			status = vid_blk_read_word(dev, DFE_CTRL1, &value);
766

767 768
			/* Disable the VBI_GATE_EN */
			value &= ~FLD_VBI_GATE_EN;
769

770 771 772
			/* Enable the auto-VGA enable, AGC, and
			   set the skip count to 2 */
			value |= FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000;
773 774

			/* Write it back */
775
			status = vid_blk_write_word(dev, DFE_CTRL1, value);
776

777
			/* Wait until AGC locks up */
778
			msleep(1);
779

780 781
			/* Disable the auto-VGA enable AGC */
			value &= ~(FLD_VGA_AUTO_EN);
782

783
			/* Write it back */
784
			status = vid_blk_write_word(dev, DFE_CTRL1, value);
785

786
			/* Enable Polaris B0 AGC output */
787
			status = vid_blk_read_word(dev, PIN_CTRL, &value);
788 789 790
			value |= (FLD_OEF_AGC_RF) |
				 (FLD_OEF_AGC_IFVGA) |
				 (FLD_OEF_AGC_IF);
791
			status = vid_blk_write_word(dev, PIN_CTRL, value);
792 793 794

			/* Set vip 1.1 output mode */
			status = cx231xx_read_modify_write_i2c_dword(dev,
795
						VID_BLK_I2C_ADDRESS,
796 797 798 799 800
						OUT_CTRL1, FLD_OUT_MODE,
						OUT_MODE_VIP11);

			/* Disable auto config of registers */
			status = cx231xx_read_modify_write_i2c_dword(dev,
801
					VID_BLK_I2C_ADDRESS,
802 803 804 805 806
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));

			/* Set CVBS input mode */
			status = cx231xx_read_modify_write_i2c_dword(dev,
807
				VID_BLK_I2C_ADDRESS,
808
				MODE_CTRL, FLD_INPUT_MODE,
809 810
				cx231xx_set_field(FLD_INPUT_MODE,
						INPUT_MODE_CVBS_0));
811

812 813
			/* Set some bits in AFE_CTRL so that channel 2 or 3
			 * is ready to receive audio */
814 815 816
			/* Clear clamp for channels 2 and 3      (bit 16-17) */
			/* Clear droop comp                      (bit 19-20) */
			/* Set VGA_SEL (for audio control)       (bit 7-8) */
817
			status = vid_blk_read_word(dev, AFE_CTRL, &value);
818 819 820

			value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;

821
			status = vid_blk_write_word(dev, AFE_CTRL, value);
822
			break;
823 824 825 826 827 828

		}
		break;
	}

	/* Set raw VBI mode */
829
	status = cx231xx_read_modify_write_i2c_dword(dev,
830
				VID_BLK_I2C_ADDRESS,
831 832
				OUT_CTRL1, FLD_VBIHACTRAW_EN,
				cx231xx_set_field(FLD_VBIHACTRAW_EN, 1));
833

834
	status = vid_blk_read_word(dev, OUT_CTRL1, &value);
835 836
	if (value & 0x02) {
		value |= (1 << 19);
837
		status = vid_blk_write_word(dev, OUT_CTRL1, value);
838 839 840
	}

	return status;
841 842 843
}

/*
844 845 846
 * Handle any video-mode specific overrides that are different
 * on a per video standards basis after touching the MODE_CTRL
 * register which resets many values for autodetect
847 848 849
 */
int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
{
850 851 852 853 854 855
	int status = 0;

	cx231xx_info("do_mode_ctrl_overrides : 0x%x\n",
		     (unsigned int)dev->norm);

	/* Change the DFE_CTRL3 bp_percent to fix flagging */
856
	status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280);
857

858
	if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
859 860
		cx231xx_info("do_mode_ctrl_overrides NTSC\n");

861 862 863
		/* Move the close caption lines out of active video,
		   adjust the active video start point */
		status = cx231xx_read_modify_write_i2c_dword(dev,
864
							VID_BLK_I2C_ADDRESS,
865 866
							VERT_TIM_CTRL,
							FLD_VBLANK_CNT, 0x18);
867
		status = cx231xx_read_modify_write_i2c_dword(dev,
868
							VID_BLK_I2C_ADDRESS,
869 870 871
							VERT_TIM_CTRL,
							FLD_VACTIVE_CNT,
							0x1E6000);
872
		status = cx231xx_read_modify_write_i2c_dword(dev,
873
							VID_BLK_I2C_ADDRESS,
874 875 876 877
							VERT_TIM_CTRL,
							FLD_V656BLANK_CNT,
							0x1E000000);

878
		status = cx231xx_read_modify_write_i2c_dword(dev,
879
							VID_BLK_I2C_ADDRESS,
880 881 882 883
							HORIZ_TIM_CTRL,
							FLD_HBLANK_CNT,
							cx231xx_set_field
							(FLD_HBLANK_CNT, 0x79));
884 885 886
	} else if (dev->norm & V4L2_STD_SECAM) {
		cx231xx_info("do_mode_ctrl_overrides SECAM\n");
		status =  cx231xx_read_modify_write_i2c_dword(dev,
887
							VID_BLK_I2C_ADDRESS,
888 889 890
							VERT_TIM_CTRL,
							FLD_VBLANK_CNT, 0x24);
		/* Adjust the active video horizontal start point */
891
		status = cx231xx_read_modify_write_i2c_dword(dev,
892
							VID_BLK_I2C_ADDRESS,
893 894 895 896
							HORIZ_TIM_CTRL,
							FLD_HBLANK_CNT,
							cx231xx_set_field
							(FLD_HBLANK_CNT, 0x85));
897 898 899
	} else {
		cx231xx_info("do_mode_ctrl_overrides PAL\n");
		status = cx231xx_read_modify_write_i2c_dword(dev,
900
							VID_BLK_I2C_ADDRESS,
901 902 903
							VERT_TIM_CTRL,
							FLD_VBLANK_CNT, 0x24);
		/* Adjust the active video horizontal start point */
904
		status = cx231xx_read_modify_write_i2c_dword(dev,
905
							VID_BLK_I2C_ADDRESS,
906 907 908 909 910 911 912
							HORIZ_TIM_CTRL,
							FLD_HBLANK_CNT,
							cx231xx_set_field
							(FLD_HBLANK_CNT, 0x85));
	}

	return status;
913 914 915 916
}

int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
{
917 918 919 920 921 922 923 924
	int status = 0;
	enum AUDIO_INPUT ainput = AUDIO_INPUT_LINE;

	switch (INPUT(input)->amux) {
	case CX231XX_AMUX_VIDEO:
		ainput = AUDIO_INPUT_TUNER_TV;
		break;
	case CX231XX_AMUX_LINE_IN:
925
		status = cx231xx_i2s_blk_set_audio_input(dev, input);
926 927 928 929 930 931 932 933 934
		ainput = AUDIO_INPUT_LINE;
		break;
	default:
		break;
	}

	status = cx231xx_set_audio_decoder_input(dev, ainput);

	return status;
935 936
}

937 938
int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
				    enum AUDIO_INPUT audio_input)
939
{
940 941
	u32 dwval;
	int status;
942
	u8 gen_ctrl;
943 944 945
	u32 value = 0;

	/* Put it in soft reset   */
946
	status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
947
	gen_ctrl |= 1;
948
	status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
949 950 951 952

	switch (audio_input) {
	case AUDIO_INPUT_LINE:
		/* setup AUD_IO control from Merlin paralle output */
953 954
		value = cx231xx_set_field(FLD_AUD_CHAN1_SRC,
					  AUD_CHAN_SRC_PARALLEL);
955
		status = vid_blk_write_word(dev, AUD_IO_CTRL, value);
956 957 958 959

		/* setup input to Merlin, SRC2 connect to AC97
		   bypass upsample-by-2, slave mode, sony mode, left justify
		   adr 091c, dat 01000000 */
960
		status = vid_blk_read_word(dev, AC97_CTL, &dwval);
961

962 963
		status = vid_blk_write_word(dev, AC97_CTL,
					   (dwval | FLD_AC97_UP2X_BYPASS));
964 965

		/* select the parallel1 and SRC3 */
966
		status = vid_blk_write_word(dev, BAND_OUT_SEL,
967 968
				cx231xx_set_field(FLD_SRC3_IN_SEL, 0x0) |
				cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x0) |
969
				cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x0));
970 971 972

		/* unmute all, AC97 in, independence mode
		   adr 08d0, data 0x00063073 */
973
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073);
974 975

		/* set AVC maximum threshold, adr 08d4, dat ffff0024 */
976 977 978
		status = vid_blk_read_word(dev, PATH1_VOL_CTL, &dwval);
		status = vid_blk_write_word(dev, PATH1_VOL_CTL,
					   (dwval | FLD_PATH1_AVC_THRESHOLD));
979 980

		/* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
981 982 983
		status = vid_blk_read_word(dev, PATH1_SC_CTL, &dwval);
		status = vid_blk_write_word(dev, PATH1_SC_CTL,
					   (dwval | FLD_PATH1_SC_THRESHOLD));
984 985 986 987 988 989
		break;

	case AUDIO_INPUT_TUNER_TV:
	default:

		/* Setup SRC sources and clocks */
990
		status = vid_blk_write_word(dev, BAND_OUT_SEL,
991 992 993 994 995 996 997 998 999 1000 1001 1002
			cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00)         |
			cx231xx_set_field(FLD_SRC6_CLK_SEL, 0x01)        |
			cx231xx_set_field(FLD_SRC5_IN_SEL, 0x00)         |
			cx231xx_set_field(FLD_SRC5_CLK_SEL, 0x02)        |
			cx231xx_set_field(FLD_SRC4_IN_SEL, 0x02)         |
			cx231xx_set_field(FLD_SRC4_CLK_SEL, 0x03)        |
			cx231xx_set_field(FLD_SRC3_IN_SEL, 0x00)         |
			cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x00)        |
			cx231xx_set_field(FLD_BASEBAND_BYPASS_CTL, 0x00) |
			cx231xx_set_field(FLD_AC97_SRC_SEL, 0x03)        |
			cx231xx_set_field(FLD_I2S_SRC_SEL, 0x00)         |
			cx231xx_set_field(FLD_PARALLEL2_SRC_SEL, 0x02)   |
1003
			cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x01));
1004 1005

		/* Setup the AUD_IO control */
1006
		status = vid_blk_write_word(dev, AUD_IO_CTRL,
1007 1008 1009 1010
			cx231xx_set_field(FLD_I2S_PORT_DIR, 0x00)  |
			cx231xx_set_field(FLD_I2S_OUT_SRC, 0x00)   |
			cx231xx_set_field(FLD_AUD_CHAN3_SRC, 0x00) |
			cx231xx_set_field(FLD_AUD_CHAN2_SRC, 0x00) |
1011
			cx231xx_set_field(FLD_AUD_CHAN1_SRC, 0x03));
1012

1013
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870);
1014 1015 1016

		/* setAudioStandard(_audio_standard); */

1017
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870);
1018 1019 1020
		switch (dev->model) {
		case CX231XX_BOARD_CNXT_RDE_250:
		case CX231XX_BOARD_CNXT_RDU_250:
1021
			status = cx231xx_read_modify_write_i2c_dword(dev,
1022
					VID_BLK_I2C_ADDRESS,
1023 1024 1025
					CHIP_CTRL,
					FLD_SIF_EN,
					cx231xx_set_field(FLD_SIF_EN, 1));
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
			break;
		default:
			break;
		}
		break;

	case AUDIO_INPUT_TUNER_FM:
		/*  use SIF for FM radio
		   setupFM();
		   setAudioStandard(_audio_standard);
		 */
		break;

	case AUDIO_INPUT_MUTE:
1040
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F011012);
1041 1042
		break;
	}
1043

1044
	/* Take it out of soft reset */
1045
	status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
1046
	gen_ctrl &= ~1;
1047
	status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
1048

1049 1050
	return status;
}
1051 1052 1053 1054

/* Set resolution of the video */
int cx231xx_resolution_set(struct cx231xx *dev)
{
1055
	/* set horzontal scale */
1056 1057 1058
	int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale);
	if (status)
		return status;
1059

1060
	/* set vertical scale */
1061
	return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale);
1062 1063
}

1064 1065 1066
/******************************************************************************
 *                    C H I P Specific  C O N T R O L   functions             *
 ******************************************************************************/
1067 1068
int cx231xx_init_ctrl_pin_status(struct cx231xx *dev)
{
1069 1070
	u32 value;
	int status = 0;
1071

1072
	status = vid_blk_read_word(dev, PIN_CTRL, &value);
1073
	value |= (~dev->board.ctl_pin_status_mask);
1074
	status = vid_blk_write_word(dev, PIN_CTRL, value);
1075

1076
	return status;
1077 1078
}

1079 1080
int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
					      u8 analog_or_digital)
1081
{
1082
	int status = 0;
1083

1084
	/* first set the direction to output */
1085 1086 1087
	status = cx231xx_set_gpio_direction(dev,
					    dev->board.
					    agc_analog_digital_select_gpio, 1);
1088

1089
	/* 0 - demod ; 1 - Analog mode */
1090
	status = cx231xx_set_gpio_value(dev,
1091 1092
				   dev->board.agc_analog_digital_select_gpio,
				   analog_or_digital);
1093

1094
	return status;
1095 1096 1097 1098
}

int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex)
{
1099 1100
	u8 value[4] = { 0, 0, 0, 0 };
	int status = 0;
1101

1102
	cx231xx_info("Changing the i2c port for tuner to %d\n", I2CIndex);
1103

1104 1105
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
				       PWR_CTL_EN, value, 4);
1106 1107
	if (status < 0)
		return status;
1108

1109 1110 1111
	if (I2CIndex == I2C_1) {
		if (value[0] & I2C_DEMOD_EN) {
			value[0] &= ~I2C_DEMOD_EN;
1112
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1113 1114 1115 1116 1117
						   PWR_CTL_EN, value, 4);
		}
	} else {
		if (!(value[0] & I2C_DEMOD_EN)) {
			value[0] |= I2C_DEMOD_EN;
1118
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1119 1120 1121
						   PWR_CTL_EN, value, 4);
		}
	}
1122

1123
	return status;
1124 1125 1126

}

1127 1128 1129
/******************************************************************************
 *                 D I F - B L O C K    C O N T R O L   functions             *
 ******************************************************************************/
1130
int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
1131
					  u32 function_mode, u32 standard)
1132
{
1133 1134 1135 1136
	int status = 0;

	if (mode == V4L2_TUNER_RADIO) {
		/* C2HH */
1137 1138
		/* lo if big signal */
		status = cx231xx_reg_mask_write(dev,
1139
				VID_BLK_I2C_ADDRESS, 32,
1140 1141 1142
				AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
		/* FUNC_MODE = DIF */
		status = cx231xx_reg_mask_write(dev,
1143
				VID_BLK_I2C_ADDRESS, 32,
1144 1145 1146
				AFE_CTRL_C2HH_SRC_CTRL, 23, 24, function_mode);
		/* IF_MODE */
		status = cx231xx_reg_mask_write(dev,
1147
				VID_BLK_I2C_ADDRESS, 32,
1148 1149 1150
				AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF);
		/* no inv */
		status = cx231xx_reg_mask_write(dev,
1151
				VID_BLK_I2C_ADDRESS, 32,
1152
				AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
1153 1154
	} else if (standard != DIF_USE_BASEBAND) {
		if (standard & V4L2_STD_MN) {
1155
			/* lo if big signal */
1156
			status = cx231xx_reg_mask_write(dev,
1157
					VID_BLK_I2C_ADDRESS, 32,
1158 1159
					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
			/* FUNC_MODE = DIF */
1160
			status = cx231xx_reg_mask_write(dev,
1161
					VID_BLK_I2C_ADDRESS, 32,
1162
					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1163 1164
					function_mode);
			/* IF_MODE */
1165
			status = cx231xx_reg_mask_write(dev,
1166
					VID_BLK_I2C_ADDRESS, 32,
1167 1168
					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb);
			/* no inv */
1169
			status = cx231xx_reg_mask_write(dev,
1170
					VID_BLK_I2C_ADDRESS, 32,
1171 1172
					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
			/* 0x124, AUD_CHAN1_SRC = 0x3 */
1173
			status = cx231xx_reg_mask_write(dev,
1174
					VID_BLK_I2C_ADDRESS, 32,
1175
					AUD_IO_CTRL, 0, 31, 0x00000003);
1176 1177
		} else if ((standard == V4L2_STD_PAL_I) |
			(standard & V4L2_STD_SECAM)) {
1178
			/* C2HH setup */
1179
			/* lo if big signal */
1180
			status = cx231xx_reg_mask_write(dev,
1181
					VID_BLK_I2C_ADDRESS, 32,
1182 1183
					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
			/* FUNC_MODE = DIF */
1184
			status = cx231xx_reg_mask_write(dev,
1185
					VID_BLK_I2C_ADDRESS, 32,
1186
					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1187 1188
					function_mode);
			/* IF_MODE */
1189
			status = cx231xx_reg_mask_write(dev,
1190
					VID_BLK_I2C_ADDRESS, 32,
1191
					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF);
1192
			/* no inv */
1193
			status = cx231xx_reg_mask_write(dev,
1194
					VID_BLK_I2C_ADDRESS, 32,
1195
					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
1196 1197
		} else {
			/* default PAL BG */
1198
			/* C2HH setup */
1199
			/* lo if big signal */
1200
			status = cx231xx_reg_mask_write(dev,
1201
					VID_BLK_I2C_ADDRESS, 32,
1202 1203
					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
			/* FUNC_MODE = DIF */
1204
			status = cx231xx_reg_mask_write(dev,
1205
					VID_BLK_I2C_ADDRESS, 32,
1206
					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1207 1208
					function_mode);
			/* IF_MODE */
1209
			status = cx231xx_reg_mask_write(dev,
1210
					VID_BLK_I2C_ADDRESS, 32,
1211
					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE);
1212
			/* no inv */
1213
			status = cx231xx_reg_mask_write(dev,
1214
					VID_BLK_I2C_ADDRESS, 32,
1215
					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
1216 1217 1218 1219
		}
	}

	return status;
1220 1221 1222 1223
}

int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
{
1224 1225 1226 1227 1228 1229
	int status = 0;
	u32 dif_misc_ctrl_value = 0;
	u32 func_mode = 0;

	cx231xx_info("%s: setStandard to %x\n", __func__, standard);

1230
	status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value);
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
	if (standard != DIF_USE_BASEBAND)
		dev->norm = standard;

	switch (dev->model) {
	case CX231XX_BOARD_CNXT_RDE_250:
	case CX231XX_BOARD_CNXT_RDU_250:
		func_mode = 0x03;
		break;
	default:
		func_mode = 0x01;
	}

1243
	status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
1244 1245 1246
						  func_mode, standard);

	if (standard == DIF_USE_BASEBAND) {	/* base band */
1247 1248
		/* There is a different SRC_PHASE_INC value
		   for baseband vs. DIF */
1249 1250 1251
		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0xDF7DF83);
		status = vid_blk_read_word(dev, DIF_MISC_CTRL,
						&dif_misc_ctrl_value);
1252
		dif_misc_ctrl_value |= FLD_DIF_DIF_BYPASS;
1253 1254
		status = vid_blk_write_word(dev, DIF_MISC_CTRL,
						dif_misc_ctrl_value);
1255
	} else if (standard & V4L2_STD_PAL_D) {
1256
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1257
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1258
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1259
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1260
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1261
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1262
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1263
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1264
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1265
					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1266
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1267
					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1268
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1269
					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1270
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1271
					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1272
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1273 1274
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1275
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1276 1277
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1278
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1279 1280
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0x72500800);
1281
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1282 1283
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1284
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1285
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3934EA);
1286
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1287 1288
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1289
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1290 1291
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1292
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1293 1294
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1295
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1296 1297 1298 1299 1300
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a023F11;
	} else if (standard & V4L2_STD_PAL_I) {
1301
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1302
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1303
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1304
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1305
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1306
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1307
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1308
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1309
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1310
					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1311
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1312
					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1313
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1314
					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1315
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1316
					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1317
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1318 1319
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1320
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1321 1322
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1323
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1324 1325
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0x72500800);
1326
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1327 1328
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1329
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1330
					   DIF_AV_SEP_CTRL, 0, 31, 0x5F39A934);
1331
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1332 1333
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1334
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1335 1336
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1337
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1338 1339
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1340
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1341 1342 1343 1344 1345 1346
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a033F11;
	} else if (standard & V4L2_STD_PAL_M) {
		/* improved Low Frequency Phase Noise */
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
		status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
		status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
		status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
						0x26001700);
		status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
						0x00002660);
		status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
						0x72500800);
		status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
						0x27000100);
		status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x012c405d);
		status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
						0x009f50c1);
		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
						0x1befbf06);
		status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
						0x000035e8);
		status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
						0x00000000);
1369 1370 1371 1372 1373
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3A0A3F10;
	} else if (standard & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
		/* improved Low Frequency Phase Noise */
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
		status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
		status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
		status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
						0x26001700);
		status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
						0x00002660);
		status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
						0x72500800);
		status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
						0x27000100);
		status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL,
						0x012c405d);
		status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
						0x009f50c1);
		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
						0x1befbf06);
		status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
						0x000035e8);
		status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
						0x00000000);
1397 1398 1399 1400
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value = 0x3A093F10;
	} else if (standard &
1401 1402
		  (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
		   V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)) {
1403

1404
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1405
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1406
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1407
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1408
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1409
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1410
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1411
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1412
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1413
					   DIF_AGC_IF_REF, 0, 31, 0x888C0380);
1414
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1415
					   DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
1416
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1417
					   DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
1418
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1419
					   DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
1420
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1421 1422
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1423
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1424 1425
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1426
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1427 1428
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1429
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1430
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
1431
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1432 1433
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1434
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1435 1436
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1437
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1438 1439
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1440
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1441
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1442
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1443 1444 1445 1446 1447 1448 1449 1450
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0xf4000000);

		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a023F11;
	} else if (standard & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) {
		/* Is it SECAM_L1? */
1451
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1452
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1453
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1454
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1455
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1456
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1457
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1458
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1459
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1460
					   DIF_AGC_IF_REF, 0, 31, 0x888C0380);
1461
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1462
					   DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
1463
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1464
					   DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
1465
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1466
					   DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
1467
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1468 1469
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1470
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1471 1472
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1473
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1474 1475
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1476
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1477
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
1478
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1479 1480
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1481
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1482 1483
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1484
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1485 1486
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1487
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1488
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1489
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1490 1491 1492 1493 1494 1495 1496
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0xf2560000);

		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a023F11;

1497
	} else if (standard & V4L2_STD_NTSC_M) {
1498 1499
		/* V4L2_STD_NTSC_M (75 IRE Setup) Or
		   V4L2_STD_NTSC_M_JP (Japan,  0 IRE Setup) */
1500

1501 1502 1503 1504
		/* For NTSC the centre frequency of video coming out of
		   sidewinder is around 7.1MHz or 3.6MHz depending on the
		   spectral inversion. so for a non spectrally inverted channel
		   the pll freq word is 0x03420c49
1505 1506
		 */

1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
		status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0x6503BC0C);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xBD038C85);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1DB4640A);
		status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
		status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C0380);
		status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
						0x26001700);
		status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
						0x00002660);
		status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
						0x04000800);
		status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
						0x27000100);
		status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x01296e1f);

		status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
						0x009f50c1);
		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
						0x1befbf06);
		status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
						0x000035e8);

		status = vid_blk_write_word(dev, DIF_AGC_CTRL_IF, 0xC2262600);
		status = vid_blk_write_word(dev, DIF_AGC_CTRL_INT,
						0xC2262600);
		status = vid_blk_write_word(dev, DIF_AGC_CTRL_RF, 0xC2262600);
1533 1534 1535 1536

		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a003F10;
1537 1538
	} else {
		/* default PAL BG */
1539
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1540
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1541
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1542
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1543
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1544
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1545
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1546
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1547
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1548
					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1549
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1550
					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1551
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1552
					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1553
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1554
					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1555
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1556 1557
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1558
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1559 1560
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1561
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1562 1563
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0x72500800);
1564
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1565 1566
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1567
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1568
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530EC);
1569
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1570 1571
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00A653A8);
1572
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1573 1574
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1575
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1576 1577
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1578
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1579 1580 1581 1582
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a013F11;
1583 1584 1585 1586 1587 1588
	}

	/* The AGC values should be the same for all standards,
	   AUD_SRC_SEL[19] should always be disabled    */
	dif_misc_ctrl_value &= ~FLD_DIF_AUD_SRC_SEL;

1589 1590
	/* It is still possible to get Set Standard calls even when we
	   are in FM mode.
1591 1592 1593 1594 1595
	   This is done to override the value for FM. */
	if (dev->active_mode == V4L2_TUNER_RADIO)
		dif_misc_ctrl_value = 0x7a080000;

	/* Write the calculated value for misc ontrol register      */
1596
	status = vid_blk_write_word(dev, DIF_MISC_CTRL, dif_misc_ctrl_value);
1597 1598

	return status;
1599 1600 1601 1602 1603 1604 1605 1606
}

int cx231xx_tuner_pre_channel_change(struct cx231xx *dev)
{
	int status = 0;
	u32 dwval;

	/* Set the RF and IF k_agc values to 3 */
1607
	status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
1608 1609 1610
	dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
	dwval |= 0x33000000;

1611
	status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
1612

1613
	return status;
1614 1615 1616 1617
}

int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
{
1618
	int status = 0;
1619 1620
	u32 dwval;

1621 1622
	/* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
	 * SECAM L/B/D standards */
1623
	status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
1624
	dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
1625

1626 1627
	if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
			 V4L2_STD_SECAM_D))
1628
		dwval |= 0x88000000;
1629
	else
1630
		dwval |= 0x44000000;
1631

1632
	status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
1633

1634
	return status;
1635 1636
}

1637
/******************************************************************************
1638
 *        	    I 2 S - B L O C K    C O N T R O L   functions            *
1639
 ******************************************************************************/
1640
int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
1641
{
1642 1643 1644
	int status = 0;
	u32 value;

1645
	status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1646
				       CH_PWR_CTRL1, 1, &value, 1);
1647 1648
	/* enables clock to delta-sigma and decimation filter */
	value |= 0x80;
1649
	status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1650 1651
					CH_PWR_CTRL1, 1, value, 1);
	/* power up all channel */
1652
	status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1653 1654 1655
					CH_PWR_CTRL2, 1, 0x00, 1);

	return status;
1656 1657
}

1658
int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
1659
					enum AV_MODE avmode)
1660
{
1661 1662 1663 1664
	int status = 0;
	u32 value = 0;

	if (avmode != POLARIS_AVMODE_ENXTERNAL_AV) {
1665
		status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1666 1667
					  CH_PWR_CTRL2, 1, &value, 1);
		value |= 0xfe;
1668
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1669 1670
						CH_PWR_CTRL2, 1, value, 1);
	} else {
1671
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1672 1673 1674 1675
						CH_PWR_CTRL2, 1, 0x00, 1);
	}

	return status;
1676 1677
}

1678 1679
/* set i2s_blk for audio input types */
int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input)
1680
{
1681
	int status = 0;
1682

1683 1684
	switch (audio_input) {
	case CX231XX_AMUX_LINE_IN:
1685
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1686
						CH_PWR_CTRL2, 1, 0x00, 1);
1687
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
1688 1689 1690 1691 1692 1693
						CH_PWR_CTRL1, 1, 0x80, 1);
		break;
	case CX231XX_AMUX_VIDEO:
	default:
		break;
	}
1694

1695
	dev->ctl_ainput = audio_input;
1696

1697
	return status;
1698 1699
}

1700 1701 1702
/******************************************************************************
 *                  P O W E R      C O N T R O L   functions                  *
 ******************************************************************************/
1703
int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
1704
{
1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718
	u8 value[4] = { 0, 0, 0, 0 };
	u32 tmp = 0;
	int status = 0;

	if (dev->power_mode != mode)
		dev->power_mode = mode;
	else {
		cx231xx_info(" setPowerMode::mode = %d, No Change req.\n",
			     mode);
		return 0;
	}

	cx231xx_info(" setPowerMode::mode = %d\n", mode);

1719 1720
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
				       4);
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735
	if (status < 0)
		return status;

	tmp = *((u32 *) value);

	switch (mode) {
	case POLARIS_AVMODE_ENXTERNAL_AV:

		tmp &= (~PWR_MODE_MASK);

		tmp |= PWR_AV_EN;
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
1736 1737
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
		msleep(PWR_SLEEP_INTERVAL);

		tmp |= PWR_ISO_EN;
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
		status =
		    cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
					   value, 4);
		msleep(PWR_SLEEP_INTERVAL);

		tmp |= POLARIS_AVMODE_ENXTERNAL_AV;
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
1755 1756
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
1757

1758 1759
		/* reset state of xceive tuner */
		dev->xc_fw_load_done = 0;
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769
		break;

	case POLARIS_AVMODE_ANALOGT_TV:

		tmp &= (~PWR_DEMOD_EN);
		tmp |= (I2C_DEMOD_EN);
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
1770 1771
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
1772 1773 1774 1775 1776 1777 1778 1779
		msleep(PWR_SLEEP_INTERVAL);

		if (!(tmp & PWR_TUNER_EN)) {
			tmp |= (PWR_TUNER_EN);
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1780 1781
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1782 1783 1784 1785 1786 1787 1788 1789 1790
			msleep(PWR_SLEEP_INTERVAL);
		}

		if (!(tmp & PWR_AV_EN)) {
			tmp |= PWR_AV_EN;
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1791 1792
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1793 1794 1795 1796 1797 1798 1799 1800
			msleep(PWR_SLEEP_INTERVAL);
		}
		if (!(tmp & PWR_ISO_EN)) {
			tmp |= PWR_ISO_EN;
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1801 1802
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1803 1804 1805 1806 1807 1808 1809 1810 1811
			msleep(PWR_SLEEP_INTERVAL);
		}

		if (!(tmp & POLARIS_AVMODE_ANALOGT_TV)) {
			tmp |= POLARIS_AVMODE_ANALOGT_TV;
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1812 1813
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833
			msleep(PWR_SLEEP_INTERVAL);
		}

		if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
		    (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
			/* tuner path to channel 1 from port 3 */
			cx231xx_enable_i2c_for_tuner(dev, I2C_3);

			if (dev->cx231xx_reset_analog_tuner)
				dev->cx231xx_reset_analog_tuner(dev);
		}
		break;

	case POLARIS_AVMODE_DIGITAL:
		if (!(tmp & PWR_TUNER_EN)) {
			tmp |= (PWR_TUNER_EN);
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1834 1835
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1836 1837 1838 1839 1840 1841 1842 1843
			msleep(PWR_SLEEP_INTERVAL);
		}
		if (!(tmp & PWR_AV_EN)) {
			tmp |= PWR_AV_EN;
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1844 1845
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1846 1847 1848 1849 1850 1851 1852 1853
			msleep(PWR_SLEEP_INTERVAL);
		}
		if (!(tmp & PWR_ISO_EN)) {
			tmp |= PWR_ISO_EN;
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1854 1855
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1856 1857 1858 1859 1860 1861 1862 1863
			msleep(PWR_SLEEP_INTERVAL);
		}

		tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN;
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
1864 1865
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
1866 1867 1868 1869 1870 1871 1872 1873
		msleep(PWR_SLEEP_INTERVAL);

		if (!(tmp & PWR_DEMOD_EN)) {
			tmp |= PWR_DEMOD_EN;
			value[0] = (u8) tmp;
			value[1] = (u8) (tmp >> 8);
			value[2] = (u8) (tmp >> 16);
			value[3] = (u8) (tmp >> 24);
1874 1875
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894
			msleep(PWR_SLEEP_INTERVAL);
		}

		if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
		    (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
			/* tuner path to channel 1 from port 3 */
			cx231xx_enable_i2c_for_tuner(dev, I2C_3);

			if (dev->cx231xx_reset_analog_tuner)
				dev->cx231xx_reset_analog_tuner(dev);
		}
		break;

	default:
		break;
	}

	msleep(PWR_SLEEP_INTERVAL);

1895 1896
	/* For power saving, only enable Pwr_resetout_n
	   when digital TV is selected. */
1897 1898 1899 1900 1901 1902
	if (mode == POLARIS_AVMODE_DIGITAL) {
		tmp |= PWR_RESETOUT_EN;
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
1903 1904
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
1905 1906 1907
		msleep(PWR_SLEEP_INTERVAL);
	}

1908 1909
	/* update power control for afe */
	status = cx231xx_afe_update_power_control(dev, mode);
1910

1911 1912
	/* update power control for i2s_blk */
	status = cx231xx_i2s_blk_update_power_control(dev, mode);
1913

1914 1915
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
				       4);
1916 1917
	cx231xx_info(" The data of PWR_CTL_EN register 0x74"
				 "=0x%0x,0x%0x,0x%0x,0x%0x\n",
1918
		     value[0], value[1], value[2], value[3]);
1919 1920

	return status;
1921 1922 1923 1924
}

int cx231xx_power_suspend(struct cx231xx *dev)
{
1925 1926 1927
	u8 value[4] = { 0, 0, 0, 0 };
	u32 tmp = 0;
	int status = 0;
1928

1929 1930
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
				       value, 4);
1931 1932
	if (status > 0)
		return status;
1933

1934 1935
	tmp = *((u32 *) value);
	tmp &= (~PWR_MODE_MASK);
1936

1937 1938 1939 1940
	value[0] = (u8) tmp;
	value[1] = (u8) (tmp >> 8);
	value[2] = (u8) (tmp >> 16);
	value[3] = (u8) (tmp >> 24);
1941 1942
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
					value, 4);
1943

1944
	return status;
1945 1946
}

1947 1948 1949
/******************************************************************************
 *                  S T R E A M    C O N T R O L   functions                  *
 ******************************************************************************/
1950 1951
int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask)
{
1952 1953 1954
	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
	u32 tmp = 0;
	int status = 0;
1955

1956
	cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask);
1957 1958
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
				       value, 4);
1959 1960
	if (status < 0)
		return status;
1961

1962 1963 1964 1965 1966 1967
	tmp = *((u32 *) value);
	tmp |= ep_mask;
	value[0] = (u8) tmp;
	value[1] = (u8) (tmp >> 8);
	value[2] = (u8) (tmp >> 16);
	value[3] = (u8) (tmp >> 24);
1968

1969 1970
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
					value, 4);
1971

1972
	return status;
1973 1974 1975 1976
}

int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
{
1977 1978 1979
	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
	u32 tmp = 0;
	int status = 0;
1980

1981 1982 1983 1984 1985
	cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask);
	status =
	    cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4);
	if (status < 0)
		return status;
1986

1987 1988 1989 1990 1991 1992
	tmp = *((u32 *) value);
	tmp &= (~ep_mask);
	value[0] = (u8) tmp;
	value[1] = (u8) (tmp >> 8);
	value[2] = (u8) (tmp >> 16);
	value[3] = (u8) (tmp >> 24);
1993

1994 1995
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
					value, 4);
1996

1997
	return status;
1998 1999 2000 2001
}

int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
{
2002
	int status = 0;
2003

2004 2005
	if (dev->udev->speed == USB_SPEED_HIGH) {
		switch (media_type) {
2006
		case 81: /* audio */
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
			cx231xx_info("%s: Audio enter HANC\n", __func__);
			status =
			    cx231xx_mode_register(dev, TS_MODE_REG, 0x9300);
			break;

		case 2:	/* vbi */
			cx231xx_info("%s: set vanc registers\n", __func__);
			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300);
			break;

		case 3:	/* sliced cc */
			cx231xx_info("%s: set hanc registers\n", __func__);
			status =
			    cx231xx_mode_register(dev, TS_MODE_REG, 0x1300);
			break;

		case 0:	/* video */
			cx231xx_info("%s: set video registers\n", __func__);
			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
			break;

		case 4:	/* ts1 */
			cx231xx_info("%s: set ts1 registers\n", __func__);
			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
			status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
			break;
		case 6:	/* ts1 parallel mode */
			cx231xx_info("%s: set ts1 parrallel mode registers\n",
				     __func__);
			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
			status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
			break;
		}
	} else {
		status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
	}
2043

2044 2045
	return status;
}
2046 2047 2048

int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
{
2049
	int rc = -1;
2050
	u32 ep_mask = -1;
2051
	struct pcb_config *pcb_config;
2052 2053

	/* get EP for media type */
2054
	pcb_config = (struct pcb_config *)&dev->current_pcb_config;
2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106

	if (pcb_config->config_num == 1) {
		switch (media_type) {
		case 0:	/* Video */
			ep_mask = ENABLE_EP4;	/* ep4  [00:1000] */
			break;
		case 1:	/* Audio */
			ep_mask = ENABLE_EP3;	/* ep3  [00:0100] */
			break;
		case 2:	/* Vbi */
			ep_mask = ENABLE_EP5;	/* ep5 [01:0000] */
			break;
		case 3:	/* Sliced_cc */
			ep_mask = ENABLE_EP6;	/* ep6 [10:0000] */
			break;
		case 4:	/* ts1 */
		case 6:	/* ts1 parallel mode */
			ep_mask = ENABLE_EP1;	/* ep1 [00:0001] */
			break;
		case 5:	/* ts2 */
			ep_mask = ENABLE_EP2;	/* ep2 [00:0010] */
			break;
		}

	} else if (pcb_config->config_num > 1) {
		switch (media_type) {
		case 0:	/* Video */
			ep_mask = ENABLE_EP4;	/* ep4  [00:1000] */
			break;
		case 1:	/* Audio */
			ep_mask = ENABLE_EP3;	/* ep3  [00:0100] */
			break;
		case 2:	/* Vbi */
			ep_mask = ENABLE_EP5;	/* ep5 [01:0000] */
			break;
		case 3:	/* Sliced_cc */
			ep_mask = ENABLE_EP6;	/* ep6 [10:0000] */
			break;
		case 4:	/* ts1 */
		case 6:	/* ts1 parallel mode */
			ep_mask = ENABLE_EP1;	/* ep1 [00:0001] */
			break;
		case 5:	/* ts2 */
			ep_mask = ENABLE_EP2;	/* ep2 [00:0010] */
			break;
		}

	}

	if (start) {
		rc = cx231xx_initialize_stream_xfer(dev, media_type);

2107
		if (rc < 0)
2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118
			return rc;

		/* enable video capture */
		if (ep_mask > 0)
			rc = cx231xx_start_stream(dev, ep_mask);
	} else {
		/* disable video capture */
		if (ep_mask > 0)
			rc = cx231xx_stop_stream(dev, ep_mask);
	}

2119 2120 2121 2122
	if (dev->mode == CX231XX_ANALOG_MODE)
		;/* do any in Analog mode */
	else
		;/* do any in digital mode */
2123 2124 2125

	return rc;
}
2126
EXPORT_SYMBOL_GPL(cx231xx_capture_start);
2127

2128 2129 2130
/*****************************************************************************
*                   G P I O   B I T control functions                        *
******************************************************************************/
2131
int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
2132
{
2133
	int status = 0;
2134

2135
	status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0);
2136

2137
	return status;
2138 2139
}

2140
int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
2141
{
2142
	int status = 0;
2143

2144
	status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1);
2145

2146
	return status;
2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160
}

/*
* cx231xx_set_gpio_direction
*      Sets the direction of the GPIO pin to input or output
*
* Parameters :
*      pin_number : The GPIO Pin number to program the direction for
*                   from 0 to 31
*      pin_value : The Direction of the GPIO Pin under reference.
*                      0 = Input direction
*                      1 = Output direction
*/
int cx231xx_set_gpio_direction(struct cx231xx *dev,
2161
			       int pin_number, int pin_value)
2162 2163
{
	int status = 0;
2164
	u32 value = 0;
2165

2166
	/* Check for valid pin_number - if 32 , bail out */
2167
	if (pin_number >= 32)
2168
		return -EINVAL;
2169

2170 2171
	/* input */
	if (pin_value == 0)
2172
		value = dev->gpio_dir & (~(1 << pin_number));	/* clear */
2173
	else
2174
		value = dev->gpio_dir | (1 << pin_number);
2175

2176
	status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val);
2177

2178
	/* cache the value for future */
2179 2180
	dev->gpio_dir = value;

2181
	return status;
2182 2183 2184
}

/*
2185
* cx231xx_set_gpio_value
2186 2187 2188 2189 2190 2191 2192 2193 2194
*      Sets the value of the GPIO pin to Logic high or low. The Pin under
*      reference should ALREADY BE SET IN OUTPUT MODE !!!!!!!!!
*
* Parameters :
*      pin_number : The GPIO Pin number to program the direction for
*      pin_value : The value of the GPIO Pin under reference.
*                      0 = set it to 0
*                      1 = set it to 1
*/
2195
int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value)
2196
{
2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208
	int status = 0;
	u32 value = 0;

	/* Check for valid pin_number - if 0xFF , bail out */
	if (pin_number >= 32)
		return -EINVAL;

	/* first do a sanity check - if the Pin is not output, make it output */
	if ((dev->gpio_dir & (1 << pin_number)) == 0x00) {
		/* It was in input mode */
		value = dev->gpio_dir | (1 << pin_number);
		dev->gpio_dir = value;
2209 2210
		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
					      (u8 *) &dev->gpio_val);
2211
		value = 0;
2212
	}
2213

2214
	if (pin_value == 0)
2215
		value = dev->gpio_val & (~(1 << pin_number));
2216
	else
2217
		value = dev->gpio_val | (1 << pin_number);
2218

2219 2220
	/* store the value */
	dev->gpio_val = value;
2221

2222
	/* toggle bit0 of GP_IO */
2223
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2224

2225
	return status;
2226 2227
}

2228 2229 2230
/*****************************************************************************
*                      G P I O I2C related functions                         *
******************************************************************************/
2231 2232 2233 2234 2235
int cx231xx_gpio_i2c_start(struct cx231xx *dev)
{
	int status = 0;

	/* set SCL to output 1 ; set SDA to output 1 */
2236 2237 2238 2239 2240
	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;

2241 2242
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2243 2244 2245
		return -EINVAL;

	/* set SCL to output 1; set SDA to output 0 */
2246 2247
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2248

2249 2250
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2251 2252
		return -EINVAL;

2253 2254 2255
	/* set SCL to output 0; set SDA to output 0      */
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2256

2257 2258
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2259 2260 2261 2262 2263 2264 2265
		return -EINVAL;

	return status;
}

int cx231xx_gpio_i2c_end(struct cx231xx *dev)
{
2266
	int status = 0;
2267

2268 2269 2270
	/* set SCL to output 0; set SDA to output 0      */
	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2271

2272 2273
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2274

2275 2276
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2277 2278
		return -EINVAL;

2279 2280 2281
	/* set SCL to output 1; set SDA to output 0      */
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2282

2283 2284
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2285 2286 2287 2288
		return -EINVAL;

	/* set SCL to input ,release SCL cable control
	   set SDA to input ,release SDA cable control */
2289 2290
	dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2291

2292
	status =
2293 2294
	    cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2295
		return -EINVAL;
2296

2297 2298 2299 2300 2301
	return status;
}

int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
{
2302 2303
	int status = 0;
	u8 i;
2304 2305

	/* set SCL to output ; set SDA to output */
2306 2307 2308 2309 2310 2311 2312 2313
	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;

	for (i = 0; i < 8; i++) {
		if (((data << i) & 0x80) == 0) {
			/* set SCL to output 0; set SDA to output 0     */
			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
			dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2314 2315
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2316 2317 2318

			/* set SCL to output 1; set SDA to output 0     */
			dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2319 2320
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2321 2322 2323

			/* set SCL to output 0; set SDA to output 0     */
			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2324 2325
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2326
		} else {
2327 2328 2329
			/* set SCL to output 0; set SDA to output 1     */
			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
			dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
2330 2331
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2332 2333 2334

			/* set SCL to output 1; set SDA to output 1     */
			dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2335 2336
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2337 2338 2339

			/* set SCL to output 0; set SDA to output 1     */
			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2340 2341
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2342
		}
2343 2344 2345 2346
	}
	return status;
}

2347
int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf)
2348 2349
{
	u8 value = 0;
2350 2351 2352
	int status = 0;
	u32 gpio_logic_value = 0;
	u8 i;
2353 2354

	/* read byte */
2355
	for (i = 0; i < 8; i++) {	/* send write I2c addr */
2356 2357

		/* set SCL to output 0; set SDA to input */
2358
		dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2359 2360
		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
2361 2362

		/* set SCL to output 1; set SDA to input */
2363
		dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2364 2365
		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
2366 2367 2368

		/* get SDA data bit */
		gpio_logic_value = dev->gpio_val;
2369 2370 2371
		status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
		if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0)
2372
			value |= (1 << (8 - i - 1));
2373 2374 2375 2376 2377

		dev->gpio_val = gpio_logic_value;
	}

	/* set SCL to output 0,finish the read latest SCL signal.
2378 2379
	   !!!set SDA to input, never to modify SDA direction at
	   the same times */
2380
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2381
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2382

2383 2384
	/* store the value */
	*buf = value & 0xff;
2385 2386 2387 2388 2389 2390

	return status;
}

int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev)
{
2391
	int status = 0;
2392
	u32 gpio_logic_value = 0;
2393 2394
	int nCnt = 10;
	int nInit = nCnt;
2395

2396 2397
	/* clock stretch; set SCL to input; set SDA to input;
	   get SCL value till SCL = 1 */
2398 2399
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
	dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
2400 2401

	gpio_logic_value = dev->gpio_val;
2402
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2403

2404
	do {
2405
		msleep(2);
2406 2407
		status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
2408
		nCnt--;
2409 2410 2411
	} while (((dev->gpio_val &
			  (1 << dev->board.tuner_scl_gpio)) == 0) &&
			 (nCnt > 0));
2412

2413
	if (nCnt == 0)
2414
		cx231xx_info("No ACK after %d msec -GPIO I2C failed!",
2415
			     nInit * 10);
2416 2417

	/* readAck
2418 2419 2420
	   throuth clock stretch ,slave has given a SCL signal,
	   so the SDA data can be directly read.  */
	status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2421

2422
	if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
2423
		dev->gpio_val = gpio_logic_value;
2424
		dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2425 2426 2427
		status = 0;
	} else {
		dev->gpio_val = gpio_logic_value;
2428
		dev->gpio_val |= (1 << dev->board.tuner_sda_gpio);
2429 2430
	}

2431 2432
	/* read SDA end, set the SCL to output 0, after this operation,
	   SDA direction can be changed. */
2433
	dev->gpio_val = gpio_logic_value;
2434 2435
	dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2436
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2437 2438 2439 2440 2441 2442

	return status;
}

int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev)
{
2443
	int status = 0;
2444 2445

	/* set SDA to ouput */
2446
	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2447
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2448 2449

	/* set SCL = 0 (output); set SDA = 0 (output) */
2450 2451
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2452
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2453 2454

	/* set SCL = 1 (output); set SDA = 0 (output) */
2455
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2456
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2457 2458

	/* set SCL = 0 (output); set SDA = 0 (output) */
2459
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2460
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2461 2462

	/* set SDA to input,and then the slave will read data from SDA. */
2463
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2464
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2465 2466 2467 2468 2469 2470

	return status;
}

int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
{
2471
	int status = 0;
2472 2473

	/* set scl to output ; set sda to input */
2474 2475
	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
2476
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2477 2478

	/* set scl to output 0; set sda to input */
2479
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2480
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2481 2482

	/* set scl to output 1; set sda to input */
2483
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2484
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2485 2486 2487 2488

	return status;
}

2489 2490 2491
/*****************************************************************************
*                      G P I O I2C related functions                         *
******************************************************************************/
2492 2493 2494
/* cx231xx_gpio_i2c_read
 * Function to read data from gpio based I2C interface
 */
2495
int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
2496
{
2497 2498
	int status = 0;
	int i = 0;
2499

2500
	/* get the lock */
2501 2502 2503 2504 2505 2506
	mutex_lock(&dev->gpio_i2c_lock);

	/* start */
	status = cx231xx_gpio_i2c_start(dev);

	/* write dev_addr */
2507
	status = cx231xx_gpio_i2c_write_byte(dev, (dev_addr << 1) + 1);
2508 2509 2510 2511

	/* readAck */
	status = cx231xx_gpio_i2c_read_ack(dev);

2512 2513 2514 2515 2516
	/* read data */
	for (i = 0; i < len; i++) {
		/* read data */
		buf[i] = 0;
		status = cx231xx_gpio_i2c_read_byte(dev, &buf[i]);
2517

2518 2519 2520 2521 2522
		if ((i + 1) != len) {
			/* only do write ack if we more length */
			status = cx231xx_gpio_i2c_write_ack(dev);
		}
	}
2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538

	/* write NAK - inform reads are complete */
	status = cx231xx_gpio_i2c_write_nak(dev);

	/* write end */
	status = cx231xx_gpio_i2c_end(dev);

	/* release the lock */
	mutex_unlock(&dev->gpio_i2c_lock);

	return status;
}

/* cx231xx_gpio_i2c_write
 * Function to write data to gpio based I2C interface
 */
2539
int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
2540
{
2541 2542
	int status = 0;
	int i = 0;
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553

	/* get the lock */
	mutex_lock(&dev->gpio_i2c_lock);

	/* start */
	status = cx231xx_gpio_i2c_start(dev);

	/* write dev_addr */
	status = cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1);

	/* read Ack */
2554
	status = cx231xx_gpio_i2c_read_ack(dev);
2555

2556
	for (i = 0; i < len; i++) {
2557
		/* Write data */
2558
		status = cx231xx_gpio_i2c_write_byte(dev, buf[i]);
2559

2560 2561 2562
		/* read Ack */
		status = cx231xx_gpio_i2c_read_ack(dev);
	}
2563

2564
	/* write End */
2565 2566 2567 2568 2569 2570 2571
	status = cx231xx_gpio_i2c_end(dev);

	/* release the lock */
	mutex_unlock(&dev->gpio_i2c_lock);

	return 0;
}