X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Ftvaudio.c;h=540a6b1461f7f08c320515abd870c6598f3aacca;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=b435bcef92607adcd253c025b024a7a532807bc5;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index b435bcef9..540a6b146 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -3,12 +3,12 @@ * * Copyright (c) 2000 Gerd Knorr * based on code by: - * Eric Sandeen (eric_sandeen@bigfoot.com) + * Eric Sandeen (eric_sandeen@bigfoot.com) * Steve VanDeBogart (vandebo@uclink.berkeley.edu) * Greg Alexander (galexand@acm.org) * * This code is placed under the terms of the GNU General Public License - * + * * OPTIONS: * debug - set to 1 if you'd like to see debug messages * @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -37,8 +38,8 @@ /* ---------------------------------------------------------------------- */ /* insmod args */ -MODULE_PARM(debug,"i"); static int debug = 0; /* insmod parameter */ +module_param(debug, int, 0644); MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips"); MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr"); @@ -207,7 +208,7 @@ static int chip_read(struct CHIPSTATE *chip) i2c_clientname(&chip->c)); return -1; } - dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer); + dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer); return buffer; } @@ -227,14 +228,14 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) return -1; } dprintk("%s: chip_read2: reg%d=0x%x\n", - i2c_clientname(&chip->c),subaddr,read[0]); + i2c_clientname(&chip->c),subaddr,read[0]); return read[0]; } static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) { int i; - + if (0 == cmd->count) return 0; @@ -273,7 +274,7 @@ static int chip_thread(void *data) DECLARE_WAITQUEUE(wait, current); struct CHIPSTATE *chip = data; struct CHIPDESC *desc = chiplist + chip->type; - + daemonize("%s",i2c_clientname(&chip->c)); allow_signal(SIGTERM); dprintk("%s: thread started\n", i2c_clientname(&chip->c)); @@ -292,10 +293,10 @@ static int chip_thread(void *data) /* don't do anything for radio or if mode != auto */ if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0) continue; - + /* have a look what's going on */ desc->checkmode(chip); - + /* schedule next check */ mod_timer(&chip->wt, jiffies+2*HZ); } @@ -352,14 +353,14 @@ static void generic_checkmode(struct CHIPSTATE *chip) static int tda9840_getmode(struct CHIPSTATE *chip) { int val, mode; - + val = chip_read(chip); mode = VIDEO_SOUND_MONO; if (val & TDA9840_DS_DUAL) mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; if (val & TDA9840_ST_STEREO) mode |= VIDEO_SOUND_STEREO; - + dprintk ("tda9840_getmode(): raw chip read: %d, return: %d\n", val, mode); return mode; @@ -369,7 +370,7 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) { int update = 1; int t = chip->shadow.bytes[TDA9840_SW + 1] & ~0x7e; - + switch (mode) { case VIDEO_SOUND_MONO: t |= TDA9840_MONO; @@ -419,7 +420,7 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) * in 1dB steps - mute is 0x27 */ -/* 0x02 - BA in TDA9855 */ +/* 0x02 - BA in TDA9855 */ /* lower 5 bits control bass gain from -12dB (0x06) to 16.5dB (0x19) * in .5dB steps - 0 is 0x0E */ @@ -433,7 +434,7 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) /* Unique to TDA9855: */ /* 4 bits << 2 control subwoofer/surround gain from -14db (0x1) to 14db (0xf) * in 3dB steps - mute is 0x0 */ - + /* Unique to TDA9850: */ /* lower 4 bits control stereo noise threshold, over which stereo turns off * set to values of 0x00 through 0x0f for Ster1 through Ster16 */ @@ -446,7 +447,7 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) #define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ #define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ /* Bits 0 to 3 select various combinations - * of line in and line out, only the + * of line in and line out, only the * interesting ones are defined */ #define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ #define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ @@ -499,7 +500,7 @@ static int tda985x_getmode(struct CHIPSTATE *chip) { int mode; - mode = ((TDA985x_STP | TDA985x_SAPP) & + mode = ((TDA985x_STP | TDA985x_SAPP) & chip_read(chip)) >> 4; /* Add mono mode regardless of SAP and stereo */ /* Allows forced mono */ @@ -510,7 +511,7 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode) { int update = 1; int c6 = chip->shadow.bytes[TDA985x_C6+1] & 0x3f; - + switch (mode) { case VIDEO_SOUND_MONO: c6 |= TDA985x_MONO; @@ -538,7 +539,7 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode) #define TDA9873_AD 0x01 /* Adjust */ #define TDA9873_PT 0x02 /* Port */ -/* Subaddress 0x00: Switching Data +/* Subaddress 0x00: Switching Data * B7..B0: * * B1, B0: Input source selection @@ -552,10 +553,10 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode) #define TDA9873_EXT_MONO 1 /* B3, B2: output signal select - * B4 : transmission mode + * B4 : transmission mode * 0, 0, 1 Mono * 1, 0, 0 Stereo - * 1, 1, 1 Stereo (reversed channel) + * 1, 1, 1 Stereo (reversed channel) * 0, 0, 0 Dual AB * 0, 0, 1 Dual AA * 0, 1, 0 Dual BB @@ -587,7 +588,7 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode) #define TDA9873_STEREO_ADJ 0x06 /* 0dB gain */ -/* Bits C6..C4 control FM stantard +/* Bits C6..C4 control FM stantard * C6, C5, C4 * 0, 0, 0 B/G (PAL FM) * 0, 0, 1 M @@ -609,7 +610,7 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode) #define TDA9873_IDR_FAST 1 << 7 -/* Subaddress 0x02: Port data */ +/* Subaddress 0x02: Port data */ /* E1, E0 free programmable ports P1/P2 0, 0 both ports low @@ -632,11 +633,11 @@ static void tda985x_setmode(struct CHIPSTATE *chip, int mode) */ #define TDA9873_MOUT_MONO 0 #define TDA9873_MOUT_FMONO 0 -#define TDA9873_MOUT_DUALA 0 -#define TDA9873_MOUT_DUALB 1 << 3 -#define TDA9873_MOUT_ST 1 << 4 +#define TDA9873_MOUT_DUALA 0 +#define TDA9873_MOUT_DUALB 1 << 3 +#define TDA9873_MOUT_ST 1 << 4 #define TDA9873_MOUT_EXTM (1 << 4 ) & (1 << 3) -#define TDA9873_MOUT_EXTL 1 << 5 +#define TDA9873_MOUT_EXTL 1 << 5 #define TDA9873_MOUT_EXTR (1 << 5 ) & (1 << 3) #define TDA9873_MOUT_EXTLR (1 << 5 ) & (1 << 4) #define TDA9873_MOUT_MUTE (1 << 5 ) & (1 << 4) & (1 << 3) @@ -670,13 +671,13 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode) dprintk("tda9873_setmode(): external input\n"); return; } - + dprintk("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); dprintk("tda9873_setmode(): sw_data = %d\n", sw_data); switch (mode) { case VIDEO_SOUND_MONO: - sw_data |= TDA9873_TR_MONO; + sw_data |= TDA9873_TR_MONO; break; case VIDEO_SOUND_STEREO: sw_data |= TDA9873_TR_STEREO; @@ -764,9 +765,9 @@ static int tda9874a_dic = -1; /* device id. code */ static unsigned int tda9874a_SIF = UNSET; static unsigned int tda9874a_AMSEL = UNSET; static unsigned int tda9874a_STD = UNSET; -MODULE_PARM(tda9874a_SIF,"i"); -MODULE_PARM(tda9874a_AMSEL,"i"); -MODULE_PARM(tda9874a_STD,"i"); +module_param(tda9874a_SIF, int, 0444); +module_param(tda9874a_AMSEL, int, 0444); +module_param(tda9874a_STD, int, 0444); /* * initialization table for tda9874 decoder: @@ -871,7 +872,7 @@ static int tda9874a_getmode(struct CHIPSTATE *chip) if(nsr & 0x02) /* NSR.S/MB=1 */ mode |= VIDEO_SOUND_STEREO; #endif - if(nsr & 0x01) /* NSR.D/SB=1 */ + if(nsr & 0x01) /* NSR.D/SB=1 */ mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; } else { if(dsr & 0x02) /* DSR.IDSTE=1 */ @@ -1027,6 +1028,21 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) #define TEA6300_S_SC 0x04 /* stereo C */ #define TEA6300_S_GMU 0x80 /* general mute */ +#define TEA6320_V 0x00 /* volume (0-5)/loudness off (6)/zero crossing mute(7) */ +#define TEA6320_FFR 0x01 /* fader front right (0-5) */ +#define TEA6320_FFL 0x02 /* fader front left (0-5) */ +#define TEA6320_FRR 0x03 /* fader rear right (0-5) */ +#define TEA6320_FRL 0x04 /* fader rear left (0-5) */ +#define TEA6320_BA 0x05 /* bass (0-4) */ +#define TEA6320_TR 0x06 /* treble (0-4) */ +#define TEA6320_S 0x07 /* switch register */ + /* values for those registers: */ +#define TEA6320_S_SA 0x07 /* stereo A input */ +#define TEA6320_S_SB 0x06 /* stereo B */ +#define TEA6320_S_SC 0x05 /* stereo C */ +#define TEA6320_S_SD 0x04 /* stereo D */ +#define TEA6320_S_GMU 0x80 /* general mute */ + #define TEA6420_S_SA 0x00 /* stereo A input */ #define TEA6420_S_SB 0x01 /* stereo B */ #define TEA6420_S_SC 0x02 /* stereo C */ @@ -1037,6 +1053,20 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) static int tea6300_shift10(int val) { return val >> 10; } static int tea6300_shift12(int val) { return val >> 12; } +/* Assumes 16bit input (values 0x3f to 0x0c are unique, values less than */ +/* 0x0c mirror those immediately higher) */ +static int tea6320_volume(int val) { return (val / (65535/(63-12)) + 12) & 0x3f; } +static int tea6320_shift11(int val) { return val >> 11; } +static int tea6320_initialize(struct CHIPSTATE * chip) +{ + chip_write(chip, TEA6320_FFR, 0x3f); + chip_write(chip, TEA6320_FFL, 0x3f); + chip_write(chip, TEA6320_FRR, 0x3f); + chip_write(chip, TEA6320_FRL, 0x3f); + + return 0; +} + /* ---------------------------------------------------------------------- */ /* audio chip descriptions - defines+functions for tda8425 */ @@ -1082,7 +1112,7 @@ static int tda8425_initialize(struct CHIPSTATE *chip) static void tda8425_setmode(struct CHIPSTATE *chip, int mode) { int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1; - + if (mode & VIDEO_SOUND_LANG1) { s1 |= TDA8425_S1_ML_SOUND_A; s1 |= TDA8425_S1_STEREO_PSEUDO; @@ -1090,10 +1120,10 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode) } else if (mode & VIDEO_SOUND_LANG2) { s1 |= TDA8425_S1_ML_SOUND_B; s1 |= TDA8425_S1_STEREO_PSEUDO; - + } else { s1 |= TDA8425_S1_ML_STEREO; - + if (mode & VIDEO_SOUND_MONO) s1 |= TDA8425_S1_STEREO_MONO; if (mode & VIDEO_SOUND_STEREO) @@ -1152,7 +1182,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode) static int ta8874z_getmode(struct CHIPSTATE *chip) { int val, mode; - + val = chip_read(chip); mode = VIDEO_SOUND_MONO; if (val & TA8874Z_B1){ @@ -1214,20 +1244,22 @@ int tda9855 = 1; int tda9873 = 1; int tda9874a = 1; int tea6300 = 0; // address clash with msp34xx +int tea6320 = 0; // address clash with msp34xx int tea6420 = 1; int pic16c54 = 1; int ta8874z = 0; // address clash with tda9840 -MODULE_PARM(tda8425,"i"); -MODULE_PARM(tda9840,"i"); -MODULE_PARM(tda9850,"i"); -MODULE_PARM(tda9855,"i"); -MODULE_PARM(tda9873,"i"); -MODULE_PARM(tda9874a,"i"); -MODULE_PARM(tea6300,"i"); -MODULE_PARM(tea6420,"i"); -MODULE_PARM(pic16c54,"i"); -MODULE_PARM(ta8874z,"i"); +module_param(tda8425, int, 0444); +module_param(tda9840, int, 0444); +module_param(tda9850, int, 0444); +module_param(tda9855, int, 0444); +module_param(tda9873, int, 0444); +module_param(tda9874a, int, 0444); +module_param(tea6300, int, 0444); +module_param(tea6320, int, 0444); +module_param(tea6420, int, 0444); +module_param(pic16c54, int, 0444); +module_param(ta8874z, int, 0444); static struct CHIPDESC chiplist[] = { { @@ -1264,7 +1296,7 @@ static struct CHIPDESC chiplist[] = { .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE, .inputmap = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0}, .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE, - + }, { .name = "tda9874h/a", @@ -1338,6 +1370,28 @@ static struct CHIPDESC chiplist[] = { .inputmap = { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC }, .inputmute = TEA6300_S_GMU, }, + { + .name = "tea6320", + .id = I2C_DRIVERID_TEA6300, + .initialize = tea6320_initialize, + .insmodopt = &tea6320, + .addr_lo = I2C_TEA6300 >> 1, + .addr_hi = I2C_TEA6300 >> 1, + .registers = 8, + .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, + + .leftreg = TEA6320_V, + .rightreg = TEA6320_V, + .bassreg = TEA6320_BA, + .treblereg = TEA6320_TR, + .volfunc = tea6320_volume, + .bassfunc = tea6320_shift11, + .treblefunc = tea6320_shift11, + + .inputreg = TEA6320_S, + .inputmap = { TEA6320_S_SA, TEA6420_S_SB, TEA6300_S_SC, TEA6320_S_SD }, + .inputmute = TEA6300_S_GMU, + }, { .name = "tea6420", .id = I2C_DRIVERID_TEA6420, @@ -1497,6 +1551,10 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) static int chip_probe(struct i2c_adapter *adap) { + /* don't attach on saa7146 based cards, + because dedicated drivers are used */ + if ((adap->id & I2C_ALGO_SAA7146)) + return 0; #ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, chip_attach); @@ -1522,7 +1580,7 @@ static int chip_detach(struct i2c_client *client) wake_up_interruptible(&chip->wq); wait_for_completion(&chip->texit); } - + i2c_detach_client(&chip->c); kfree(chip); return 0; @@ -1567,8 +1625,11 @@ static int chip_command(struct i2c_client *client, if (desc->flags & CHIP_HAS_VOLUME) { va->flags |= VIDEO_AUDIO_VOLUME; va->volume = max(chip->left,chip->right); - va->balance = (32768*min(chip->left,chip->right))/ - (va->volume ? va->volume : 1); + if (va->volume) + va->balance = (32768*min(chip->left,chip->right))/ + va->volume; + else + va->balance = 32768; } if (desc->flags & CHIP_HAS_BASSTREBLE) { va->flags |= VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; @@ -1587,7 +1648,7 @@ static int chip_command(struct i2c_client *client, case VIDIOCSAUDIO: { struct video_audio *va = arg; - + if (desc->flags & CHIP_HAS_VOLUME) { chip->left = (min(65536 - va->balance,32768) * va->volume) / 32768; @@ -1613,7 +1674,7 @@ static int chip_command(struct i2c_client *client, case VIDIOCSCHAN: { struct video_channel *vc = arg; - + dprintk(KERN_DEBUG "tvaudio: VIDIOCSCHAN\n"); chip->norm = vc->norm; break;