⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cx23885-417.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
		return -1;	}	/* transfer to the chip */	dprintk(2, "Loading firmware ...\n");	dataptr = (u32 *)firmware->data;	for (i = 0; i < (firmware->size >> 2); i++) {		value = *dataptr;		checksum += ~value;		if (mc417_memory_write(dev, i, value) != 0) {			printk(KERN_ERR "ERROR: Loading firmware failed!\n");			release_firmware(firmware);			return -1;		}		dataptr++;	}	/* read back to verify with the checksum */	dprintk(1, "Verifying firmware ...\n");	for (i--; i >= 0; i--) {		if (mc417_memory_read(dev, i, &value) != 0) {			printk(KERN_ERR "ERROR: Reading firmware failed!\n");			release_firmware(firmware);			return -1;		}		checksum -= ~value;	}	if (checksum) {		printk(KERN_ERR			"ERROR: Firmware load failed (checksum mismatch).\n");		release_firmware(firmware);		return -1;	}	release_firmware(firmware);	dprintk(1, "Firmware upload successful.\n");	retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,		IVTV_CMD_HW_BLOCKS_RST);	/* Restore GPIO settings, make sure EIO14 is enabled as an output. */	dprintk(2, "%s: GPIO output EIO 0-15 was = 0x%x\n",		__func__, gpio_output);	/* Power-up seems to have GPIOs AFU. This was causing digital side	 * to fail at power-up. Seems GPIOs should be set to 0x10ff0411 at	 * power-up.	 * gpio_output |= (1<<14);	 */	/* Note: GPIO14 is specific to the HVR1800 here */	gpio_output = 0x10ff0411 | (1<<14);	retval |= mc417_register_write(dev, 0x9020, gpio_output | (1<<14));	dprintk(2, "%s: GPIO output EIO 0-15 now = 0x%x\n",		__func__, gpio_output);	dprintk(1, "%s: GPIO value  EIO 0-15 was = 0x%x\n",		__func__, value);	value |= (1<<14);	dprintk(1, "%s: GPIO value  EIO 0-15 now = 0x%x\n",		__func__, value);	retval |= mc417_register_write(dev, 0x900C, value);	retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);	retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8);	if (retval < 0)		printk(KERN_ERR "%s: Error with mc417_register_write\n",			__func__);	return 0;}void cx23885_417_check_encoder(struct cx23885_dev *dev){	u32 status, seq;	status = seq = 0;	cx23885_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq);	dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq);}static void cx23885_codec_settings(struct cx23885_dev *dev){	dprintk(1, "%s()\n", __func__);	/* assign frame size */	cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,				dev->ts1.height, dev->ts1.width);	dev->mpeg_params.width = dev->ts1.width;	dev->mpeg_params.height = dev->ts1.height;	dev->mpeg_params.is_50hz =		(dev->encodernorm.id & V4L2_STD_625_50) != 0;	cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params);	cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);	cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);}static int cx23885_initialize_codec(struct cx23885_dev *dev){	int version;	int retval;	u32 i, data[7];	dprintk(1, "%s()\n", __func__);	retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */	if (retval < 0) {		dprintk(2, "%s() PING OK\n", __func__);		retval = cx23885_load_firmware(dev);		if (retval < 0) {			printk(KERN_ERR "%s() f/w load failed\n", __func__);			return retval;		}		dev->cx23417_mailbox = cx23885_find_mailbox(dev);		if (dev->cx23417_mailbox < 0) {			printk(KERN_ERR "%s() mailbox < 0, error\n",				__func__);			return -1;		}		retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0);		if (retval < 0) {			printk(KERN_ERR				"ERROR: cx23417 firmware ping failed!\n");			return -1;		}		retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1,			&version);		if (retval < 0) {			printk(KERN_ERR "ERROR: cx23417 firmware get encoder :"				"version failed!\n");			return -1;		}		dprintk(1, "cx23417 firmware version is 0x%08x\n", version);		msleep(200);	}	cx23885_codec_settings(dev);	msleep(60);	cx23885_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,		CX23885_FIELD1_SAA7115, CX23885_FIELD2_SAA7115);	cx23885_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,		CX23885_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0,		0, 0);	/* Setup to capture VBI */	data[0] = 0x0001BD00;	data[1] = 1;          /* frames per interrupt */	data[2] = 4;          /* total bufs */	data[3] = 0x91559155; /* start codes */	data[4] = 0x206080C0; /* stop codes */	data[5] = 6;          /* lines */	data[6] = 64;         /* BPL */	cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1],		data[2], data[3], data[4], data[5], data[6]);	for (i = 2; i <= 24; i++) {		int valid;		valid = ((i >= 19) && (i <= 21));		cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i,				valid, 0 , 0, 0);		cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0,				i | 0x80000000, valid, 0, 0, 0);	}	cx23885_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX23885_UNMUTE);	msleep(60);	/* initialize the video input */	cx23885_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);	msleep(60);	/* Enable VIP style pixel invalidation so we work with scaled mode */	mc417_memory_write(dev, 2120, 0x00000080);	/* start capturing to the host interface */	cx23885_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,		CX23885_MPEG_CAPTURE, CX23885_RAW_BITS_NONE);	msleep(10);	return 0;}/* ------------------------------------------------------------------ */static int bb_buf_setup(struct videobuf_queue *q,	unsigned int *count, unsigned int *size){	struct cx23885_fh *fh = q->priv_data;	fh->dev->ts1.ts_packet_size  = mpeglinesize;	fh->dev->ts1.ts_packet_count = mpeglines;	*size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;	*count = mpegbufs;	return 0;}static int bb_buf_prepare(struct videobuf_queue *q,	struct videobuf_buffer *vb, enum v4l2_field field){	struct cx23885_fh *fh = q->priv_data;	return cx23885_buf_prepare(q, &fh->dev->ts1,		(struct cx23885_buffer *)vb,		field);}static void bb_buf_queue(struct videobuf_queue *q,	struct videobuf_buffer *vb){	struct cx23885_fh *fh = q->priv_data;	cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb);}static void bb_buf_release(struct videobuf_queue *q,	struct videobuf_buffer *vb){	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);}static struct videobuf_queue_ops cx23885_qops = {	.buf_setup    = bb_buf_setup,	.buf_prepare  = bb_buf_prepare,	.buf_queue    = bb_buf_queue,	.buf_release  = bb_buf_release,};/* ------------------------------------------------------------------ */static const u32 *ctrl_classes[] = {	cx2341x_mpeg_ctrls,	NULL};static int cx23885_queryctrl(struct cx23885_dev *dev,	struct v4l2_queryctrl *qctrl){	qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);	if (qctrl->id == 0)		return -EINVAL;	/* MPEG V4L2 controls */	if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))		qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;	return 0;}static int cx23885_querymenu(struct cx23885_dev *dev,	struct v4l2_querymenu *qmenu){	struct v4l2_queryctrl qctrl;	qctrl.id = qmenu->id;	cx23885_queryctrl(dev, &qctrl);	return v4l2_ctrl_query_menu(qmenu, &qctrl,		cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));}static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	unsigned int i;	for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)		if (*id & cx23885_tvnorms[i].id)			break;	if (i == ARRAY_SIZE(cx23885_tvnorms))		return -EINVAL;	dev->encodernorm = cx23885_tvnorms[i];#if 0	/* Notify the video decoder and other i2c clients.	 * This will likely need to be enabled for non NTSC	 * formats.	 */	cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_S_STD, id);	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, id);#endif	return 0;}static int vidioc_enum_input(struct file *file, void *priv,				struct v4l2_input *i){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	struct cx23885_input *input;	unsigned int n;	n = i->index;	if (n >= 4)		return -EINVAL;	input = &cx23885_boards[dev->board].input[n];	if (input->type == 0)		return -EINVAL;	memset(i, 0, sizeof(*i));	i->index = n;	/* FIXME	 * strcpy(i->name, input->name); */	strcpy(i->name, "unset");	if (input->type == CX23885_VMUX_TELEVISION ||	    input->type == CX23885_VMUX_CABLE)		i->type = V4L2_INPUT_TYPE_TUNER;	else		i->type  = V4L2_INPUT_TYPE_CAMERA;	for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++)		i->std |= cx23885_tvnorms[n].id;	return 0;}static int vidioc_g_input(struct file *file, void *priv, unsigned int *i){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	*i = dev->input;	return 0;}static int vidioc_s_input(struct file *file, void *priv, unsigned int i){	if (i >= 4)		return -EINVAL;	return 0;}static int vidioc_g_tuner(struct file *file, void *priv,				struct v4l2_tuner *t){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	if (UNSET == dev->tuner_type)		return -EINVAL;	if (0 != t->index)		return -EINVAL;	memset(t, 0, sizeof(*t));	strcpy(t->name, "Television");	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);	dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);	return 0;}static int vidioc_s_tuner(struct file *file, void *priv,				struct v4l2_tuner *t){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	if (UNSET == dev->tuner_type)		return -EINVAL;	/* Update the A/V core */	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);	return 0;}static int vidioc_g_frequency(struct file *file, void *priv,				struct v4l2_frequency *f){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	memset(f, 0, sizeof(*f));	if (UNSET == dev->tuner_type)		return -EINVAL;	f->type = V4L2_TUNER_ANALOG_TV;	f->frequency = dev->freq;	/* Assumption that tuner is always on bus 1 */	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);	return 0;}static int vidioc_s_frequency(struct file *file, void *priv,				struct v4l2_frequency *f){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,		CX23885_END_NOW, CX23885_MPEG_CAPTURE,		CX23885_RAW_BITS_NONE);	dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n",		dev->tuner_type);	dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n",		f->tuner, f->type);	if (UNSET == dev->tuner_type)		return -EINVAL;	if (f->tuner != 0)		return -EINVAL;	if (f->type != V4L2_TUNER_ANALOG_TV)		return -EINVAL;	dev->freq = f->frequency;	/* Assumption that tuner is always on bus 1 */	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);	cx23885_initialize_codec(dev);	return 0;}static int vidioc_s_ctrl(struct file *file, void *priv,				struct v4l2_control *ctl){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	/* Update the A/V core */	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);	return 0;}static int vidioc_querycap(struct file *file, void  *priv,				struct v4l2_capability *cap){	struct cx23885_fh  *fh  = file->private_data;	struct cx23885_dev *dev = fh->dev;	struct cx23885_tsport  *tsport = &dev->ts1;	memset(cap, 0, sizeof(*cap));	strcpy(cap->driver, dev->name);	strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,		sizeof(cap->card));	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));	cap->version = CX23885_VERSION_CODE;	cap->capabilities =		V4L2_CAP_VIDEO_CAPTURE |		V4L2_CAP_READWRITE     |		V4L2_CAP_STREAMING     |		0;	if (UNSET != dev->tuner_type)		cap->capabilities |= V4L2_CAP_TUNER;	return 0;}static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,					struct v4l2_fmtdesc *f)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -