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

📄 adv717x.c

📁 linux TV 源码
💻 C
字号:
/*    ADV7175A - Analog Devices ADV7175A video encoder driver version 0.0.3   Copyright (C) 2000 Henrik Johannson <henrikjo@post.utfors.se>   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/module.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/pci.h>#include <linux/signal.h>#include <asm/io.h>#include <asm/pgtable.h>#include <asm/page.h>#include <linux/sched.h>#include <asm/segment.h>#include <linux/types.h>#include <linux/wrapper.h>#include <linux/videodev.h>#include <linux/version.h>#include <asm/uaccess.h>#include <linux/i2c-algo-bit.h>#include <linux/video_encoder.h>#include "em8300_reg.h"#include <linux/em8300.h>#include "adv717x.h"#include "encoder.h"#ifdef MODULEint pixelport_16bit = 1;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,9)MODULE_LICENSE("GPL");#endifMODULE_PARM(pixelport_16bit, "i");int pixelport_other_pal = 1;MODULE_PARM(pixelport_other_pal, "i");int swap_redblue_pal = 0;MODULE_PARM(swap_redblue_pal, "i");static int color_bars = 0;MODULE_PARM(color_bars, "i");#endif#define i2c_is_isa_client(clientptr) \		((clientptr)->adapter->algo->id == I2C_ALGO_ISA)#define i2c_is_isa_adapter(adapptr) \		((adapptr)->algo->id == I2C_ALGO_ISA)#define ADV7175_REG_MR0 0#define ADV7175_REG_MR1 1#define ADV7175_REG_TTXRQ_CTRL 0x24static int adv717x_attach_adapter(struct i2c_adapter *adapter);int adv717x_detach_client(struct i2c_client *client);int adv717x_command(struct i2c_client *client, unsigned int cmd, void *arg);void adv717x_inc_use (struct i2c_client *client);void adv717x_dec_use (struct i2c_client *client);#define CHIP_ADV7175A 1#define CHIP_ADV7170  2struct adv717x_data_s {	int chiptype;	int mode;	int bars;	int rgbmode;	int enableoutput;	unsigned char config[32];	int configlen;};/* This is the driver that will be inserted */static struct i2c_driver adv717x_driver = {  /* name */		"ADV717X video encoder driver",  /* id */		I2C_DRIVERID_ADV717X,  /* flags */		I2C_DF_NOTIFY,  /* attach_adapter */  &adv717x_attach_adapter,  /* detach_client */   &adv717x_detach_client,  /* command */		&adv717x_command,  /* inc_use */		&adv717x_inc_use,  /* dec_use */		&adv717x_dec_use};int adv717x_id = 0;static unsigned char PAL_config_7170[27] = {	0x05,   // Mode Register 0	0x07,   // Mode Register 1	0x48,   // Mode Register 2	0x00,   // Mode Register 3	0x00,   // Mode Register 4	0x00,   // Reserved	0x00,   // Reserved	0x0d,   // Timing Register 0	0x77,   // Timing Register 1	0xcb,   // Subcarrier Frequency Register 0	0x8a,   // Subcarrier Frequency Register 1	0x09,   // Subcarrier Frequency Register 2	0x2a,   // Subcarrier Frequency Register 3	0x00,   // Subcarrier Phase Register 	0x00,   // Closed Captioning Ext Register 0	0x00,   // Closed Captioning Ext Register 1	0x00,   // Closed Captioning Register 0 	0x00,   // Closed Captioning Register 1 	0x00,   // Pedestal Control Register 0	0x00,   // Pedestal Control Register 1	0x00,   // Pedestal Control Register 2	0x00,   // Pedestal Control Register 3	0x00,	// CGMS_WSS Reg 0	0x00,	// CGMS_WSS Reg 1	0x00,	// CGMS_WSS Reg 2	0x00	// TeleText Control Register};static unsigned char NTSC_config_7170[27] = {	0x10,   // Mode Register 0	0x06,   // Mode Register 1	0x08,   // Mode Register 2	0x00,   // Mode Register 3	0x00,   // Mode Register 4	0x00,   // Reserved	0x00,   // Reserved	0x0d,   // Timing Register 0	0x77,   // Timing Register 1	0x16,   // Subcarrier Frequency Register 0	0x7c,   // Subcarrier Frequency Register 1	0xf0,   // Subcarrier Frequency Register 2	0x21,   // Subcarrier Frequency Register 3	0x00,   // Subcarrier Phase Register 	0x00,   // Closed Captioning Ext Register 0	0x00,   // Closed Captioning Ext Register 1	0x00,   // Closed Captioning Register 0 	0x00,   // Closed Captioning Register 1 	0x00,   // Pedestal Control Register 0	0x00,   // Pedestal Control Register 1	0x00,   // Pedestal Control Register 2	0x00,   // Pedestal Control Register 3	0x00,	// CGMS_WSS Reg 0	0x00,	// CGMS_WSS Reg 1	0x00,	// CGMS_WSS Reg 2	0x00	// TeleText Control Register};static unsigned char PAL_M_config_7175[16] = {   //These need to be tested	0x06,   // Mode Register 0	0x00,   // Mode Register 1	0xa3,   // Subcarrier Frequency Register 0	0xef, 	// Subcarrier Frequency Register 1	0xe6, 	// Subcarrier Frequency Register 2	0x21,  	// Subcarrier Frequency Register 3	0x00,   // Subcarrier Phase Register	0x0d,   // Timing Register 0	0x00,   // Closed Captioning Ext Register 0	0x00,   // Closed Captioning Ext Register 1	0x00,   // Closed Captioning Register 0	0x00,   // Closed Captioning Register 1	0xc0, 	// Timing Register 1	0x73,  	// Mode Register 2	0x00,   // Pedestal Control Register 0	0x00,   // Pedestal Control Register 1};static unsigned char PAL_config_7175[17] = {	0x01,   // Mode Register 0	0x06,   // Mode Register 1	0xcb,   // Subcarrier Frequency Register 0	0x8a,   // Subcarrier Frequency Register 1	0x09,   // Subcarrier Frequency Register 2	0x2a,   // Subcarrier Frequency Register 3	0x00,   // Subcarrier Phase Register 	0x0d,   // Timing Register 0	0x00,   // Closed Captioning Ext Register 0	0x00,   // Closed Captioning Ext Register 1	0x00,   // Closed Captioning Register 0 	0x00,   // Closed Captioning Register 1 	0x73,   // Timing Register 1	0x08,   // Mode Register 2	0x00,   // Pedestal Control Register 0	0x00,   // Pedestal Control Register 1	0x00,   // Mode Register 3};static unsigned char PAL60_config_7175[16] = {	0x12,   // Mode Register 0	0x0,	// Mode Register 1	0xcb,   // Subcarrier Frequency Register 0	0x8a,   // Subcarrier Frequency Register 1	0x09,   // Subcarrier Frequency Register 2	0x2a,   // Subcarrier Frequency Register 3	0x00,   // Subcarrier Phase Register 	0x0d,   // Timing Register 0	0x00,   // Closed Captioning Ext Register 0	0x00,   // Closed Captioning Ext Register 1	0x00,   // Closed Captioning Register 0 	0x00,   // Closed Captioning Register 1 	0x73,   // Timing Register 1	0x08,   // Mode Register 2	0x00,   // Pedestal Control Register 0	0x00,   // Pedestal Control Register 1};static unsigned char NTSC_config_7175[16] = {	0x04,   // Mode Register 0	0x00,   // Mode Register 1	0x16,   // Subcarrier Frequency Register 0	0x7c, 	// Subcarrier Frequency Register 1	0xf0, 	// Subcarrier Frequency Register 2	0x21,  	// Subcarrier Frequency Register 3	0x00,   // Subcarrier Phase Register	0x0d,   // Timing Register 0	0x00,   // Closed Captioning Ext Register 0	0x00,   // Closed Captioning Ext Register 1	0x00,   // Closed Captioning Register 0	0x00,   // Closed Captioning Register 1	0x77,  	// Timing Register 1	0x00, 	// Mode Register 2	0x00,   // Pedestal Control Register 0	0x00,   // Pedestal Control Register 1};static int adv717x_update(struct i2c_client *client){	struct adv717x_data_s *data = client->data ;	char tmpconfig[32];	int n,i;	memcpy(tmpconfig, data->config, data->configlen);	tmpconfig[1] |= data->bars ? 0x80:0;	switch(data->chiptype) {	case CHIP_ADV7175A:		if (data->rgbmode) {			tmpconfig[0] |= 0x40;		}		break;	case CHIP_ADV7170:		if (data->rgbmode) {			tmpconfig[3] |= 0x10;		}		break;	}		if (!data->enableoutput) {		tmpconfig[1] |= 0x7f;	}		for(i=0; i < data->configlen; i++) {		n=i2c_smbus_write_byte_data(client,i,tmpconfig[i]);	}	i2c_smbus_write_byte_data(client,7, tmpconfig[7] & 0x7f);	i2c_smbus_write_byte_data(client,7, tmpconfig[7] | 0x80);	i2c_smbus_write_byte_data(client,7, tmpconfig[7] & 0x7f);	return 0;}static int adv717x_setmode(int mode, struct i2c_client *client) {	struct adv717x_data_s *data = client->data ;	unsigned char *config=NULL;	pr_debug("adv717x_setmode(%d,%p)\n", mode, client);		switch(mode) {	case ENCODER_MODE_PAL:		printk(KERN_NOTICE "adv717x.o: Configuring for PAL\n");		switch (data->chiptype) {		case CHIP_ADV7175A:			config = PAL_config_7175;			data->configlen = sizeof(PAL_config_7175);			break;		case CHIP_ADV7170:			config = PAL_config_7170;			data->configlen = sizeof(PAL_config_7170);			break;		}		break;	case ENCODER_MODE_PAL_M:		printk(KERN_NOTICE "adv717x.o: Configuring for PALM\n");		switch (data->chiptype) {		case CHIP_ADV7175A:			config = PAL_config_7175;			data->configlen = sizeof(PAL_M_config_7175);			break;		case CHIP_ADV7170:			config = PAL_config_7170;			data->configlen = sizeof(PAL_config_7170);			break;		}		break;	case ENCODER_MODE_PAL60:		printk(KERN_NOTICE "adv717x.o: Configuring for PAL 60\n");		switch (data->chiptype) {		case CHIP_ADV7175A:			config = PAL60_config_7175;			data->configlen = sizeof(PAL60_config_7175);			break;		case CHIP_ADV7170:			config = PAL_config_7170;			data->configlen = sizeof(PAL_config_7170);			break;		}		break;	case ENCODER_MODE_NTSC:		printk(KERN_NOTICE "adv717x.o: Configuring for NTSC\n");	 	switch (data->chiptype) {		case CHIP_ADV7175A:			config = NTSC_config_7175;			data->configlen = sizeof(NTSC_config_7175);			break;		case CHIP_ADV7170:			config = NTSC_config_7170;			data->configlen = sizeof(NTSC_config_7170);			break;		}		break;	default:		return -1;	}	data->mode = mode;	if (config) {		memcpy(data->config, config, data->configlen);	}	return 0;}static int adv717x_setup(struct i2c_client *client){	struct adv717x_data_s *data = client->data ;		memset(data->config, 0, sizeof(data->config));	data->bars=0;	data->rgbmode=0;	data->enableoutput=0;	adv717x_setmode(ENCODER_MODE_PAL60, client);		adv717x_update(client);		return 0;}static int adv717x_detect(struct i2c_adapter *adapter, int address){	struct adv717x_data_s *data;	struct i2c_client *new_client;	int mr0,mr1;	int err;	if (i2c_is_isa_adapter(adapter)) {		printk(KERN_ERR "adv717xa.o: called for an ISA bus adapter?!?\n");		return 0;	}	if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {		return 0;	}	 	 	if (!(new_client = kmalloc(sizeof(struct i2c_client) + sizeof(struct adv717x_data_s), GFP_KERNEL))) {		return -ENOMEM;	}	data = (struct adv717x_data_s *) (((struct i2c_client *) new_client) + 1);	new_client->addr = address;	new_client->data = data;	new_client->adapter = adapter;	new_client->driver = &adv717x_driver;	new_client->flags = 0;	i2c_smbus_write_byte_data(new_client, ADV7175_REG_MR1,0x55);	mr1=i2c_smbus_read_byte_data(new_client, ADV7175_REG_MR1);	 	if (mr1 == 0x55) {		mr0=i2c_smbus_read_byte_data(new_client, ADV7175_REG_MR0);		if (mr0 & 0x20) {			strcpy(new_client->name, "ADV7175A chip");			data->chiptype = CHIP_ADV7175A;			printk(KERN_NOTICE "adv717x.o: ADV7175A chip detected\n");		} else {			strcpy(new_client->name, "ADV7170 chip");			data->chiptype = CHIP_ADV7170;			printk(KERN_NOTICE "adv717x.o: ADV7170 chip detected\n");		}	 		new_client->id = adv717x_id++;		if ((err = i2c_attach_client(new_client))) {			kfree(new_client);			return err;		}		adv717x_setup(new_client);		return 0;	} 	kfree(new_client);	return 0;			  }static int adv717x_attach_adapter(struct i2c_adapter *adapter){	adv717x_detect(adapter,0x6a);	adv717x_detect(adapter,0x7a);	adv717x_detect(adapter,0xa);	return 0;}int adv717x_detach_client(struct i2c_client *client){	int err;	if ((err = i2c_detach_client(client))) {		printk(KERN_ERR "adv717x.o: Client deregistration failed, client not detached.\n");		return err;	}	kfree(client);	return 0;}int adv717x_command(struct i2c_client *client, unsigned int cmd, void *arg){	struct adv717x_data_s *data = client->data ;	switch(cmd) {	case ENCODER_CMD_SETMODE:		adv717x_setmode((int)arg, client);		adv717x_update(client);		break;	case ENCODER_CMD_ENABLEOUTPUT:		data->enableoutput = (int)arg;		adv717x_update(client);		break;	default:	}	return 0;}/* Nothing here yet */void adv717x_inc_use (struct i2c_client *client){#ifdef MODULE	MOD_INC_USE_COUNT;#endif}/* Nothing here yet */void adv717x_dec_use (struct i2c_client *client){#ifdef MODULE	MOD_DEC_USE_COUNT;#endif}/* ----------------------------------------------------------------------- */#ifdef MODULEint init_module(void)#elseint adv717x_init(void)#endif{	int pp_ntsc;	int pp_pal;	int rb_pal;	int bars;	if (pixelport_16bit) {		pp_ntsc = pp_pal = 0x40;		if (pixelport_other_pal) {			pp_pal = 0x00;		}	} else {		pp_ntsc = pp_pal = 0x00;		if (pixelport_other_pal) {			pp_pal = 0x40;		}	}	if (swap_redblue_pal) {		rb_pal = 0xA0;	} else {		rb_pal = 0x70;	}	if( color_bars ) {		bars = 0x80;	} else {		bars = 0x00;	}	pr_debug("adv717x.o: pixelport_16bit: %d\n", pixelport_16bit);	pr_debug("adv717x.o: pixelport_other_pal: %d\n", pixelport_other_pal);	pr_debug("adv717x.o: color_bars: %d\n", color_bars);	PAL_config_7170[7] = (PAL_config_7170[7] & ~0x40) | pp_pal;	NTSC_config_7170[7] = (NTSC_config_7170[7] & ~0x40) | pp_ntsc;	PAL_M_config_7175[7] = (PAL_M_config_7175[7] & ~0x40) | pp_pal;	PAL_config_7175[7] = (PAL_config_7175[7] & ~0x40) | pp_pal;	PAL60_config_7175[7] = (PAL60_config_7175[7] & ~0x40) | pp_pal;	NTSC_config_7175[7] = (NTSC_config_7175[7] & ~0x40) | pp_ntsc;	PAL_config_7175[12] = (PAL_config_7175[12] & ~0xF0) | rb_pal;	PAL60_config_7175[12] = (PAL60_config_7175[12] & ~0xF0) | rb_pal;	NTSC_config_7175[12] = (NTSC_config_7175[12] & ~0xF0) | rb_pal;	PAL_config_7170[1] = (PAL_config_7170[1] & ~0x80) | bars;	NTSC_config_7170[1] = (NTSC_config_7170[1] & ~0x80) | bars;	PAL_M_config_7175[1] = (PAL_M_config_7175[1] & ~0x80) | bars;	PAL_config_7175[1] = (PAL_config_7175[1] & ~0x80) | bars;	PAL60_config_7175[1] = (PAL60_config_7175[1] & ~0x80) | bars;	NTSC_config_7175[1] = (NTSC_config_7175[1] & ~0x80) | bars;	return i2c_add_driver(&adv717x_driver);}#ifdef MODULEvoid cleanup_module(void){	i2c_del_driver(&adv717x_driver);}#endif

⌨️ 快捷键说明

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