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

📄 saa7115.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	0x02, 0x84,		/* input tuner -> input 4, amplifier active */	0x09, 0x53,		/* 0x53, was 0x56 for 60hz. luminance control */	0x80, 0x20,		/* enable task B */	0x88, 0xd0,	0x88, 0xf0,	0x00, 0x00};/* ============== SAA7715 AUDIO settings ============= *//* 48.0 kHz */static const unsigned char saa7115_cfg_48_audio[] = {	0x34, 0xce,	0x35, 0xfb,	0x36, 0x30,	0x00, 0x00};/* 44.1 kHz */static const unsigned char saa7115_cfg_441_audio[] = {	0x34, 0xf2,	0x35, 0x00,	0x36, 0x2d,	0x00, 0x00};/* 32.0 kHz */static const unsigned char saa7115_cfg_32_audio[] = {	0x34, 0xdf,	0x35, 0xa7,	0x36, 0x20,	0x00, 0x00};/* 48.0 kHz 60hz */static const unsigned char saa7115_cfg_60hz_48_audio[] = {	0x30, 0xcd,	0x31, 0x20,	0x32, 0x03,	0x00, 0x00};/* 48.0 kHz 50hz */static const unsigned char saa7115_cfg_50hz_48_audio[] = {	0x30, 0x00,	0x31, 0xc0,	0x32, 0x03,	0x00, 0x00};/* 44.1 kHz 60hz */static const unsigned char saa7115_cfg_60hz_441_audio[] = {	0x30, 0xbc,	0x31, 0xdf,	0x32, 0x02,	0x00, 0x00};/* 44.1 kHz 50hz */static const unsigned char saa7115_cfg_50hz_441_audio[] = {	0x30, 0x00,	0x31, 0x72,	0x32, 0x03,	0x00, 0x00};/* 32.0 kHz 60hz */static const unsigned char saa7115_cfg_60hz_32_audio[] = {	0x30, 0xde,	0x31, 0x15,	0x32, 0x02,	0x00, 0x00};/* 32.0 kHz 50hz */static const unsigned char saa7115_cfg_50hz_32_audio[] = {	0x30, 0x00,	0x31, 0x80,	0x32, 0x02,	0x00, 0x00};static int saa7115_odd_parity(u8 c){	c ^= (c >> 4);	c ^= (c >> 2);	c ^= (c >> 1);	return c & 1;}static int saa7115_decode_vps(u8 * dst, u8 * p){	static const u8 biphase_tbl[] = {		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,		0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,		0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,		0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,		0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,		0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,		0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,		0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,		0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,		0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,		0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,		0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,		0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,		0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,		0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,		0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,		0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,		0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,		0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,		0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,		0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,		0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,		0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,		0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,		0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,	};	int i;	u8 c, err = 0;	for (i = 0; i < 2 * 13; i += 2) {		err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];		c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);		dst[i / 2] = c;	}	return err & 0xf0;}static int saa7115_decode_wss(u8 * p){	static const int wss_bits[8] = {		0, 0, 0, 1, 0, 1, 1, 1	};	unsigned char parity;	int wss = 0;	int i;	for (i = 0; i < 16; i++) {		int b1 = wss_bits[p[i] & 7];		int b2 = wss_bits[(p[i] >> 3) & 7];		if (b1 == b2)			return -1;		wss |= b2 << i;	}	parity = wss & 15;	parity ^= parity >> 2;	parity ^= parity >> 1;	if (!(parity & 1))		return -1;	return wss;}static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq){	struct saa7115_state *state = i2c_get_clientdata(client);	saa7115_dbg("set audio clock freq: %d\n", freq);	switch (freq) {		case V4L2_AUDCLK_32_KHZ:			saa7115_writeregs(client, saa7115_cfg_32_audio);			if (state->std & V4L2_STD_525_60) {				saa7115_writeregs(client, saa7115_cfg_60hz_32_audio);			} else {				saa7115_writeregs(client, saa7115_cfg_50hz_32_audio);			}			break;		case V4L2_AUDCLK_441_KHZ:			saa7115_writeregs(client, saa7115_cfg_441_audio);			if (state->std & V4L2_STD_525_60) {				saa7115_writeregs(client, saa7115_cfg_60hz_441_audio);			} else {				saa7115_writeregs(client, saa7115_cfg_50hz_441_audio);			}			break;		case V4L2_AUDCLK_48_KHZ:			saa7115_writeregs(client, saa7115_cfg_48_audio);			if (state->std & V4L2_STD_525_60) {				saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);			} else {				saa7115_writeregs(client, saa7115_cfg_50hz_48_audio);			}			break;		default:			saa7115_dbg("invalid audio setting %d\n", freq);			return -EINVAL;	}	state->audclk_freq = freq;	return 0;}static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl){	struct saa7115_state *state = i2c_get_clientdata(client);	switch (ctrl->id) {	case V4L2_CID_BRIGHTNESS:		if (ctrl->value < 0 || ctrl->value > 255) {			saa7115_err("invalid brightness setting %d\n", ctrl->value);			return -ERANGE;		}		state->bright = ctrl->value;		saa7115_write(client, 0x0a, state->bright);		break;	case V4L2_CID_CONTRAST:		if (ctrl->value < 0 || ctrl->value > 127) {			saa7115_err("invalid contrast setting %d\n", ctrl->value);			return -ERANGE;		}		state->contrast = ctrl->value;		saa7115_write(client, 0x0b, state->contrast);		break;	case V4L2_CID_SATURATION:		if (ctrl->value < 0 || ctrl->value > 127) {			saa7115_err("invalid saturation setting %d\n", ctrl->value);			return -ERANGE;		}		state->sat = ctrl->value;		saa7115_write(client, 0x0c, state->sat);		break;	case V4L2_CID_HUE:		if (ctrl->value < -127 || ctrl->value > 127) {			saa7115_err("invalid hue setting %d\n", ctrl->value);			return -ERANGE;		}		state->hue = ctrl->value;		saa7115_write(client, 0x0d, state->hue);		break;	}	return 0;}static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl){	struct saa7115_state *state = i2c_get_clientdata(client);	switch (ctrl->id) {	case V4L2_CID_BRIGHTNESS:		ctrl->value = state->bright;		break;	case V4L2_CID_CONTRAST:		ctrl->value = state->contrast;		break;	case V4L2_CID_SATURATION:		ctrl->value = state->sat;		break;	case V4L2_CID_HUE:		ctrl->value = state->hue;		break;	default:		return -EINVAL;	}	return 0;}static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std){	struct saa7115_state *state = i2c_get_clientdata(client);	int taskb = saa7115_read(client, 0x80) & 0x10;	// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.	if (std & V4L2_STD_525_60) {		saa7115_dbg("decoder set standard 60 Hz\n");		saa7115_writeregs(client, saa7115_cfg_60hz_video);	} else {		saa7115_dbg("decoder set standard 50 Hz\n");		saa7115_writeregs(client, saa7115_cfg_50hz_video);	}	state->std = std;	/* restart task B if needed */	if (taskb && state->ident == V4L2_IDENT_SAA7114) {		saa7115_writeregs(client, saa7115_cfg_vbi_on);	}	/* switch audio mode too! */	saa7115_set_audio_clock_freq(client, state->audclk_freq);}static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client){	struct saa7115_state *state = i2c_get_clientdata(client);	return state->std;}static void saa7115_log_status(struct i2c_client *client){	struct saa7115_state *state = i2c_get_clientdata(client);	char *audfreq = "undefined";	int reg1e, reg1f;	int signalOk;	int vcr;	switch (state->audclk_freq) {		case V4L2_AUDCLK_32_KHZ:  audfreq = "32 kHz"; break;		case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break;		case V4L2_AUDCLK_48_KHZ:  audfreq = "48 kHz"; break;	}	saa7115_info("Audio frequency: %s\n", audfreq);	if (client->name[6] == '4') {		/* status for the saa7114 */		reg1f = saa7115_read(client, 0x1f);		signalOk = (reg1f & 0xc1) == 0x81;		saa7115_info("Video signal:    %s\n", signalOk ? "ok" : "bad");		saa7115_info("Frequency:       %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");		return;	}	/* status for the saa7115 */	reg1e = saa7115_read(client, 0x1e);	reg1f = saa7115_read(client, 0x1f);	signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;	vcr = !(reg1f & 0x10);	saa7115_info("Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");	saa7115_info("Frequency:       %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");	switch (reg1e & 0x03) {		case 1:			saa7115_info("Detected format: NTSC\n");			break;		case 2:			saa7115_info("Detected format: PAL\n");			break;		case 3:			saa7115_info("Detected format: SECAM\n");			break;		default:			saa7115_info("Detected format: BW/No color\n");			break;	}}/* setup the sliced VBI lcr registers according to the sliced VBI format */static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt){	struct saa7115_state *state = i2c_get_clientdata(client);	int is_50hz = (state->std & V4L2_STD_625_50);	u8 lcr[24];	int i, x;	/* saa7114 doesn't yet support VBI */	if (state->ident == V4L2_IDENT_SAA7114)		return;	for (i = 0; i <= 23; i++)		lcr[i] = 0xff;	if (fmt->service_set == 0) {		/* raw VBI */		if (is_50hz)			for (i = 6; i <= 23; i++)				lcr[i] = 0xdd;		else			for (i = 10; i <= 21; i++)				lcr[i] = 0xdd;	} else {		/* sliced VBI */		/* first clear lines that cannot be captured */		if (is_50hz) {			for (i = 0; i <= 5; i++)				fmt->service_lines[0][i] =					fmt->service_lines[1][i] = 0;		}		else {			for (i = 0; i <= 9; i++)				fmt->service_lines[0][i] =					fmt->service_lines[1][i] = 0;			for (i = 22; i <= 23; i++)				fmt->service_lines[0][i] =					fmt->service_lines[1][i] = 0;		}		/* Now set the lcr values according to the specified service */		for (i = 6; i <= 23; i++) {			lcr[i] = 0;			for (x = 0; x <= 1; x++) {				switch (fmt->service_lines[1-x][i]) {					case 0:						lcr[i] |= 0xf << (4 * x);						break;					case V4L2_SLICED_TELETEXT_B:						lcr[i] |= 1 << (4 * x);						break;					case V4L2_SLICED_CAPTION_525:						lcr[i] |= 4 << (4 * x);						break;					case V4L2_SLICED_WSS_625:						lcr[i] |= 5 << (4 * x);						break;					case V4L2_SLICED_VPS:						lcr[i] |= 7 << (4 * x);						break;				}			}		}	}	/* write the lcr registers */	for (i = 2; i <= 23; i++) {		saa7115_write(client, i - 2 + 0x41, lcr[i]);	}	/* enable/disable raw VBI capturing */	saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off);}static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt){	static u16 lcr2vbi[] = {		0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */		0, V4L2_SLICED_CAPTION_525,	/* 4 */		V4L2_SLICED_WSS_625, 0,		/* 5 */		V4L2_SLICED_VPS, 0, 0, 0, 0,	/* 7 */		0, 0, 0, 0	};	struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;	int i;	if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)		return -EINVAL;	memset(sliced, 0, sizeof(*sliced));	/* done if using raw VBI */	if (saa7115_read(client, 0x80) & 0x10)		return 0;	for (i = 2; i <= 23; i++) {		u8 v = saa7115_read(client, i - 2 + 0x41);		sliced->service_lines[0][i] = lcr2vbi[v >> 4];		sliced->service_lines[1][i] = lcr2vbi[v & 0xf];		sliced->service_set |=			sliced->service_lines[0][i] | sliced->service_lines[1][i];

⌨️ 快捷键说明

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