tda9887.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 718 行 · 第 1/2 页

C
718
字号
#include <linux/module.h>#include <linux/kernel.h>#include <linux/i2c.h>#include <linux/types.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/videodev2.h>#include <media/v4l2-common.h>#include <media/tuner.h>#include "tuner-i2c.h"#include "tda9887.h"#include "compat.h"/* Chips:   TDA9885 (PAL, NTSC)   TDA9886 (PAL, SECAM, NTSC)   TDA9887 (PAL, SECAM, NTSC, FM Radio)   Used as part of several tuners*/static int debug;module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "enable verbose debug messages");static DEFINE_MUTEX(tda9887_list_mutex);static LIST_HEAD(hybrid_tuner_instance_list);struct tda9887_priv {	struct tuner_i2c_props i2c_props;	struct list_head hybrid_tuner_instance_list;	unsigned char 	   data[4];	unsigned int       config;	unsigned int       mode;	unsigned int       audmode;	v4l2_std_id        std;};/* ---------------------------------------------------------------------- */#define UNSET       (-1U)struct tvnorm {	v4l2_std_id       std;	char              *name;	unsigned char     b;	unsigned char     c;	unsigned char     e;};/* ---------------------------------------------------------------------- *///// TDA defines////// first reg (b)#define cVideoTrapBypassOFF     0x00    // bit b0#define cVideoTrapBypassON      0x01    // bit b0#define cAutoMuteFmInactive     0x00    // bit b1#define cAutoMuteFmActive       0x02    // bit b1#define cIntercarrier           0x00    // bit b2#define cQSS                    0x04    // bit b2#define cPositiveAmTV           0x00    // bit b3:4#define cFmRadio                0x08    // bit b3:4#define cNegativeFmTV           0x10    // bit b3:4#define cForcedMuteAudioON      0x20    // bit b5#define cForcedMuteAudioOFF     0x00    // bit b5#define cOutputPort1Active      0x00    // bit b6#define cOutputPort1Inactive    0x40    // bit b6#define cOutputPort2Active      0x00    // bit b7#define cOutputPort2Inactive    0x80    // bit b7//// second reg (c)#define cDeemphasisOFF          0x00    // bit c5#define cDeemphasisON           0x20    // bit c5#define cDeemphasis75           0x00    // bit c6#define cDeemphasis50           0x40    // bit c6#define cAudioGain0             0x00    // bit c7#define cAudioGain6             0x80    // bit c7#define cTopMask                0x1f    // bit c0:4#define cTopDefault		0x10 	// bit c0:4//// third reg (e)#define cAudioIF_4_5             0x00    // bit e0:1#define cAudioIF_5_5             0x01    // bit e0:1#define cAudioIF_6_0             0x02    // bit e0:1#define cAudioIF_6_5             0x03    // bit e0:1#define cVideoIFMask		0x1c	// bit e2:4/* Video IF selection in TV Mode (bit B3=0) */#define cVideoIF_58_75           0x00    // bit e2:4#define cVideoIF_45_75           0x04    // bit e2:4#define cVideoIF_38_90           0x08    // bit e2:4#define cVideoIF_38_00           0x0C    // bit e2:4#define cVideoIF_33_90           0x10    // bit e2:4#define cVideoIF_33_40           0x14    // bit e2:4#define cRadioIF_45_75           0x18    // bit e2:4#define cRadioIF_38_90           0x1C    // bit e2:4/* IF1 selection in Radio Mode (bit B3=1) */#define cRadioIF_33_30		0x00	// bit e2,4 (also 0x10,0x14)#define cRadioIF_41_30		0x04	// bit e2,4/* Output of AFC pin in radio mode when bit E7=1 */#define cRadioAGC_SIF		0x00	// bit e3#define cRadioAGC_FM		0x08	// bit e3#define cTunerGainNormal         0x00    // bit e5#define cTunerGainLow            0x20    // bit e5#define cGating_18               0x00    // bit e6#define cGating_36               0x40    // bit e6#define cAgcOutON                0x80    // bit e7#define cAgcOutOFF               0x00    // bit e7/* ---------------------------------------------------------------------- */static struct tvnorm tvnorms[] = {	{		.std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,		.name  = "PAL-BGHN",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis50  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_5_5   |			   cVideoIF_38_90 ),	},{		.std   = V4L2_STD_PAL_I,		.name  = "PAL-I",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis50  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_6_0   |			   cVideoIF_38_90 ),	},{		.std   = V4L2_STD_PAL_DK,		.name  = "PAL-DK",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis50  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_6_5   |			   cVideoIF_38_90 ),	},{		.std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,		.name  = "PAL-M/Nc",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis75  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_4_5   |			   cVideoIF_45_75 ),	},{		.std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,		.name  = "SECAM-BGH",		.b     = ( cPositiveAmTV  |			   cQSS           ),		.c     = ( cTopDefault),		.e     = ( cGating_36	  |			   cAudioIF_5_5   |			   cVideoIF_38_90 ),	},{		.std   = V4L2_STD_SECAM_L,		.name  = "SECAM-L",		.b     = ( cPositiveAmTV  |			   cQSS           ),		.c     = ( cTopDefault),		.e     = ( cGating_36	  |			   cAudioIF_6_5   |			   cVideoIF_38_90 ),	},{		.std   = V4L2_STD_SECAM_LC,		.name  = "SECAM-L'",		.b     = ( cOutputPort2Inactive |			   cPositiveAmTV  |			   cQSS           ),		.c     = ( cTopDefault),		.e     = ( cGating_36	  |			   cAudioIF_6_5   |			   cVideoIF_33_90 ),	},{		.std   = V4L2_STD_SECAM_DK,		.name  = "SECAM-DK",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis50  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_6_5   |			   cVideoIF_38_90 ),	},{		.std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,		.name  = "NTSC-M",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis75  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_4_5   |			   cVideoIF_45_75 ),	},{		.std   = V4L2_STD_NTSC_M_JP,		.name  = "NTSC-M-JP",		.b     = ( cNegativeFmTV  |			   cQSS           ),		.c     = ( cDeemphasisON  |			   cDeemphasis50  |			   cTopDefault),		.e     = ( cGating_36     |			   cAudioIF_4_5   |			   cVideoIF_58_75 ),	}};static struct tvnorm radio_stereo = {	.name = "Radio Stereo",	.b    = ( cFmRadio       |		  cQSS           ),	.c    = ( cDeemphasisOFF |		  cAudioGain6    |		  cTopDefault),	.e    = ( cTunerGainLow  |		  cAudioIF_5_5   |		  cRadioIF_38_90 ),};static struct tvnorm radio_mono = {	.name = "Radio Mono",	.b    = ( cFmRadio       |		  cQSS           ),	.c    = ( cDeemphasisON  |		  cDeemphasis75  |		  cTopDefault),	.e    = ( cTunerGainLow  |		  cAudioIF_5_5   |		  cRadioIF_38_90 ),};/* ---------------------------------------------------------------------- */static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf){	struct tda9887_priv *priv = fe->analog_demod_priv;	static char *afc[16] = {		"- 12.5 kHz",		"- 37.5 kHz",		"- 62.5 kHz",		"- 87.5 kHz",		"-112.5 kHz",		"-137.5 kHz",		"-162.5 kHz",		"-187.5 kHz [min]",		"+187.5 kHz [max]",		"+162.5 kHz",		"+137.5 kHz",		"+112.5 kHz",		"+ 87.5 kHz",		"+ 62.5 kHz",		"+ 37.5 kHz",		"+ 12.5 kHz",	};	tuner_info("read: 0x%2x\n", buf[0]);	tuner_info("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");	tuner_info("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);	tuner_info("  fmif level     : %s\n", (buf[0] & 0x20) ? "high" : "low");	tuner_info("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");	tuner_info("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");}static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf){	struct tda9887_priv *priv = fe->analog_demod_priv;	static char *sound[4] = {		"AM/TV",		"FM/radio",		"FM/TV",		"FM/radio"	};	static char *adjust[32] = {		"-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",		"-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",		"0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",		"+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"	};	static char *deemph[4] = {		"no", "no", "75", "50"	};	static char *carrier[4] = {		"4.5 MHz",		"5.5 MHz",		"6.0 MHz",		"6.5 MHz / AM"	};	static char *vif[8] = {		"58.75 MHz",		"45.75 MHz",		"38.9 MHz",		"38.0 MHz",		"33.9 MHz",		"33.4 MHz",		"45.75 MHz + pin13",		"38.9 MHz + pin13",	};	static char *rif[4] = {		"44 MHz",		"52 MHz",		"52 MHz",		"44 MHz",	};	tuner_info("write: byte B 0x%02x\n", buf[1]);	tuner_info("  B0   video mode      : %s\n",		   (buf[1] & 0x01) ? "video trap" : "sound trap");	tuner_info("  B1   auto mute fm    : %s\n",		   (buf[1] & 0x02) ? "yes" : "no");	tuner_info("  B2   carrier mode    : %s\n",		   (buf[1] & 0x04) ? "QSS" : "Intercarrier");	tuner_info("  B3-4 tv sound/radio  : %s\n",		   sound[(buf[1] & 0x18) >> 3]);	tuner_info("  B5   force mute audio: %s\n",		   (buf[1] & 0x20) ? "yes" : "no");	tuner_info("  B6   output port 1   : %s\n",		   (buf[1] & 0x40) ? "high (inactive)" : "low (active)");	tuner_info("  B7   output port 2   : %s\n",		   (buf[1] & 0x80) ? "high (inactive)" : "low (active)");	tuner_info("write: byte C 0x%02x\n", buf[2]);

⌨️ 快捷键说明

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