vserver 1.9.5.x5
[linux-2.6.git] / drivers / media / video / tvaudio.c
index b435bce..540a6b1 100644 (file)
@@ -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 <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -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;