cx231xx-avcore.c 91.2 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

   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>
34
#include <media/tuner.h>
35 36 37 38 39 40

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

#include "cx231xx.h"
41
#include "cx231xx-dif.h"
42

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

*******************************************************************************/
56 57
/******************************************************************************
 *                    VERVE REGISTER                                          *
58
 *									      *
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
 ******************************************************************************/
static int verve_write_byte(struct cx231xx *dev, u8 saddr, u8 data)
{
	return cx231xx_write_i2c_data(dev, VERVE_I2C_ADDRESS,
					saddr, 1, data, 1);
}

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

	status = cx231xx_read_i2c_data(dev, VERVE_I2C_ADDRESS,
					saddr, 1, &temp, 1);
	*data = (u8) temp;
	return status;
}
void initGPIO(struct cx231xx *dev)
{
	u32 _gpio_direction = 0;
	u32 value = 0;
	u8 val = 0;

	_gpio_direction = _gpio_direction & 0xFC0003FF;
	_gpio_direction = _gpio_direction | 0x03FDFC00;
	cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0);

	verve_read_byte(dev, 0x07, &val);
	cx231xx_info(" verve_read_byte address0x07=0x%x\n", val);
	verve_write_byte(dev, 0x07, 0xF4);
	verve_read_byte(dev, 0x07, &val);
	cx231xx_info(" verve_read_byte address0x07=0x%x\n", val);

	cx231xx_capture_start(dev, 1, 2);

	cx231xx_mode_register(dev, EP_MODE_SET, 0x0500FE00);
	cx231xx_mode_register(dev, GBULK_BIT_EN, 0xFFFDFFFF);

}
void uninitGPIO(struct cx231xx *dev)
{
	u8 value[4] = { 0, 0, 0, 0 };

	cx231xx_capture_start(dev, 0, 2);
	verve_write_byte(dev, 0x07, 0x14);
	cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
			0x68, value, 4);
}
107 108 109 110

/******************************************************************************
 *                    A F E - B L O C K    C O N T R O L   functions          *
 * 				[ANALOG FRONT END]			      *
111
 ******************************************************************************/
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
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)
130
{
131 132
	int status = 0;
	u8 temp = 0;
133
	u8 afe_power_status = 0;
134 135 136 137
	int i = 0;

	/* super block initialize */
	temp = (u8) (ref_count & 0xff);
138
	status = afe_write_byte(dev, SUP_BLK_TUNE2, temp);
139 140
	if (status < 0)
		return status;
141

142
	status = afe_read_byte(dev, SUP_BLK_TUNE2, &afe_power_status);
143 144
	if (status < 0)
		return status;
145 146 147

	temp = (u8) ((ref_count & 0x300) >> 8);
	temp |= 0x40;
148
	status = afe_write_byte(dev, SUP_BLK_TUNE1, temp);
149 150 151
	if (status < 0)
		return status;

152
	status = afe_write_byte(dev, SUP_BLK_PLL2, 0x0f);
153 154
	if (status < 0)
		return status;
155 156

	/* enable pll     */
157 158
	while (afe_power_status != 0x18) {
		status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18);
159 160 161 162 163 164
		if (status < 0) {
			cx231xx_info(
			": Init Super Block failed in send cmd\n");
			break;
		}

165 166
		status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status);
		afe_power_status &= 0xff;
167
		if (status < 0) {
168
			cx231xx_info(
169
			": Init Super Block failed in receive cmd\n");
170 171 172 173
			break;
		}
		i++;
		if (i == 10) {
174 175
			cx231xx_info(
			": Init Super Block force break in loop !!!!\n");
176 177 178 179 180 181 182 183 184
			status = -1;
			break;
		}
	}

	if (status < 0)
		return status;

	/* start tuning filter */
185
	status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x40);
186 187 188
	if (status < 0)
		return status;

189 190 191
	msleep(5);

	/* exit tuning */
192
	status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x00);
193 194

	return status;
195 196
}

197
int cx231xx_afe_init_channels(struct cx231xx *dev)
198
{
199 200 201
	int status = 0;

	/* power up all 3 channels, clear pd_buffer */
202 203 204
	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);
205 206

	/* Enable quantizer calibration */
207
	status = afe_write_byte(dev, ADC_COM_QUANT, 0x02);
208 209

	/* channel initialize, force modulator (fb) reset */
210 211 212
	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);
213 214

	/* start quantilizer calibration  */
215 216 217
	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);
218 219 220
	msleep(5);

	/* exit modulator (fb) reset */
221 222 223
	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);
224 225

	/* enable the pre_clamp in each channel for single-ended input */
226 227 228
	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);
229 230

	/* use diode instead of resistor, so set term_en to 0, res_en to 0  */
231
	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
232
				   ADC_QGAIN_RES_TRM_CH1, 3, 7, 0x00);
233
	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
234
				   ADC_QGAIN_RES_TRM_CH2, 3, 7, 0x00);
235
	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
236 237 238
				   ADC_QGAIN_RES_TRM_CH3, 3, 7, 0x00);

	/* dynamic element matching off */
239 240 241
	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);
242 243

	return status;
244 245
}

246
int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev)
247
{
248
	u8 c_value = 0;
249
	int status = 0;
250

251
	status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH2, &c_value);
252
	c_value &= (~(0x50));
253
	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, c_value);
254

255
	return status;
256 257 258
}

/*
259 260 261 262
	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.

263 264 265 266
	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)
*/
267
int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
268
{
269 270 271 272
	u8 ch1_setting = (u8) input_mux;
	u8 ch2_setting = (u8) (input_mux >> 8);
	u8 ch3_setting = (u8) (input_mux >> 16);
	int status = 0;
273
	u8 value = 0;
274 275

	if (ch1_setting != 0) {
276
		status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
277
		value &= ~INPUT_SEL_MASK;
278 279
		value |= (ch1_setting - 1) << 4;
		value &= 0xff;
280
		status = afe_write_byte(dev, ADC_INPUT_CH1, value);
281 282 283
	}

	if (ch2_setting != 0) {
284
		status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
285
		value &= ~INPUT_SEL_MASK;
286 287
		value |= (ch2_setting - 1) << 4;
		value &= 0xff;
288
		status = afe_write_byte(dev, ADC_INPUT_CH2, value);
289 290
	}

291 292
	/* For ch3_setting, the value to put in the register is
	   7 less than the input number */
293
	if (ch3_setting != 0) {
294
		status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
295
		value &= ~INPUT_SEL_MASK;
296 297
		value |= (ch3_setting - 1) << 4;
		value &= 0xff;
298
		status = afe_write_byte(dev, ADC_INPUT_CH3, value);
299 300 301
	}

	return status;
302 303
}

304
int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
305
{
306 307
	int status = 0;

308 309 310 311 312
	/*
	* FIXME: We need to implement the AFE code for LOW IF and for HI IF.
	* Currently, only baseband works.
	*/

313 314
	switch (mode) {
	case AFE_MODE_LOW_IF:
315
		cx231xx_Setup_AFE_for_LowIF(dev);
316 317
		break;
	case AFE_MODE_BASEBAND:
318
		status = cx231xx_afe_setup_AFE_for_baseband(dev);
319 320 321 322 323 324 325 326 327 328 329 330
		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;
	}

331
	if ((mode != dev->afe_mode) &&
332
		(dev->video_input == CX231XX_VMUX_TELEVISION))
333
		status = cx231xx_afe_adjust_ref_count(dev,
334 335
						     CX231XX_VMUX_TELEVISION);

336
	dev->afe_mode = mode;
337 338

	return status;
339 340
}

341
int cx231xx_afe_update_power_control(struct cx231xx *dev,
342
					enum AV_MODE avmode)
343
{
344
	u8 afe_power_status = 0;
345 346 347
	int status = 0;

	switch (dev->model) {
348
	case CX231XX_BOARD_CNXT_CARRAERA:
349
	case CX231XX_BOARD_CNXT_RDE_250:
350
	case CX231XX_BOARD_CNXT_SHELBY:
351
	case CX231XX_BOARD_CNXT_RDU_250:
352 353 354
	case CX231XX_BOARD_CNXT_RDE_253S:
	case CX231XX_BOARD_CNXT_RDU_253S:
	case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
355
	case CX231XX_BOARD_HAUPPAUGE_EXETER:
356
	case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
357
	case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
358
		if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
359
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
360
						FLD_PWRDN_ENABLE_PLL)) {
361
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
362
							FLD_PWRDN_TUNING_BIAS |
363 364 365
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
366 367 368 369
				if (status < 0)
					break;
			}

370 371 372 373 374 375
			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);
376
		} else if (avmode == POLARIS_AVMODE_DIGITAL) {
377 378 379 380 381 382 383 384 385 386
			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 |
387 388
						FLD_PWRDN_PD_BIAS |
						FLD_PWRDN_PD_TUNECK;
389 390
			status |= afe_write_byte(dev, SUP_BLK_PWRDN,
						   afe_power_status);
391
		} else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
392
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
393
						FLD_PWRDN_ENABLE_PLL)) {
394
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
395
							FLD_PWRDN_TUNING_BIAS |
396 397 398
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
399 400 401 402
				if (status < 0)
					break;
			}

403 404 405 406 407 408
			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);
409 410 411 412 413 414 415
		} else {
			cx231xx_info("Invalid AV mode input\n");
			status = -1;
		}
		break;
	default:
		if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
416
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
417
						FLD_PWRDN_ENABLE_PLL)) {
418
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
419
							FLD_PWRDN_TUNING_BIAS |
420 421 422
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
423 424 425 426
				if (status < 0)
					break;
			}

427 428 429 430 431 432
			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);
433
		} else if (avmode == POLARIS_AVMODE_DIGITAL) {
434 435 436 437 438 439 440 441 442 443
			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 |
444 445
						FLD_PWRDN_PD_BIAS |
						FLD_PWRDN_PD_TUNECK;
446 447
			status |= afe_write_byte(dev, SUP_BLK_PWRDN,
							afe_power_status);
448
		} else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
449
			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
450
						FLD_PWRDN_ENABLE_PLL)) {
451
				status = afe_write_byte(dev, SUP_BLK_PWRDN,
452
							FLD_PWRDN_TUNING_BIAS |
453 454 455
							FLD_PWRDN_ENABLE_PLL);
				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
							&afe_power_status);
456 457 458 459
				if (status < 0)
					break;
			}

460 461 462 463 464 465
			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);
466 467 468 469 470 471 472
		} else {
			cx231xx_info("Invalid AV mode input\n");
			status = -1;
		}
	}			/* switch  */

	return status;
473 474
}

475
int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input)
476
{
477 478
	u8 input_mode = 0;
	u8 ntf_mode = 0;
479 480 481 482 483
	int status = 0;

	dev->video_input = video_input;

	if (video_input == CX231XX_VMUX_TELEVISION) {
484 485 486
		status = afe_read_byte(dev, ADC_INPUT_CH3, &input_mode);
		status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3,
					&ntf_mode);
487
	} else {
488 489 490
		status = afe_read_byte(dev, ADC_INPUT_CH1, &input_mode);
		status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH1,
					&ntf_mode);
491
	}
492

493 494 495 496
	input_mode = (ntf_mode & 0x3) | ((input_mode & 0x6) << 1);

	switch (input_mode) {
	case SINGLE_ENDED:
497
		dev->afe_ref_count = 0x23C;
498 499
		break;
	case LOW_IF:
500
		dev->afe_ref_count = 0x24C;
501 502
		break;
	case EU_IF:
503
		dev->afe_ref_count = 0x258;
504 505
		break;
	case US_IF:
506
		dev->afe_ref_count = 0x260;
507 508 509 510 511
		break;
	default:
		break;
	}

512
	status = cx231xx_afe_init_super_block(dev, dev->afe_ref_count);
513

514 515
	return status;
}
516

517 518
/******************************************************************************
 *     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    *
519
 ******************************************************************************/
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
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);
}
548 549 550 551 552 553 554 555 556 557 558
int cx231xx_check_fw(struct cx231xx *dev)
{
	u8 temp = 0;
	int status = 0;
	status = vid_blk_read_byte(dev, DL_CTL_ADDRESS_LOW, &temp);
	if (status < 0)
		return status;
	else
		return temp;

}
559

560 561
int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
{
562 563 564 565 566 567 568
	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)) {
569 570 571
			/* External AV */
			status = cx231xx_set_power_mode(dev,
					POLARIS_AVMODE_ENXTERNAL_AV);
572
			if (status < 0) {
573 574 575
				cx231xx_errdev("%s: set_power_mode : Failed to"
						" set Power - errCode [%d]!\n",
						__func__, status);
576 577 578
				return status;
			}
		}
579 580 581
		status = cx231xx_set_decoder_video_input(dev,
							 INPUT(input)->type,
							 INPUT(input)->vmux);
582 583 584 585 586
		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)) {
587 588 589
			/* Tuner */
			status = cx231xx_set_power_mode(dev,
						POLARIS_AVMODE_ANALOGT_TV);
590
			if (status < 0) {
591 592 593
				cx231xx_errdev("%s: set_power_mode:Failed"
					" to set Power - errCode [%d]!\n",
					__func__, status);
594 595 596
				return status;
			}
		}
597 598 599 600 601 602
		if (dev->tuner_type == TUNER_NXP_TDA18271)
			status = cx231xx_set_decoder_video_input(dev,
							CX231XX_VMUX_TELEVISION,
							INPUT(input)->vmux);
		else
			status = cx231xx_set_decoder_video_input(dev,
603 604
							CX231XX_VMUX_COMPOSITE1,
							INPUT(input)->vmux);
605

606 607
		break;
	default:
608
		cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n",
609 610 611 612 613 614 615 616
		     __func__, INPUT(input)->type);
		break;
	}

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

	return status;
617 618
}

619 620
int cx231xx_set_decoder_video_input(struct cx231xx *dev,
				u8 pin_type, u8 input)
621
{
622 623 624 625
	int status = 0;
	u32 value = 0;

	if (pin_type != dev->video_input) {
626
		status = cx231xx_afe_adjust_ref_count(dev, pin_type);
627
		if (status < 0) {
628
			cx231xx_errdev("%s: adjust_ref_count :Failed to set"
629
				"AFE input mux - errCode [%d]!\n",
630
				__func__, status);
631 632 633
			return status;
		}
	}
634

635 636
	/* call afe block to set video inputs */
	status = cx231xx_afe_set_input_mux(dev, input);
637
	if (status < 0) {
638
		cx231xx_errdev("%s: set_input_mux :Failed to set"
639
				" AFE input mux - errCode [%d]!\n",
640
				__func__, status);
641 642 643 644 645
		return status;
	}

	switch (pin_type) {
	case CX231XX_VMUX_COMPOSITE1:
646
		status = vid_blk_read_word(dev, AFE_CTRL, &value);
647 648 649
		value |= (0 << 13) | (1 << 4);
		value &= ~(1 << 5);

650 651 652 653
		/* set [24:23] [22:15] to 0  */
		value &= (~(0x1ff8000));
		/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0  */
		value |= 0x1000000;
654
		status = vid_blk_write_word(dev, AFE_CTRL, value);
655

656
		status = vid_blk_read_word(dev, OUT_CTRL1, &value);
657
		value |= (1 << 7);
658
		status = vid_blk_write_word(dev, OUT_CTRL1, value);
659

660
		/* Set output mode */
661
		status = cx231xx_read_modify_write_i2c_dword(dev,
662
							VID_BLK_I2C_ADDRESS,
663 664
							OUT_CTRL1,
							FLD_OUT_MODE,
665
							dev->board.output_mode);
666 667 668 669

		/* Tell DIF object to go to baseband mode  */
		status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
		if (status < 0) {
670 671
			cx231xx_errdev("%s: cx231xx_dif set to By pass"
						   " mode- errCode [%d]!\n",
672 673 674 675 676
				__func__, status);
			return status;
		}

		/* Read the DFE_CTRL1 register */
677
		status = vid_blk_read_word(dev, DFE_CTRL1, &value);
678 679 680 681 682 683 684 685

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

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

		/* Write it back */
686
		status = vid_blk_write_word(dev, DFE_CTRL1, value);
687 688 689

		/* Disable auto config of registers */
		status = cx231xx_read_modify_write_i2c_dword(dev,
690
					VID_BLK_I2C_ADDRESS,
691 692 693 694 695
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));

		/* Set CVBS input mode */
		status = cx231xx_read_modify_write_i2c_dword(dev,
696
			VID_BLK_I2C_ADDRESS,
697 698 699 700 701 702
			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 */

703
		status = vid_blk_read_word(dev, AFE_CTRL, &value);
704

705 706 707 708 709
		/* 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;
710
		status = vid_blk_write_word(dev, AFE_CTRL, value);
711 712 713 714

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

		/* Read the DFE_CTRL1 register */
722
		status = vid_blk_read_word(dev, DFE_CTRL1, &value);
723 724 725 726 727 728 729 730

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

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

		/* Write it back */
731
		status = vid_blk_write_word(dev, DFE_CTRL1, value);
732 733 734

		/* Disable auto config of registers  */
		status =  cx231xx_read_modify_write_i2c_dword(dev,
735
					VID_BLK_I2C_ADDRESS,
736 737 738 739 740
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));

		/* Set YC input mode */
		status = cx231xx_read_modify_write_i2c_dword(dev,
741
			VID_BLK_I2C_ADDRESS,
742 743 744 745 746
			MODE_CTRL,
			FLD_INPUT_MODE,
			cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_YC_1));

		/* Chroma to ADC2 */
747
		status = vid_blk_read_word(dev, AFE_CTRL, &value);
748 749 750 751 752 753 754
		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);

755
		status = vid_blk_write_word(dev, AFE_CTRL, value);
756

757
		status = cx231xx_afe_set_mode(dev, AFE_MODE_BASEBAND);
758 759 760 761
		break;
	case CX231XX_VMUX_TELEVISION:
	case CX231XX_VMUX_CABLE:
	default:
762 763
		/* TODO: Test if this is also needed for xc2028/xc3028 */
		if (dev->board.tuner_type == TUNER_XC5000) {
764 765
			/* Disable the use of  DIF   */

766
			status = vid_blk_read_word(dev, AFE_CTRL, &value);
767 768 769
			value |= (0 << 13) | (1 << 4);
			value &= ~(1 << 5);

770 771 772 773
			/* set [24:23] [22:15] to 0 */
			value &= (~(0x1FF8000));
			/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
			value |= 0x1000000;
774 775 776
			status = vid_blk_write_word(dev, AFE_CTRL, value);

			status = vid_blk_read_word(dev, OUT_CTRL1, &value);
777
			value |= (1 << 7);
778
			status = vid_blk_write_word(dev, OUT_CTRL1, value);
779

780
			/* Set output mode */
781
			status = cx231xx_read_modify_write_i2c_dword(dev,
782
							VID_BLK_I2C_ADDRESS,
783
							OUT_CTRL1, FLD_OUT_MODE,
784
							dev->board.output_mode);
785

786 787 788
			/* Tell DIF object to go to baseband mode */
			status = cx231xx_dif_set_standard(dev,
							  DIF_USE_BASEBAND);
789
			if (status < 0) {
790 791 792
				cx231xx_errdev("%s: cx231xx_dif set to By pass"
						" mode- errCode [%d]!\n",
						__func__, status);
793 794 795 796
				return status;
			}

			/* Read the DFE_CTRL1 register */
797
			status = vid_blk_read_word(dev, DFE_CTRL1, &value);
798 799 800 801 802 803 804 805

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

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

			/* Write it back */
806
			status = vid_blk_write_word(dev, DFE_CTRL1, value);
807 808

			/* Disable auto config of registers */
809
			status = cx231xx_read_modify_write_i2c_dword(dev,
810
					VID_BLK_I2C_ADDRESS,
811 812
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));
813 814

			/* Set CVBS input mode */
815
			status = cx231xx_read_modify_write_i2c_dword(dev,
816
				VID_BLK_I2C_ADDRESS,
817
				MODE_CTRL, FLD_INPUT_MODE,
818 819
				cx231xx_set_field(FLD_INPUT_MODE,
						INPUT_MODE_CVBS_0));
820
		} else {
821
			/* Enable the DIF for the tuner */
822

823 824
			/* Reinitialize the DIF */
			status = cx231xx_dif_set_standard(dev, dev->norm);
825
			if (status < 0) {
826 827 828
				cx231xx_errdev("%s: cx231xx_dif set to By pass"
						" mode- errCode [%d]!\n",
						__func__, status);
829 830 831
				return status;
			}

832
			/* Make sure bypass is cleared */
833
			status = vid_blk_read_word(dev, DIF_MISC_CTRL, &value);
834 835 836 837 838

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

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

841
			/* Read the DFE_CTRL1 register */
842
			status = vid_blk_read_word(dev, DFE_CTRL1, &value);
843

844 845
			/* Disable the VBI_GATE_EN */
			value &= ~FLD_VBI_GATE_EN;
846

847 848 849
			/* Enable the auto-VGA enable, AGC, and
			   set the skip count to 2 */
			value |= FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000;
850 851

			/* Write it back */
852
			status = vid_blk_write_word(dev, DFE_CTRL1, value);
853

854
			/* Wait until AGC locks up */
855
			msleep(1);
856

857 858
			/* Disable the auto-VGA enable AGC */
			value &= ~(FLD_VGA_AUTO_EN);
859

860
			/* Write it back */
861
			status = vid_blk_write_word(dev, DFE_CTRL1, value);
862

863
			/* Enable Polaris B0 AGC output */
864
			status = vid_blk_read_word(dev, PIN_CTRL, &value);
865 866 867
			value |= (FLD_OEF_AGC_RF) |
				 (FLD_OEF_AGC_IFVGA) |
				 (FLD_OEF_AGC_IF);
868
			status = vid_blk_write_word(dev, PIN_CTRL, value);
869

870
			/* Set output mode */
871
			status = cx231xx_read_modify_write_i2c_dword(dev,
872
						VID_BLK_I2C_ADDRESS,
873
						OUT_CTRL1, FLD_OUT_MODE,
874
						dev->board.output_mode);
875 876 877

			/* Disable auto config of registers */
			status = cx231xx_read_modify_write_i2c_dword(dev,
878
					VID_BLK_I2C_ADDRESS,
879 880 881 882 883
					MODE_CTRL, FLD_ACFG_DIS,
					cx231xx_set_field(FLD_ACFG_DIS, 1));

			/* Set CVBS input mode */
			status = cx231xx_read_modify_write_i2c_dword(dev,
884
				VID_BLK_I2C_ADDRESS,
885
				MODE_CTRL, FLD_INPUT_MODE,
886 887
				cx231xx_set_field(FLD_INPUT_MODE,
						INPUT_MODE_CVBS_0));
888

889 890
			/* Set some bits in AFE_CTRL so that channel 2 or 3
			 * is ready to receive audio */
891 892 893
			/* 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) */
894
			status = vid_blk_read_word(dev, AFE_CTRL, &value);
895

896 897 898 899
			/*Set Func mode:01-DIF 10-baseband 11-YUV*/
			value &= (~(FLD_FUNC_MODE));
			value |= 0x800000;

900 901
			value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;

902
			status = vid_blk_write_word(dev, AFE_CTRL, value);
903 904 905 906 907 908 909 910

			if (dev->tuner_type == TUNER_NXP_TDA18271) {
				status = vid_blk_read_word(dev, PIN_CTRL,
				 &value);
				status = vid_blk_write_word(dev, PIN_CTRL,
				 (value & 0xFFFFFFEF));
			}

911
			break;
912 913 914 915 916 917

		}
		break;
	}

	/* Set raw VBI mode */
918
	status = cx231xx_read_modify_write_i2c_dword(dev,
919
				VID_BLK_I2C_ADDRESS,
920 921
				OUT_CTRL1, FLD_VBIHACTRAW_EN,
				cx231xx_set_field(FLD_VBIHACTRAW_EN, 1));
922

923
	status = vid_blk_read_word(dev, OUT_CTRL1, &value);
924 925
	if (value & 0x02) {
		value |= (1 << 19);
926
		status = vid_blk_write_word(dev, OUT_CTRL1, value);
927 928 929
	}

	return status;
930 931
}

932 933 934 935
void cx231xx_enable656(struct cx231xx *dev)
{
	u8 temp = 0;
	int status;
936
	/*enable TS1 data[0:7] as output to export 656*/
937 938 939

	status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0xFF);

940
	/*enable TS1 clock as output to export 656*/
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964

	status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
	temp = temp|0x04;

	status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);

}
EXPORT_SYMBOL_GPL(cx231xx_enable656);

void cx231xx_disable656(struct cx231xx *dev)
{
	u8 temp = 0;
	int status;


	status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0x00);

	status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
	temp = temp&0xFB;

	status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
}
EXPORT_SYMBOL_GPL(cx231xx_disable656);

965
/*
966 967 968
 * 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
969 970 971
 */
int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
{
972 973 974 975 976 977
	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 */
978
	status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280);
979

980
	if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
981 982
		cx231xx_info("do_mode_ctrl_overrides NTSC\n");

983 984 985
		/* Move the close caption lines out of active video,
		   adjust the active video start point */
		status = cx231xx_read_modify_write_i2c_dword(dev,
986
							VID_BLK_I2C_ADDRESS,
987 988
							VERT_TIM_CTRL,
							FLD_VBLANK_CNT, 0x18);
989
		status = cx231xx_read_modify_write_i2c_dword(dev,
990
							VID_BLK_I2C_ADDRESS,
991 992
							VERT_TIM_CTRL,
							FLD_VACTIVE_CNT,
993
							0x1E7000);
994
		status = cx231xx_read_modify_write_i2c_dword(dev,
995
							VID_BLK_I2C_ADDRESS,
996 997
							VERT_TIM_CTRL,
							FLD_V656BLANK_CNT,
998
							0x1C000000);
999

1000
		status = cx231xx_read_modify_write_i2c_dword(dev,
1001
							VID_BLK_I2C_ADDRESS,
1002 1003 1004 1005
							HORIZ_TIM_CTRL,
							FLD_HBLANK_CNT,
							cx231xx_set_field
							(FLD_HBLANK_CNT, 0x79));
1006

1007 1008 1009
	} else if (dev->norm & V4L2_STD_SECAM) {
		cx231xx_info("do_mode_ctrl_overrides SECAM\n");
		status =  cx231xx_read_modify_write_i2c_dword(dev,
1010
							VID_BLK_I2C_ADDRESS,
1011
							VERT_TIM_CTRL,
1012
							FLD_VBLANK_CNT, 0x20);
1013 1014 1015 1016 1017 1018
		status = cx231xx_read_modify_write_i2c_dword(dev,
							VID_BLK_I2C_ADDRESS,
							VERT_TIM_CTRL,
							FLD_VACTIVE_CNT,
							cx231xx_set_field
							(FLD_VACTIVE_CNT,
1019
							 0x244));
1020 1021 1022 1023 1024 1025
		status = cx231xx_read_modify_write_i2c_dword(dev,
							VID_BLK_I2C_ADDRESS,
							VERT_TIM_CTRL,
							FLD_V656BLANK_CNT,
							cx231xx_set_field
							(FLD_V656BLANK_CNT,
1026
							0x24));
1027
		/* Adjust the active video horizontal start point */
1028
		status = cx231xx_read_modify_write_i2c_dword(dev,
1029
							VID_BLK_I2C_ADDRESS,
1030 1031 1032 1033
							HORIZ_TIM_CTRL,
							FLD_HBLANK_CNT,
							cx231xx_set_field
							(FLD_HBLANK_CNT, 0x85));
1034 1035 1036
	} else {
		cx231xx_info("do_mode_ctrl_overrides PAL\n");
		status = cx231xx_read_modify_write_i2c_dword(dev,
1037
							VID_BLK_I2C_ADDRESS,
1038
							VERT_TIM_CTRL,
1039
							FLD_VBLANK_CNT, 0x20);
1040 1041 1042 1043 1044 1045
		status = cx231xx_read_modify_write_i2c_dword(dev,
							VID_BLK_I2C_ADDRESS,
							VERT_TIM_CTRL,
							FLD_VACTIVE_CNT,
							cx231xx_set_field
							(FLD_VACTIVE_CNT,
1046
							 0x244));
1047 1048 1049 1050 1051 1052
		status = cx231xx_read_modify_write_i2c_dword(dev,
							VID_BLK_I2C_ADDRESS,
							VERT_TIM_CTRL,
							FLD_V656BLANK_CNT,
							cx231xx_set_field
							(FLD_V656BLANK_CNT,
1053
							0x24));
1054
		/* Adjust the active video horizontal start point */
1055
		status = cx231xx_read_modify_write_i2c_dword(dev,
1056
							VID_BLK_I2C_ADDRESS,
1057 1058 1059 1060
							HORIZ_TIM_CTRL,
							FLD_HBLANK_CNT,
							cx231xx_set_field
							(FLD_HBLANK_CNT, 0x85));
1061

1062 1063 1064
	}

	return status;
1065 1066
}

1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
int cx231xx_unmute_audio(struct cx231xx *dev)
{
	return vid_blk_write_byte(dev, PATH1_VOL_CTL, 0x24);
}
EXPORT_SYMBOL_GPL(cx231xx_unmute_audio);

int stopAudioFirmware(struct cx231xx *dev)
{
	return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x03);
}

int restartAudioFirmware(struct cx231xx *dev)
{
	return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x13);
}

1083 1084
int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
{
1085 1086 1087 1088 1089 1090 1091 1092
	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:
1093
		status = cx231xx_i2s_blk_set_audio_input(dev, input);
1094 1095 1096 1097 1098 1099 1100 1101 1102
		ainput = AUDIO_INPUT_LINE;
		break;
	default:
		break;
	}

	status = cx231xx_set_audio_decoder_input(dev, ainput);

	return status;
1103 1104
}

1105 1106
int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
				    enum AUDIO_INPUT audio_input)
1107
{
1108 1109
	u32 dwval;
	int status;
1110
	u8 gen_ctrl;
1111 1112 1113
	u32 value = 0;

	/* Put it in soft reset   */
1114
	status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
1115
	gen_ctrl |= 1;
1116
	status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
1117 1118 1119 1120

	switch (audio_input) {
	case AUDIO_INPUT_LINE:
		/* setup AUD_IO control from Merlin paralle output */
1121 1122
		value = cx231xx_set_field(FLD_AUD_CHAN1_SRC,
					  AUD_CHAN_SRC_PARALLEL);
1123
		status = vid_blk_write_word(dev, AUD_IO_CTRL, value);
1124 1125 1126 1127

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

1130 1131
		status = vid_blk_write_word(dev, AC97_CTL,
					   (dwval | FLD_AC97_UP2X_BYPASS));
1132 1133

		/* select the parallel1 and SRC3 */
1134
		status = vid_blk_write_word(dev, BAND_OUT_SEL,
1135 1136
				cx231xx_set_field(FLD_SRC3_IN_SEL, 0x0) |
				cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x0) |
1137
				cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x0));
1138 1139 1140

		/* unmute all, AC97 in, independence mode
		   adr 08d0, data 0x00063073 */
1141
		status = vid_blk_write_word(dev, DL_CTL, 0x3000001);
1142
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073);
1143 1144

		/* set AVC maximum threshold, adr 08d4, dat ffff0024 */
1145 1146 1147
		status = vid_blk_read_word(dev, PATH1_VOL_CTL, &dwval);
		status = vid_blk_write_word(dev, PATH1_VOL_CTL,
					   (dwval | FLD_PATH1_AVC_THRESHOLD));
1148 1149

		/* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
1150 1151 1152
		status = vid_blk_read_word(dev, PATH1_SC_CTL, &dwval);
		status = vid_blk_write_word(dev, PATH1_SC_CTL,
					   (dwval | FLD_PATH1_SC_THRESHOLD));
1153 1154 1155 1156
		break;

	case AUDIO_INPUT_TUNER_TV:
	default:
1157
		status = stopAudioFirmware(dev);
1158
		/* Setup SRC sources and clocks */
1159
		status = vid_blk_write_word(dev, BAND_OUT_SEL,
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
			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)   |
1172
			cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x01));
1173 1174

		/* Setup the AUD_IO control */
1175
		status = vid_blk_write_word(dev, AUD_IO_CTRL,
1176 1177 1178 1179
			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) |
1180
			cx231xx_set_field(FLD_AUD_CHAN1_SRC, 0x03));
1181

1182
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870);
1183 1184

		/* setAudioStandard(_audio_standard); */
1185
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870);
1186 1187 1188

		status = restartAudioFirmware(dev);

1189 1190 1191
		switch (dev->board.tuner_type) {
		case TUNER_XC5000:
			/* SIF passthrough at 28.6363 MHz sample rate */
1192
			status = cx231xx_read_modify_write_i2c_dword(dev,
1193
					VID_BLK_I2C_ADDRESS,
1194 1195 1196
					CHIP_CTRL,
					FLD_SIF_EN,
					cx231xx_set_field(FLD_SIF_EN, 1));
1197
			break;
1198 1199
		case TUNER_NXP_TDA18271:
			/* Normal mode: SIF passthrough at 14.32 MHz */
1200 1201 1202 1203 1204 1205
			status = cx231xx_read_modify_write_i2c_dword(dev,
					VID_BLK_I2C_ADDRESS,
					CHIP_CTRL,
					FLD_SIF_EN,
					cx231xx_set_field(FLD_SIF_EN, 0));
			break;
1206
		default:
1207 1208 1209 1210
			/* This is just a casual suggestion to people adding
			   new boards in case they use a tuner type we don't
			   currently know about */
			printk(KERN_INFO "Unknown tuner type configuring SIF");
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222
			break;
		}
		break;

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

	case AUDIO_INPUT_MUTE:
1223
		status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F011012);
1224 1225
		break;
	}
1226

1227
	/* Take it out of soft reset */
1228
	status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
1229
	gen_ctrl &= ~1;
1230
	status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
1231

1232 1233
	return status;
}
1234

1235 1236 1237
/******************************************************************************
 *                    C H I P Specific  C O N T R O L   functions             *
 ******************************************************************************/
1238 1239
int cx231xx_init_ctrl_pin_status(struct cx231xx *dev)
{
1240 1241
	u32 value;
	int status = 0;
1242

1243
	status = vid_blk_read_word(dev, PIN_CTRL, &value);
1244
	value |= (~dev->board.ctl_pin_status_mask);
1245
	status = vid_blk_write_word(dev, PIN_CTRL, value);
1246

1247
	return status;
1248 1249
}

1250 1251
int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
					      u8 analog_or_digital)
1252
{
1253
	int status = 0;
1254

1255
	/* first set the direction to output */
1256 1257 1258
	status = cx231xx_set_gpio_direction(dev,
					    dev->board.
					    agc_analog_digital_select_gpio, 1);
1259

1260
	/* 0 - demod ; 1 - Analog mode */
1261
	status = cx231xx_set_gpio_value(dev,
1262 1263
				   dev->board.agc_analog_digital_select_gpio,
				   analog_or_digital);
1264

1265
	return status;
1266 1267
}

1268
int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
1269
{
1270 1271
	u8 value[4] = { 0, 0, 0, 0 };
	int status = 0;
1272
	bool current_is_port_3;
1273

1274 1275
	if (dev->board.dont_use_port_3)
		is_port_3 = false;
1276 1277
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
				       PWR_CTL_EN, value, 4);
1278 1279
	if (status < 0)
		return status;
1280

1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
	current_is_port_3 = value[0] & I2C_DEMOD_EN ? true : false;

	/* Just return, if already using the right port */
	if (current_is_port_3 == is_port_3)
		return 0;

	if (is_port_3)
		value[0] |= I2C_DEMOD_EN;
	else
		value[0] &= ~I2C_DEMOD_EN;

	cx231xx_info("Changing the i2c master port to %d\n",
		     is_port_3 ?  3 : 1);

	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
					PWR_CTL_EN, value, 4);
1297

1298
	return status;
1299

1300
}
1301 1302
EXPORT_SYMBOL_GPL(cx231xx_enable_i2c_port_3);

1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
void update_HH_register_after_set_DIF(struct cx231xx *dev)
{
/*
	u8 status = 0;
	u32 value = 0;

	vid_blk_write_word(dev, PIN_CTRL, 0xA0FFF82F);
	vid_blk_write_word(dev, DIF_MISC_CTRL, 0x0A203F11);
	vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0x1BEFBF06);

	status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
	vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
	status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL,  &value);
*/
}

void cx231xx_dump_HH_reg(struct cx231xx *dev)
{
	u8 status = 0;
	u32 value = 0;
	u16  i = 0;

	value = 0x45005390;
	status = vid_blk_write_word(dev, 0x104, value);

	for (i = 0x100; i < 0x140; i++) {
		status = vid_blk_read_word(dev, i, &value);
		cx231xx_info("reg0x%x=0x%x\n", i, value);
		i = i+3;
	}

	for (i = 0x300; i < 0x400; i++) {
		status = vid_blk_read_word(dev, i, &value);
		cx231xx_info("reg0x%x=0x%x\n", i, value);
		i = i+3;
	}

	for (i = 0x400; i < 0x440; i++) {
		status = vid_blk_read_word(dev, i,  &value);
		cx231xx_info("reg0x%x=0x%x\n", i, value);
		i = i+3;
	}

1346 1347 1348 1349 1350
	status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
	cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
	vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
	status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
	cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
1351
}
1352

1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
void cx231xx_dump_SC_reg(struct cx231xx *dev)
{
	u8 value[4] = { 0, 0, 0, 0 };
	int status = 0;
	cx231xx_info("cx231xx_dump_SC_reg %s!\n", __TIME__);

	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0],
				 value[1], value[2], value[3]);

	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0],
				 value[1], value[2], value[3]);

	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0],
				 value[1], value[2], value[3]);

	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0],
				 value[1], value[2], value[3]);

	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0],
				 value[1], value[2], value[3]);
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
				 value, 4);
	cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0],
				 value[1], value[2], value[3]);


}

void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev)

{
	u8 status = 0;
	u8 value = 0;



	status = afe_read_byte(dev, ADC_STATUS2_CH3, &value);
	value = (value & 0xFE)|0x01;
	status = afe_write_byte(dev, ADC_STATUS2_CH3, value);

	status = afe_read_byte(dev, ADC_STATUS2_CH3, &value);
	value = (value & 0xFE)|0x00;
	status = afe_write_byte(dev, ADC_STATUS2_CH3, value);


/*
1457
	config colibri to lo-if mode
1458

1459 1460
	FIXME: ntf_mode = 2'b00 by default. But set 0x1 would reduce
		the diff IF input by half,
1461

1462
		for low-if agc defect
1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500
*/

	status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value);
	value = (value & 0xFC)|0x00;
	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, value);

	status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
	value = (value & 0xF9)|0x02;
	status = afe_write_byte(dev, ADC_INPUT_CH3, value);

	status = afe_read_byte(dev, ADC_FB_FRCRST_CH3, &value);
	value = (value & 0xFB)|0x04;
	status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, value);

	status = afe_read_byte(dev, ADC_DCSERVO_DEM_CH3, &value);
	value = (value & 0xFC)|0x03;
	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, value);

	status = afe_read_byte(dev, ADC_CTRL_DAC1_CH3, &value);
	value = (value & 0xFB)|0x04;
	status = afe_write_byte(dev, ADC_CTRL_DAC1_CH3, value);

	status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
	value = (value & 0xF8)|0x06;
	status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);

	status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
	value = (value & 0x8F)|0x40;
	status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);

	status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH3, &value);
	value = (value & 0xDF)|0x20;
	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, value);
}

void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq,
		 u8 spectral_invert, u32 mode)
{
1501 1502 1503 1504
	u32 colibri_carrier_offset = 0;
	u8 status = 0;
	u32 func_mode = 0x01; /* Device has a DIF if this function is called */
	u32 standard = 0;
1505 1506 1507
	u8 value[4] = { 0, 0, 0, 0 };

	cx231xx_info("Enter cx231xx_set_Colibri_For_LowIF()\n");
1508 1509 1510 1511 1512 1513
	value[0] = (u8) 0x6F;
	value[1] = (u8) 0x6F;
	value[2] = (u8) 0x6F;
	value[3] = (u8) 0x6F;
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
					PWR_CTL_EN, value, 4);
1514 1515 1516 1517 1518 1519 1520

	/*Set colibri for low IF*/
	status = cx231xx_afe_set_mode(dev, AFE_MODE_LOW_IF);

	/* Set C2HH for low IF operation.*/
	standard = dev->norm;
	status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
1521
						       func_mode, standard);
1522 1523 1524

	/* Get colibri offsets.*/
	colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode,
1525
								   standard);
1526 1527

	cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n",
1528
		     colibri_carrier_offset, standard);
1529 1530

	/* Set the band Pass filter for DIF*/
1531 1532
	cx231xx_set_DIF_bandpass(dev, (if_freq+colibri_carrier_offset),
				 spectral_invert, mode);
1533 1534 1535 1536
}

u32 cx231xx_Get_Colibri_CarrierOffset(u32 mode, u32 standerd)
{
1537
	u32 colibri_carrier_offset = 0;
1538

1539
	if (mode == TUNER_MODE_FM_RADIO) {
1540
		colibri_carrier_offset = 1100000;
1541
	} else if (standerd & (V4L2_STD_MN | V4L2_STD_NTSC_M_JP)) {
1542 1543 1544 1545 1546 1547 1548 1549
		colibri_carrier_offset = 4832000;  /*4.83MHz	*/
	} else if (standerd & (V4L2_STD_PAL_B | V4L2_STD_PAL_G)) {
		colibri_carrier_offset = 2700000;  /*2.70MHz       */
	} else if (standerd & (V4L2_STD_PAL_D | V4L2_STD_PAL_I
			| V4L2_STD_SECAM)) {
		colibri_carrier_offset = 2100000;  /*2.10MHz	*/
	}

1550
	return colibri_carrier_offset;
1551 1552 1553 1554 1555
}

void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
		 u8 spectral_invert, u32 mode)
{
1556 1557 1558 1559 1560
	unsigned long pll_freq_word;
	int status = 0;
	u32 dif_misc_ctrl_value = 0;
	u64 pll_freq_u64 = 0;
	u32 i = 0;
1561 1562 1563 1564 1565

	cx231xx_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n",
			 if_freq, spectral_invert, mode);


1566 1567 1568
	if (mode == TUNER_MODE_FM_RADIO) {
		pll_freq_word = 0x905A1CAC;
		status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD,  pll_freq_word);
1569

1570 1571 1572 1573 1574 1575 1576 1577
	} else /*KSPROPERTY_TUNER_MODE_TV*/{
		/* Calculate the PLL frequency word based on the adjusted if_freq*/
		pll_freq_word = if_freq;
		pll_freq_u64 = (u64)pll_freq_word << 28L;
		do_div(pll_freq_u64, 50000000);
		pll_freq_word = (u32)pll_freq_u64;
		/*pll_freq_word = 0x3463497;*/
		status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD,  pll_freq_word);
1578

1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597
	if (spectral_invert) {
		if_freq -= 400000;
		/* Enable Spectral Invert*/
		status = vid_blk_read_word(dev, DIF_MISC_CTRL,
					&dif_misc_ctrl_value);
		dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000;
		status = vid_blk_write_word(dev, DIF_MISC_CTRL,
					dif_misc_ctrl_value);
	} else {
		if_freq += 400000;
		/* Disable Spectral Invert*/
		status = vid_blk_read_word(dev, DIF_MISC_CTRL,
					&dif_misc_ctrl_value);
		dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF;
		status = vid_blk_write_word(dev, DIF_MISC_CTRL,
					dif_misc_ctrl_value);
	}

	if_freq = (if_freq/100000)*100000;
1598

1599 1600
	if (if_freq < 3000000)
		if_freq = 3000000;
1601

1602 1603
	if (if_freq > 16000000)
		if_freq = 16000000;
1604 1605
	}

1606 1607 1608 1609 1610 1611 1612 1613
	cx231xx_info("Enter IF=%zd\n",
			sizeof(Dif_set_array)/sizeof(struct dif_settings));
	for (i = 0; i < sizeof(Dif_set_array)/sizeof(struct dif_settings); i++) {
		if (Dif_set_array[i].if_freq == if_freq) {
			status = vid_blk_write_word(dev,
			Dif_set_array[i].register_address, Dif_set_array[i].value);
		}
	}
1614 1615
}

1616 1617 1618
/******************************************************************************
 *                 D I F - B L O C K    C O N T R O L   functions             *
 ******************************************************************************/
1619
int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
1620
					  u32 function_mode, u32 standard)
1621
{
1622 1623
	int status = 0;

1624

1625 1626
	if (mode == V4L2_TUNER_RADIO) {
		/* C2HH */
1627 1628
		/* lo if big signal */
		status = cx231xx_reg_mask_write(dev,
1629
				VID_BLK_I2C_ADDRESS, 32,
1630 1631 1632
				AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
		/* FUNC_MODE = DIF */
		status = cx231xx_reg_mask_write(dev,
1633
				VID_BLK_I2C_ADDRESS, 32,
1634 1635 1636
				AFE_CTRL_C2HH_SRC_CTRL, 23, 24, function_mode);
		/* IF_MODE */
		status = cx231xx_reg_mask_write(dev,
1637
				VID_BLK_I2C_ADDRESS, 32,
1638 1639 1640
				AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF);
		/* no inv */
		status = cx231xx_reg_mask_write(dev,
1641
				VID_BLK_I2C_ADDRESS, 32,
1642
				AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
1643 1644
	} else if (standard != DIF_USE_BASEBAND) {
		if (standard & V4L2_STD_MN) {
1645
			/* lo if big signal */
1646
			status = cx231xx_reg_mask_write(dev,
1647
					VID_BLK_I2C_ADDRESS, 32,
1648 1649
					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
			/* FUNC_MODE = DIF */
1650
			status = cx231xx_reg_mask_write(dev,
1651
					VID_BLK_I2C_ADDRESS, 32,
1652
					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1653 1654
					function_mode);
			/* IF_MODE */
1655
			status = cx231xx_reg_mask_write(dev,
1656
					VID_BLK_I2C_ADDRESS, 32,
1657 1658
					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb);
			/* no inv */
1659
			status = cx231xx_reg_mask_write(dev,
1660
					VID_BLK_I2C_ADDRESS, 32,
1661 1662
					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
			/* 0x124, AUD_CHAN1_SRC = 0x3 */
1663
			status = cx231xx_reg_mask_write(dev,
1664
					VID_BLK_I2C_ADDRESS, 32,
1665
					AUD_IO_CTRL, 0, 31, 0x00000003);
1666
		} else if ((standard == V4L2_STD_PAL_I) |
1667
			(standard & V4L2_STD_PAL_D) |
1668
			(standard & V4L2_STD_SECAM)) {
1669
			/* C2HH setup */
1670
			/* lo if big signal */
1671
			status = cx231xx_reg_mask_write(dev,
1672
					VID_BLK_I2C_ADDRESS, 32,
1673 1674
					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
			/* FUNC_MODE = DIF */
1675
			status = cx231xx_reg_mask_write(dev,
1676
					VID_BLK_I2C_ADDRESS, 32,
1677
					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1678 1679
					function_mode);
			/* IF_MODE */
1680
			status = cx231xx_reg_mask_write(dev,
1681
					VID_BLK_I2C_ADDRESS, 32,
1682
					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF);
1683
			/* no inv */
1684
			status = cx231xx_reg_mask_write(dev,
1685
					VID_BLK_I2C_ADDRESS, 32,
1686
					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
1687 1688
		} else {
			/* default PAL BG */
1689
			/* C2HH setup */
1690
			/* lo if big signal */
1691
			status = cx231xx_reg_mask_write(dev,
1692
					VID_BLK_I2C_ADDRESS, 32,
1693 1694
					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
			/* FUNC_MODE = DIF */
1695
			status = cx231xx_reg_mask_write(dev,
1696
					VID_BLK_I2C_ADDRESS, 32,
1697
					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
1698 1699
					function_mode);
			/* IF_MODE */
1700
			status = cx231xx_reg_mask_write(dev,
1701
					VID_BLK_I2C_ADDRESS, 32,
1702
					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE);
1703
			/* no inv */
1704
			status = cx231xx_reg_mask_write(dev,
1705
					VID_BLK_I2C_ADDRESS, 32,
1706
					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
1707 1708 1709 1710
		}
	}

	return status;
1711 1712 1713 1714
}

int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
{
1715 1716 1717 1718 1719 1720
	int status = 0;
	u32 dif_misc_ctrl_value = 0;
	u32 func_mode = 0;

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

1721
	status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value);
1722 1723 1724 1725
	if (standard != DIF_USE_BASEBAND)
		dev->norm = standard;

	switch (dev->model) {
1726
	case CX231XX_BOARD_CNXT_CARRAERA:
1727
	case CX231XX_BOARD_CNXT_RDE_250:
1728
	case CX231XX_BOARD_CNXT_SHELBY:
1729
	case CX231XX_BOARD_CNXT_RDU_250:
1730
	case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
1731
	case CX231XX_BOARD_HAUPPAUGE_EXETER:
1732 1733
		func_mode = 0x03;
		break;
1734 1735 1736 1737
	case CX231XX_BOARD_CNXT_RDE_253S:
	case CX231XX_BOARD_CNXT_RDU_253S:
		func_mode = 0x01;
		break;
1738 1739 1740 1741
	default:
		func_mode = 0x01;
	}

1742
	status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
1743 1744 1745
						  func_mode, standard);

	if (standard == DIF_USE_BASEBAND) {	/* base band */
1746 1747
		/* There is a different SRC_PHASE_INC value
		   for baseband vs. DIF */
1748 1749 1750
		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0xDF7DF83);
		status = vid_blk_read_word(dev, DIF_MISC_CTRL,
						&dif_misc_ctrl_value);
1751
		dif_misc_ctrl_value |= FLD_DIF_DIF_BYPASS;
1752 1753
		status = vid_blk_write_word(dev, DIF_MISC_CTRL,
						dif_misc_ctrl_value);
1754
	} else if (standard & V4L2_STD_PAL_D) {
1755
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1756
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1757
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1758
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1759
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1760
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1761
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1762
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1763
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1764
					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1765
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1766
					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1767
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1768
					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1769
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1770
					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1771
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1772 1773
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1774
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1775 1776
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1777
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1778 1779
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0x72500800);
1780
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1781 1782
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1783
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1784
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3934EA);
1785
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1786 1787
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1788
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1789 1790
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1791
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1792 1793
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1794
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1795 1796 1797 1798 1799
					   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) {
1800
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1801
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1802
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1803
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1804
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1805
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1806
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1807
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1808
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1809
					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
1810
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1811
					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
1812
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1813
					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
1814
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1815
					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
1816
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1817 1818
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1819
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1820 1821
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1822
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1823 1824
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0x72500800);
1825
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1826 1827
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1828
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1829
					   DIF_AV_SEP_CTRL, 0, 31, 0x5F39A934);
1830
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1831 1832
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1833
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1834 1835
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1836
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1837 1838
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1839
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1840 1841 1842 1843 1844 1845
					   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 */
1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867
		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);
1868 1869 1870 1871 1872
		/* 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 */
1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895
		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);
1896 1897 1898 1899
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value = 0x3A093F10;
	} else if (standard &
1900 1901
		  (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
		   V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)) {
1902

1903
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1904
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1905
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1906
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1907
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1908
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1909
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1910
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1911
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1912
					   DIF_AGC_IF_REF, 0, 31, 0x888C0380);
1913
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1914
					   DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
1915
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1916
					   DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
1917
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1918
					   DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
1919
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1920 1921
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1922
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1923 1924
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1925
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1926 1927
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1928
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1929
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
1930
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1931 1932
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1933
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1934 1935
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1936
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1937 1938
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1939
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1940
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1941
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1942 1943 1944 1945 1946 1947 1948 1949
					   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? */
1950
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1951
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
1952
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1953
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
1954
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1955
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
1956
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1957
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
1958
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1959
					   DIF_AGC_IF_REF, 0, 31, 0x888C0380);
1960
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1961
					   DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
1962
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1963
					   DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
1964
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1965
					   DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
1966
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1967 1968
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
1969
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1970 1971
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
1972
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1973 1974
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
1975
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1976
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
1977
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1978 1979
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00000000);
1980
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1981 1982
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
1983
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1984 1985
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
1986
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1987
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
1988
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
1989 1990 1991 1992 1993 1994 1995
					   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;

1996
	} else if (standard & V4L2_STD_NTSC_M) {
1997 1998
		/* V4L2_STD_NTSC_M (75 IRE Setup) Or
		   V4L2_STD_NTSC_M_JP (Japan,  0 IRE Setup) */
1999

2000 2001 2002 2003
		/* 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
2004 2005
		 */

2006 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
		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);
2032 2033 2034 2035

		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a003F10;
2036 2037
	} else {
		/* default PAL BG */
2038
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2039
					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
2040
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2041
					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
2042
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2043
					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
2044
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2045
					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
2046
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2047
					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
2048
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2049
					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
2050
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2051
					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
2052
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2053
					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
2054
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2055 2056
					   DIF_AGC_IF_INT_CURRENT, 0, 31,
					   0x26001700);
2057
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2058 2059
					   DIF_AGC_RF_CURRENT, 0, 31,
					   0x00002660);
2060
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2061 2062
					   DIF_VIDEO_AGC_CTRL, 0, 31,
					   0x72500800);
2063
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2064 2065
					   DIF_VID_AUD_OVERRIDE, 0, 31,
					   0x27000100);
2066
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2067
					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530EC);
2068
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2069 2070
					   DIF_COMP_FLT_CTRL, 0, 31,
					   0x00A653A8);
2071
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2072 2073
					   DIF_SRC_PHASE_INC, 0, 31,
					   0x1befbf06);
2074
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2075 2076
					   DIF_SRC_GAIN_CONTROL, 0, 31,
					   0x000035e8);
2077
		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
2078 2079 2080 2081
					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
		/* Save the Spec Inversion value */
		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
		dif_misc_ctrl_value |= 0x3a013F11;
2082 2083 2084 2085 2086 2087
	}

	/* 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;

2088 2089
	/* It is still possible to get Set Standard calls even when we
	   are in FM mode.
2090 2091 2092 2093 2094
	   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      */
2095
	status = vid_blk_write_word(dev, DIF_MISC_CTRL, dif_misc_ctrl_value);
2096 2097

	return status;
2098 2099 2100 2101 2102 2103 2104 2105
}

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

	/* Set the RF and IF k_agc values to 3 */
2106
	status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
2107 2108 2109
	dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
	dwval |= 0x33000000;

2110
	status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
2111

2112
	return status;
2113 2114 2115 2116
}

int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
{
2117
	int status = 0;
2118
	u32 dwval;
2119 2120
	cx231xx_info("cx231xx_tuner_post_channel_change  dev->tuner_type =0%d\n",
		     dev->tuner_type);
2121 2122
	/* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
	 * SECAM L/B/D standards */
2123
	status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
2124
	dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
2125

2126
	if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
			 V4L2_STD_SECAM_D)) {
			if (dev->tuner_type == TUNER_NXP_TDA18271) {
				dwval &= ~FLD_DIF_IF_REF;
				dwval |= 0x88000300;
			} else
				dwval |= 0x88000000;
		} else {
			if (dev->tuner_type == TUNER_NXP_TDA18271) {
				dwval &= ~FLD_DIF_IF_REF;
				dwval |= 0xCC000300;
			} else
				dwval |= 0x44000000;
		}
2140

2141
	status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
2142

2143
	return status;
2144 2145
}

2146
/******************************************************************************
2147
 *        	    I 2 S - B L O C K    C O N T R O L   functions            *
2148
 ******************************************************************************/
2149
int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
2150
{
2151 2152 2153
	int status = 0;
	u32 value;

2154
	status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2155
				       CH_PWR_CTRL1, 1, &value, 1);
2156 2157
	/* enables clock to delta-sigma and decimation filter */
	value |= 0x80;
2158
	status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2159 2160
					CH_PWR_CTRL1, 1, value, 1);
	/* power up all channel */
2161
	status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2162 2163 2164
					CH_PWR_CTRL2, 1, 0x00, 1);

	return status;
2165 2166
}

2167
int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
2168
					enum AV_MODE avmode)
2169
{
2170 2171 2172 2173
	int status = 0;
	u32 value = 0;

	if (avmode != POLARIS_AVMODE_ENXTERNAL_AV) {
2174
		status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2175 2176
					  CH_PWR_CTRL2, 1, &value, 1);
		value |= 0xfe;
2177
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2178 2179
						CH_PWR_CTRL2, 1, value, 1);
	} else {
2180
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2181 2182 2183 2184
						CH_PWR_CTRL2, 1, 0x00, 1);
	}

	return status;
2185 2186
}

2187 2188
/* set i2s_blk for audio input types */
int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input)
2189
{
2190
	int status = 0;
2191

2192 2193
	switch (audio_input) {
	case CX231XX_AMUX_LINE_IN:
2194
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2195
						CH_PWR_CTRL2, 1, 0x00, 1);
2196
		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
2197 2198 2199 2200 2201 2202
						CH_PWR_CTRL1, 1, 0x80, 1);
		break;
	case CX231XX_AMUX_VIDEO:
	default:
		break;
	}
2203

2204
	dev->ctl_ainput = audio_input;
2205

2206
	return status;
2207 2208
}

2209 2210 2211
/******************************************************************************
 *                  P O W E R      C O N T R O L   functions                  *
 ******************************************************************************/
2212
int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
2213
{
2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225
	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;
	}

2226 2227
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
				       4);
2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
	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);
2243 2244
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
		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);
2262 2263
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
2264

2265 2266
		/* reset state of xceive tuner */
		dev->xc_fw_load_done = 0;
2267 2268 2269 2270
		break;

	case POLARIS_AVMODE_ANALOGT_TV:

2271
		tmp |= PWR_DEMOD_EN;
2272 2273 2274 2275 2276
		tmp |= (I2C_DEMOD_EN);
		value[0] = (u8) tmp;
		value[1] = (u8) (tmp >> 8);
		value[2] = (u8) (tmp >> 16);
		value[3] = (u8) (tmp >> 24);
2277 2278
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
2279 2280 2281 2282 2283 2284 2285 2286
		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);
2287 2288
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2289 2290 2291 2292 2293 2294 2295 2296 2297
			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);
2298 2299
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2300 2301 2302 2303 2304 2305 2306 2307
			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);
2308 2309
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2310 2311 2312 2313 2314 2315 2316 2317 2318
			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);
2319 2320
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2321 2322 2323
			msleep(PWR_SLEEP_INTERVAL);
		}

2324 2325 2326
		if (dev->board.tuner_type != TUNER_ABSENT) {
			/* Enable tuner */
			cx231xx_enable_i2c_port_3(dev, true);
2327

2328
			/* reset the Tuner */
2329 2330
			if (dev->board.tuner_gpio)
				cx231xx_gpio_set(dev, dev->board.tuner_gpio);
2331

2332 2333 2334
			if (dev->cx231xx_reset_analog_tuner)
				dev->cx231xx_reset_analog_tuner(dev);
		}
2335

2336 2337 2338 2339 2340 2341 2342 2343 2344
		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);
2345 2346
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2347 2348 2349 2350 2351 2352 2353 2354
			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);
2355 2356
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2357 2358 2359 2360 2361 2362 2363 2364
			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);
2365 2366
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2367 2368 2369
			msleep(PWR_SLEEP_INTERVAL);
		}

2370
		tmp &= (~PWR_AV_MODE);
2371 2372 2373 2374 2375
		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);
2376 2377
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
2378 2379 2380 2381 2382 2383 2384 2385
		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);
2386 2387
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
							PWR_CTL_EN, value, 4);
2388 2389 2390
			msleep(PWR_SLEEP_INTERVAL);
		}

2391 2392 2393 2394 2395 2396 2397 2398 2399
		if (dev->board.tuner_type != TUNER_ABSENT) {
			/*
			 * Enable tuner
			 *	Hauppauge Exeter seems to need to do something different!
			 */
			if (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER)
				cx231xx_enable_i2c_port_3(dev, false);
			else
				cx231xx_enable_i2c_port_3(dev, true);
2400

2401
			/* reset the Tuner */
2402 2403
			if (dev->board.tuner_gpio)
				cx231xx_gpio_set(dev, dev->board.tuner_gpio);
2404

2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415
			if (dev->cx231xx_reset_analog_tuner)
				dev->cx231xx_reset_analog_tuner(dev);
		}
		break;

	default:
		break;
	}

	msleep(PWR_SLEEP_INTERVAL);

2416 2417
	/* For power saving, only enable Pwr_resetout_n
	   when digital TV is selected. */
2418 2419 2420 2421 2422 2423
	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);
2424 2425
		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
						PWR_CTL_EN, value, 4);
2426 2427 2428
		msleep(PWR_SLEEP_INTERVAL);
	}

2429 2430
	/* update power control for afe */
	status = cx231xx_afe_update_power_control(dev, mode);
2431

2432 2433
	/* update power control for i2s_blk */
	status = cx231xx_i2s_blk_update_power_control(dev, mode);
2434

2435 2436
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
				       4);
2437 2438

	return status;
2439 2440 2441 2442
}

int cx231xx_power_suspend(struct cx231xx *dev)
{
2443 2444 2445
	u8 value[4] = { 0, 0, 0, 0 };
	u32 tmp = 0;
	int status = 0;
2446

2447 2448
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
				       value, 4);
2449 2450
	if (status > 0)
		return status;
2451

2452 2453
	tmp = *((u32 *) value);
	tmp &= (~PWR_MODE_MASK);
2454

2455 2456 2457 2458
	value[0] = (u8) tmp;
	value[1] = (u8) (tmp >> 8);
	value[2] = (u8) (tmp >> 16);
	value[3] = (u8) (tmp >> 24);
2459 2460
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
					value, 4);
2461

2462
	return status;
2463 2464
}

2465 2466 2467
/******************************************************************************
 *                  S T R E A M    C O N T R O L   functions                  *
 ******************************************************************************/
2468 2469
int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask)
{
2470 2471 2472
	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
	u32 tmp = 0;
	int status = 0;
2473

2474
	cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask);
2475 2476
	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
				       value, 4);
2477 2478
	if (status < 0)
		return status;
2479

2480 2481 2482 2483 2484 2485
	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);
2486

2487 2488
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
					value, 4);
2489

2490
	return status;
2491 2492 2493 2494
}

int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
{
2495 2496 2497
	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
	u32 tmp = 0;
	int status = 0;
2498

2499 2500 2501 2502 2503
	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;
2504

2505 2506 2507 2508 2509 2510
	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);
2511

2512 2513
	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
					value, 4);
2514

2515
	return status;
2516 2517 2518 2519
}

int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
{
2520
	int status = 0;
2521 2522
	u32 value = 0;
	u8 val[4] = { 0, 0, 0, 0 };
2523

2524 2525
	if (dev->udev->speed == USB_SPEED_HIGH) {
		switch (media_type) {
2526
		case 81: /* audio */
2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548
			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 */
2549 2550
			cx231xx_info("%s: set ts1 registers", __func__);

2551
		if (dev->board.has_417) {
2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573
			cx231xx_info(" MPEG\n");
			value &= 0xFFFFFFFC;
			value |= 0x3;

			status = cx231xx_mode_register(dev, TS_MODE_REG, value);

			val[0] = 0x04;
			val[1] = 0xA3;
			val[2] = 0x3B;
			val[3] = 0x00;
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
				 TS1_CFG_REG, val, 4);

			val[0] = 0x00;
			val[1] = 0x08;
			val[2] = 0x00;
			val[3] = 0x08;
			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
				 TS1_LENGTH_REG, val, 4);

		} else {
			cx231xx_info(" BDA\n");
2574
			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
2575 2576
			status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010);
		}
2577
			break;
2578

2579 2580 2581 2582 2583 2584 2585 2586 2587 2588
		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);
	}
2589

2590 2591
	return status;
}
2592 2593 2594

int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
{
2595
	int rc = -1;
2596
	u32 ep_mask = -1;
2597
	struct pcb_config *pcb_config;
2598 2599

	/* get EP for media type */
2600
	pcb_config = (struct pcb_config *)&dev->current_pcb_config;
2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652

	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);

2653
		if (rc < 0)
2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664
			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);
	}

2665 2666 2667 2668
	if (dev->mode == CX231XX_ANALOG_MODE)
		;/* do any in Analog mode */
	else
		;/* do any in digital mode */
2669 2670 2671

	return rc;
}
2672
EXPORT_SYMBOL_GPL(cx231xx_capture_start);
2673

2674 2675 2676
/*****************************************************************************
*                   G P I O   B I T control functions                        *
******************************************************************************/
2677
int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val)
2678
{
2679
	int status = 0;
2680

2681
	status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0);
2682

2683
	return status;
2684 2685
}

2686
int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val)
2687
{
2688
	int status = 0;
2689

2690
	status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1);
2691

2692
	return status;
2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706
}

/*
* 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,
2707
			       int pin_number, int pin_value)
2708 2709
{
	int status = 0;
2710
	u32 value = 0;
2711

2712
	/* Check for valid pin_number - if 32 , bail out */
2713
	if (pin_number >= 32)
2714
		return -EINVAL;
2715

2716 2717
	/* input */
	if (pin_value == 0)
2718
		value = dev->gpio_dir & (~(1 << pin_number));	/* clear */
2719
	else
2720
		value = dev->gpio_dir | (1 << pin_number);
2721

2722
	status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val);
2723

2724
	/* cache the value for future */
2725 2726
	dev->gpio_dir = value;

2727
	return status;
2728 2729 2730
}

/*
2731
* cx231xx_set_gpio_value
2732 2733 2734 2735 2736 2737 2738 2739 2740
*      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
*/
2741
int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value)
2742
{
2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754
	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;
2755 2756
		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
					      (u8 *) &dev->gpio_val);
2757
		value = 0;
2758
	}
2759

2760
	if (pin_value == 0)
2761
		value = dev->gpio_val & (~(1 << pin_number));
2762
	else
2763
		value = dev->gpio_val | (1 << pin_number);
2764

2765 2766
	/* store the value */
	dev->gpio_val = value;
2767

2768
	/* toggle bit0 of GP_IO */
2769
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2770

2771
	return status;
2772 2773
}

2774 2775 2776
/*****************************************************************************
*                      G P I O I2C related functions                         *
******************************************************************************/
2777 2778 2779 2780 2781
int cx231xx_gpio_i2c_start(struct cx231xx *dev)
{
	int status = 0;

	/* set SCL to output 1 ; set SDA to output 1 */
2782 2783 2784 2785 2786
	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;

2787 2788
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2789 2790 2791
		return -EINVAL;

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

2795 2796
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2797 2798
		return -EINVAL;

2799 2800 2801
	/* 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);
2802

2803 2804
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2805 2806 2807 2808 2809 2810 2811
		return -EINVAL;

	return status;
}

int cx231xx_gpio_i2c_end(struct cx231xx *dev)
{
2812
	int status = 0;
2813

2814 2815 2816
	/* 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;
2817

2818 2819
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2820

2821 2822
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2823 2824
		return -EINVAL;

2825 2826 2827
	/* 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);
2828

2829 2830
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2831 2832 2833 2834
		return -EINVAL;

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

2838
	status =
2839 2840
	    cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
	if (status < 0)
2841
		return -EINVAL;
2842

2843 2844 2845 2846 2847
	return status;
}

int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
{
2848 2849
	int status = 0;
	u8 i;
2850 2851

	/* set SCL to output ; set SDA to output */
2852 2853 2854 2855 2856 2857 2858 2859
	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);
2860 2861
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2862 2863 2864

			/* set SCL to output 1; set SDA to output 0     */
			dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2865 2866
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2867 2868 2869

			/* set SCL to output 0; set SDA to output 0     */
			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2870 2871
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2872
		} else {
2873 2874 2875
			/* 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;
2876 2877
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2878 2879 2880

			/* set SCL to output 1; set SDA to output 1     */
			dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2881 2882
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2883 2884 2885

			/* set SCL to output 0; set SDA to output 1     */
			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2886 2887
			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
						      (u8 *)&dev->gpio_val);
2888
		}
2889 2890 2891 2892
	}
	return status;
}

2893
int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf)
2894 2895
{
	u8 value = 0;
2896 2897 2898
	int status = 0;
	u32 gpio_logic_value = 0;
	u8 i;
2899 2900

	/* read byte */
2901
	for (i = 0; i < 8; i++) {	/* send write I2c addr */
2902 2903

		/* set SCL to output 0; set SDA to input */
2904
		dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2905 2906
		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
2907 2908

		/* set SCL to output 1; set SDA to input */
2909
		dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
2910 2911
		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
2912 2913 2914

		/* get SDA data bit */
		gpio_logic_value = dev->gpio_val;
2915 2916 2917
		status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
		if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0)
2918
			value |= (1 << (8 - i - 1));
2919 2920 2921 2922 2923

		dev->gpio_val = gpio_logic_value;
	}

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

2929 2930
	/* store the value */
	*buf = value & 0xff;
2931 2932 2933 2934 2935 2936

	return status;
}

int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev)
{
2937
	int status = 0;
2938
	u32 gpio_logic_value = 0;
2939 2940
	int nCnt = 10;
	int nInit = nCnt;
2941

2942 2943
	/* clock stretch; set SCL to input; set SDA to input;
	   get SCL value till SCL = 1 */
2944 2945
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
	dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
2946 2947

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

2950
	do {
2951
		msleep(2);
2952 2953
		status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
					      (u8 *)&dev->gpio_val);
2954
		nCnt--;
2955 2956 2957
	} while (((dev->gpio_val &
			  (1 << dev->board.tuner_scl_gpio)) == 0) &&
			 (nCnt > 0));
2958

2959
	if (nCnt == 0)
2960
		cx231xx_info("No ACK after %d msec -GPIO I2C failed!",
2961
			     nInit * 10);
2962

2963 2964 2965 2966 2967
	/*
	 * readAck
	 * through clock stretch, slave has given a SCL signal,
	 * so the SDA data can be directly read.
	 */
2968
	status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2969

2970
	if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
2971
		dev->gpio_val = gpio_logic_value;
2972
		dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
2973 2974 2975
		status = 0;
	} else {
		dev->gpio_val = gpio_logic_value;
2976
		dev->gpio_val |= (1 << dev->board.tuner_sda_gpio);
2977 2978
	}

2979 2980
	/* read SDA end, set the SCL to output 0, after this operation,
	   SDA direction can be changed. */
2981
	dev->gpio_val = gpio_logic_value;
2982 2983
	dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
2984
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2985 2986 2987 2988 2989 2990

	return status;
}

int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev)
{
2991
	int status = 0;
2992 2993

	/* set SDA to ouput */
2994
	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
2995
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
2996 2997

	/* set SCL = 0 (output); set SDA = 0 (output) */
2998 2999
	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
3000
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3001 3002

	/* set SCL = 1 (output); set SDA = 0 (output) */
3003
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
3004
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3005 3006

	/* set SCL = 0 (output); set SDA = 0 (output) */
3007
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
3008
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3009 3010

	/* set SDA to input,and then the slave will read data from SDA. */
3011
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
3012
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3013 3014 3015 3016 3017 3018

	return status;
}

int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
{
3019
	int status = 0;
3020 3021

	/* set scl to output ; set sda to input */
3022 3023
	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
3024
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3025 3026

	/* set scl to output 0; set sda to input */
3027
	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
3028
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3029 3030

	/* set scl to output 1; set sda to input */
3031
	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
3032
	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
3033 3034 3035 3036

	return status;
}

3037 3038 3039
/*****************************************************************************
*                      G P I O I2C related functions                         *
******************************************************************************/
3040 3041 3042
/* cx231xx_gpio_i2c_read
 * Function to read data from gpio based I2C interface
 */
3043
int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
3044
{
3045 3046
	int status = 0;
	int i = 0;
3047

3048
	/* get the lock */
3049 3050 3051 3052 3053 3054
	mutex_lock(&dev->gpio_i2c_lock);

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

	/* write dev_addr */
3055
	status = cx231xx_gpio_i2c_write_byte(dev, (dev_addr << 1) + 1);
3056 3057 3058 3059

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

3060 3061 3062 3063 3064
	/* read data */
	for (i = 0; i < len; i++) {
		/* read data */
		buf[i] = 0;
		status = cx231xx_gpio_i2c_read_byte(dev, &buf[i]);
3065

3066 3067 3068 3069 3070
		if ((i + 1) != len) {
			/* only do write ack if we more length */
			status = cx231xx_gpio_i2c_write_ack(dev);
		}
	}
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086

	/* 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
 */
3087
int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
3088
{
3089 3090
	int status = 0;
	int i = 0;
3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101

	/* 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 */
3102
	status = cx231xx_gpio_i2c_read_ack(dev);
3103

3104
	for (i = 0; i < len; i++) {
3105
		/* Write data */
3106
		status = cx231xx_gpio_i2c_write_byte(dev, buf[i]);
3107

3108 3109 3110
		/* read Ack */
		status = cx231xx_gpio_i2c_read_ack(dev);
	}
3111

3112
	/* write End */
3113 3114 3115 3116 3117 3118 3119
	status = cx231xx_gpio_i2c_end(dev);

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

	return 0;
}