Esempio n. 1
0
int cx231xx_reset_analog_tuner(struct cx231xx *dev)
{
	int status = 0;

	if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {

		struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;

		if (dops->init != NULL && !dev->xc_fw_load_done) {

			cx231xx_info("Reloading firmware for XC5000\n");
			status = dops->init(dev->dvb->frontend);
			if (status == 0) {
				dev->xc_fw_load_done = 1;
				cx231xx_info
				    ("XC5000 firmware download completed\n");
			} else {
				dev->xc_fw_load_done = 0;
				cx231xx_info
				    ("XC5000 firmware download failed !!!\n");
			}
		}

	}

	return status;
}
Esempio n. 2
0
/* Since cx231xx_pre_card_setup() requires a proper dev->model,
 * this won't work for boards with generic PCI IDs
 */
void cx231xx_pre_card_setup(struct cx231xx *dev)
{

	cx231xx_set_model(dev);

	cx231xx_info("Identified as %s (card=%d)\n",
		     dev->board.name, dev->model);

	/* set the direction for GPIO pins */
	if (dev->board.tuner_gpio) {
		cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
		cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
		cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);

		/* request some modules if any required */

		/* reset the Tuner */
		cx231xx_gpio_set(dev, dev->board.tuner_gpio);
	}

	/* set the mode to Analog mode initially */
	cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);

	/* Unlock device */
	/* cx231xx_set_mode(dev, CX231XX_SUSPEND); */

}
Esempio n. 3
0
int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
{
	int rc = 0;
	struct cx231xx *dev = ptr;

	if (dev->tuner_type == TUNER_XC5000) {
		if (command == XC5000_TUNER_RESET) {
			cx231xx_info
				("Tuner CB: RESET: cmd %d : tuner type %d \n",
				 command, dev->tuner_type);
			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
					       1);
			msleep(10);
			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
					       0);
			msleep(330);
			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
					       1);
			msleep(10);
		}
	} else if (dev->tuner_type == TUNER_NXP_TDA18271) {
		switch (command) {
		case TDA18271_CALLBACK_CMD_AGC_ENABLE:
			if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
				rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
			break;
		default:
			rc = -EINVAL;
			break;
		}
	}
	return rc;
}
Esempio n. 4
0
int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
{
	int status = 0;

	if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {

		struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;

		if (dops->set_analog_params != NULL) {
			struct analog_parameters params;

			params.frequency = freq;
			params.std = dev->norm;
			params.mode = 0;	/* 0- Air; 1 - cable */
			/*params.audmode = ;       */

			/* Set the analog parameters to set the frequency */
			cx231xx_info("Setting Frequency for XC5000\n");
			dops->set_analog_params(dev->dvb->frontend, &params);
		}

	}

	return status;
}
void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c)
{
	unsigned char buf;
	int i, rc;

	cx231xx_info(": Checking for I2C devices ..\n");
	for (i = 0; i < 128; i++) {
		c->addr = i;
		rc = i2c_master_recv(c, &buf, 0);
		if (rc < 0)
			continue;
		cx231xx_info("%s: i2c scan: found device @ 0x%x  [%s]\n",
			     dev->name, i << 1,
			     i2c_devs[i] ? i2c_devs[i] : "???");
	}
	cx231xx_info(": Completed Checking for I2C devices.\n");
}
Esempio n. 6
0
static void cx231xx_config_tuner(struct cx231xx *dev)
{
	struct tuner_setup tun_setup;
	struct v4l2_frequency f;

	if (dev->tuner_type == TUNER_ABSENT)
		return;

	tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
	tun_setup.type = dev->tuner_type;
	tun_setup.addr = dev->tuner_addr;
	tun_setup.tuner_callback = cx231xx_tuner_callback;

	tuner_call(dev, tuner, s_type_addr, &tun_setup);

#if 0
	if (tun_setup.type == TUNER_XC5000) {
		static struct xc2028_ctrl ctrl = {
			.fname = XC5000_DEFAULT_FIRMWARE,
			.max_len = 64,
			.demod = 0;
		};
		struct v4l2_priv_tun_config cfg = {
			.tuner = dev->tuner_type,
			.priv = &ctrl,
		};
		tuner_call(dev, tuner, s_config, &cfg);
	}
#endif
	/* configure tuner */
	f.tuner = 0;
	f.type = V4L2_TUNER_ANALOG_TV;
	f.frequency = 9076;	/* just a magic number */
	dev->ctl_freq = f.frequency;
	call_all(dev, tuner, s_frequency, &f);

}

void cx231xx_card_setup(struct cx231xx *dev)
{

	cx231xx_set_model(dev);

	dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
	if (cx231xx_boards[dev->model].tuner_addr)
		dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;

	/* request some modules */
	if (dev->board.decoder == CX231XX_AVDECODER) {
		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
					&dev->i2c_bus[0].i2c_adap,
					"cx25840", 0x88 >> 1, NULL);
		if (dev->sd_cx25840 == NULL)
			cx231xx_info("cx25840 subdev registration failure\n");
		cx25840_call(dev, core, load_fw);

	}
Esempio n. 7
0
/*
 * Stop and Deallocate URBs
 */
void cx231xx_uninit_vbi_isoc(struct cx231xx *dev)
{
	struct urb *urb;
	int i;

	cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n");

	dev->vbi_mode.bulk_ctl.nfields = -1;
	for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) {
		urb = dev->vbi_mode.bulk_ctl.urb[i];
		if (urb) {
			if (!irqs_disabled())
				usb_kill_urb(urb);
			else
				usb_unlink_urb(urb);

			if (dev->vbi_mode.bulk_ctl.transfer_buffer[i]) {

				kfree(dev->vbi_mode.bulk_ctl.
				      transfer_buffer[i]);
				dev->vbi_mode.bulk_ctl.transfer_buffer[i] =
				    NULL;
			}
			usb_free_urb(urb);
			dev->vbi_mode.bulk_ctl.urb[i] = NULL;
		}
		dev->vbi_mode.bulk_ctl.transfer_buffer[i] = NULL;
	}

	kfree(dev->vbi_mode.bulk_ctl.urb);
	kfree(dev->vbi_mode.bulk_ctl.transfer_buffer);

	dev->vbi_mode.bulk_ctl.urb = NULL;
	dev->vbi_mode.bulk_ctl.transfer_buffer = NULL;
	dev->vbi_mode.bulk_ctl.num_bufs = 0;

	cx231xx_capture_start(dev, 0, Vbi);
}
Esempio n. 8
0
int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
{
	int rc = 0;
	struct cx231xx *dev = ptr;

	if (dev->tuner_type == TUNER_XC5000) {
		if (command == XC5000_TUNER_RESET) {
			cx231xx_info
				("Tuner CB: RESET: cmd %d : tuner type %d \n",
				 command, dev->tuner_type);
			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
					       1);
			msleep(10);
			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
					       0);
			msleep(330);
			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
					       1);
			msleep(10);
		}
	}
	return rc;
}
Esempio n. 9
0
/*
 * Allocate URBs and start IRQ
 */
int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
			  int num_bufs, int max_pkt_size,
			  int (*bulk_copy) (struct cx231xx *dev,
					    struct urb *urb))
{
	struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq;
	int i;
	int sb_size, pipe;
	struct urb *urb;
	int rc;

	cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_prepare_isoc\n");

	/* De-allocates all pending stuff */
	cx231xx_uninit_vbi_isoc(dev);

	/* clear if any halt */
	usb_clear_halt(dev->udev,
		       usb_rcvbulkpipe(dev->udev,
				       dev->vbi_mode.end_point_addr));

	dev->vbi_mode.bulk_ctl.bulk_copy = bulk_copy;
	dev->vbi_mode.bulk_ctl.num_bufs = num_bufs;
	dma_q->pos = 0;
	dma_q->is_partial_line = 0;
	dma_q->last_sav = 0;
	dma_q->current_field = -1;
	dma_q->bytes_left_in_line = dev->width << 1;
	dma_q->lines_per_field = ((dev->norm & V4L2_STD_625_50) ?
				  PAL_VBI_LINES : NTSC_VBI_LINES);
	dma_q->lines_completed = 0;
	for (i = 0; i < 8; i++)
		dma_q->partial_buf[i] = 0;

	dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs,
					     GFP_KERNEL);
	if (!dev->vbi_mode.bulk_ctl.urb) {
		cx231xx_errdev("cannot alloc memory for usb buffers\n");
		return -ENOMEM;
	}

	dev->vbi_mode.bulk_ctl.transfer_buffer =
	    kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
	if (!dev->vbi_mode.bulk_ctl.transfer_buffer) {
		cx231xx_errdev("cannot allocate memory for usbtransfer\n");
		kfree(dev->vbi_mode.bulk_ctl.urb);
		return -ENOMEM;
	}

	dev->vbi_mode.bulk_ctl.max_pkt_size = max_pkt_size;
	dev->vbi_mode.bulk_ctl.buf = NULL;

	sb_size = max_packets * dev->vbi_mode.bulk_ctl.max_pkt_size;

	/* allocate urbs and transfer buffers */
	for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) {

		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
			cx231xx_err(DRIVER_NAME
				    ": cannot alloc bulk_ctl.urb %i\n", i);
			cx231xx_uninit_vbi_isoc(dev);
			return -ENOMEM;
		}
		dev->vbi_mode.bulk_ctl.urb[i] = urb;
		urb->transfer_flags = 0;

		dev->vbi_mode.bulk_ctl.transfer_buffer[i] =
		    kzalloc(sb_size, GFP_KERNEL);
		if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) {
			cx231xx_err(DRIVER_NAME
				    ": unable to allocate %i bytes for transfer"
				    " buffer %i%s\n", sb_size, i,
				    in_interrupt() ? " while in int" : "");
			cx231xx_uninit_vbi_isoc(dev);
			return -ENOMEM;
		}

		pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr);
		usb_fill_bulk_urb(urb, dev->udev, pipe,
				  dev->vbi_mode.bulk_ctl.transfer_buffer[i],
				  sb_size, cx231xx_irq_vbi_callback, dma_q);
	}

	init_waitqueue_head(&dma_q->wq);

	/* submit urbs and enables IRQ */
	for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) {
		rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC);
		if (rc) {
			cx231xx_err(DRIVER_NAME
				    ": submit of urb %i failed (error=%i)\n", i,
				    rc);
			cx231xx_uninit_vbi_isoc(dev);
			return rc;
		}
	}

	cx231xx_capture_start(dev, 1, Vbi);

	return 0;
}
u32 initialize_cx231xx(struct cx231xx *dev)
{
	u32 config_info = 0;
	struct pcb_config *p_pcb_info;
	u8 usb_speed = 1;	
	u8 data[4] = { 0, 0, 0, 0 };
	u32 ts1_source = 0;
	u32 ts2_source = 0;
	u32 analog_source = 0;
	u8 _current_scenario_idx = 0xff;

	ts1_source = SOURCE_TS_BDA;
	ts2_source = SOURCE_TS_BDA;

	cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4);

	config_info = *((u32 *) data);
	usb_speed = (u8) (config_info & 0x1);

	
	if (config_info & BUS_POWER) {	
		switch (config_info & BUSPOWER_MASK) {
		case TS1_PORT | BUS_POWER:
			cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY].speed =
			    usb_speed;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY];
			_current_scenario_idx = INDEX_BUSPOWER_DIGITAL_ONLY;
			break;
		case AVDEC_ENABLE | BUS_POWER:
			cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY].speed =
			    usb_speed;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY];
			_current_scenario_idx = INDEX_BUSPOWER_ANALOG_ONLY;
			break;
		case AVDEC_ENABLE | BUS_POWER | TS1_PORT:
			cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY].speed =
			    usb_speed;
			p_pcb_info = &cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY];
			_current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY;
			break;
		default:
			cx231xx_info("bad config in buspower!!!!\n");
			cx231xx_info("config_info=%x\n",
				     (config_info & BUSPOWER_MASK));
			return 1;
		}
	} else {		

		switch (config_info & SELFPOWER_MASK) {
		case TS1_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY].speed =
			    usb_speed;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY];
			_current_scenario_idx = INDEX_SELFPOWER_DIGITAL_ONLY;
			break;
		case TS1_TS2_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].
			    ts2_source = ts2_source;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL];
			_current_scenario_idx = INDEX_SELFPOWER_DUAL_DIGITAL;
			break;
		case AVDEC_ENABLE | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].
			    analog_source = analog_source;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY];
			_current_scenario_idx = INDEX_SELFPOWER_ANALOG_ONLY;
			break;
		case AVDEC_ENABLE | TS1_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].ts1_source =
			    ts1_source;
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].analog_source =
			    analog_source;
			p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_DUAL];
			_current_scenario_idx = INDEX_SELFPOWER_DUAL;
			break;
		case AVDEC_ENABLE | TS1_TS2_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts1_source =
			    ts1_source;
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts2_source =
			    ts2_source;
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].analog_source =
			    analog_source;
			p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE];
			_current_scenario_idx = INDEX_SELFPOWER_TRIPLE;
			break;
		case AVDEC_ENABLE | TS1VIP_TS2_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].
			    analog_source = analog_source;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR];
			_current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR;
			break;
		default:
			cx231xx_info("bad senario!!!!!\n");
			cx231xx_info("config_info=%x\n",
				     (config_info & SELFPOWER_MASK));
			return 1;
		}
	}

	dev->current_scenario_idx = _current_scenario_idx;

	memcpy(&dev->current_pcb_config, p_pcb_info,
		   sizeof(struct pcb_config));

	if (pcb_debug) {
		cx231xx_info("SC(0x00) register = 0x%x\n", config_info);
		cx231xx_info("scenario %d\n",
			    (dev->current_pcb_config.index) + 1);
		cx231xx_info("type=%x\n", dev->current_pcb_config.type);
		cx231xx_info("mode=%x\n", dev->current_pcb_config.mode);
		cx231xx_info("speed=%x\n", dev->current_pcb_config.speed);
		cx231xx_info("ts1_source=%x\n",
			     dev->current_pcb_config.ts1_source);
		cx231xx_info("ts2_source=%x\n",
			     dev->current_pcb_config.ts2_source);
		cx231xx_info("analog_source=%x\n",
			     dev->current_pcb_config.analog_source);
	}

	return 0;
}
Esempio n. 11
0
int initialize_cx231xx(struct cx231xx *dev)
{
	int retval;
	u32 config_info = 0;
	struct pcb_config *p_pcb_info;
	u8 usb_speed = 1;	/* from register,1--HS, 0--FS  */
	u8 data[4] = { 0, 0, 0, 0 };
	u32 ts1_source = 0;
	u32 ts2_source = 0;
	u32 analog_source = 0;
	u8 _current_scenario_idx = 0xff;

	ts1_source = SOURCE_TS_BDA;
	ts2_source = SOURCE_TS_BDA;

	/* read board config register to find out which
	pcb config it is related to */
	retval = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
				       data, 4);
	if (retval < 0)
		return retval;

	config_info = le32_to_cpu(*((__le32 *)data));
	usb_speed = (u8) (config_info & 0x1);

	/* Verify this device belongs to Bus power or Self power device */
	if (config_info & BUS_POWER) {	/* bus-power */
		switch (config_info & BUSPOWER_MASK) {
		case TS1_PORT | BUS_POWER:
			cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY].speed =
			    usb_speed;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY];
			_current_scenario_idx = INDEX_BUSPOWER_DIGITAL_ONLY;
			break;
		case AVDEC_ENABLE | BUS_POWER:
			cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY].speed =
			    usb_speed;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY];
			_current_scenario_idx = INDEX_BUSPOWER_ANALOG_ONLY;
			break;
		case AVDEC_ENABLE | BUS_POWER | TS1_PORT:
			cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY].speed =
			    usb_speed;
			p_pcb_info = &cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY];
			_current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY;
			break;
		default:
			cx231xx_info("bad config in buspower!!!!\n");
			cx231xx_info("config_info=%x\n",
				     (config_info & BUSPOWER_MASK));
			return 1;
		}
	} else {		/* self-power */

		switch (config_info & SELFPOWER_MASK) {
		case TS1_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY].speed =
			    usb_speed;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY];
			_current_scenario_idx = INDEX_SELFPOWER_DIGITAL_ONLY;
			break;
		case TS1_TS2_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].
			    ts2_source = ts2_source;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL];
			_current_scenario_idx = INDEX_SELFPOWER_DUAL_DIGITAL;
			break;
		case AVDEC_ENABLE | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].
			    analog_source = analog_source;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY];
			_current_scenario_idx = INDEX_SELFPOWER_ANALOG_ONLY;
			break;
		case AVDEC_ENABLE | TS1_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].ts1_source =
			    ts1_source;
			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].analog_source =
			    analog_source;
			p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_DUAL];
			_current_scenario_idx = INDEX_SELFPOWER_DUAL;
			break;
		case AVDEC_ENABLE | TS1_TS2_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts1_source =
			    ts1_source;
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts2_source =
			    ts2_source;
			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].analog_source =
			    analog_source;
			p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE];
			_current_scenario_idx = INDEX_SELFPOWER_TRIPLE;
			break;
		case AVDEC_ENABLE | TS1VIP_TS2_PORT | SELF_POWER:
			cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].speed =
			    usb_speed;
			cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].
			    analog_source = analog_source;
			p_pcb_info =
			    &cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR];
			_current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR;
			break;
		default:
			cx231xx_info("bad senario!!!!!\n");
			cx231xx_info("config_info=%x\n",
				     (config_info & SELFPOWER_MASK));
			return -ENODEV;
		}
	}

	dev->current_scenario_idx = _current_scenario_idx;

	memcpy(&dev->current_pcb_config, p_pcb_info,
		   sizeof(struct pcb_config));

	if (pcb_debug) {
		cx231xx_info("SC(0x00) register = 0x%x\n", config_info);
		cx231xx_info("scenario %d\n",
			    (dev->current_pcb_config.index) + 1);
		cx231xx_info("type=%x\n", dev->current_pcb_config.type);
		cx231xx_info("mode=%x\n", dev->current_pcb_config.mode);
		cx231xx_info("speed=%x\n", dev->current_pcb_config.speed);
		cx231xx_info("ts1_source=%x\n",
			     dev->current_pcb_config.ts1_source);
		cx231xx_info("ts2_source=%x\n",
			     dev->current_pcb_config.ts2_source);
		cx231xx_info("analog_source=%x\n",
			     dev->current_pcb_config.analog_source);
	}

	return 0;
}