patch-2.4.8 linux/drivers/media/video/tvaudio.c
Next file: linux/drivers/media/video/zr36067.c
Previous file: linux/drivers/media/video/tuner.h
Back to the patch index
Back to the overall index
- Lines: 201
- Date:
Sun Aug 5 13:15:05 2001
- Orig file:
v2.4.7/linux/drivers/media/video/tvaudio.c
- Orig date:
Tue May 1 16:05:00 2001
diff -u --recursive --new-file v2.4.7/linux/drivers/media/video/tvaudio.c linux/drivers/media/video/tvaudio.c
@@ -98,6 +98,7 @@
int inputreg;
int inputmap[8];
int inputmute;
+ int inputmask;
};
static struct CHIPDESC chiplist[];
@@ -113,7 +114,7 @@
/* current settings */
__u16 left,right,treble,bass,mode;
-
+ int prevmode;
/* thread */
struct task_struct *thread;
struct semaphore *notify;
@@ -124,7 +125,7 @@
/* ---------------------------------------------------------------------- */
-/* i2c addresses */
+/* i2c addresses */
static unsigned short normal_i2c[] = {
I2C_TDA8425 >> 1,
@@ -182,6 +183,18 @@
return 0;
}
+static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask)
+{
+ if (mask != 0) {
+ if (-1 == subaddr) {
+ val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
+ } else {
+ val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
+ }
+ }
+ return chip_write(chip, subaddr, val);
+}
+
static int chip_read(struct CHIPSTATE *chip)
{
unsigned char buffer;
@@ -283,7 +296,6 @@
continue;
/* have a look what's going on */
- dprintk("%s: thread checkmode\n", chip->c.name);
desc->checkmode(chip);
/* schedule next check */
@@ -303,10 +315,16 @@
struct CHIPDESC *desc = chiplist + chip->type;
int mode = desc->getmode(chip);
- if (mode & VIDEO_SOUND_STEREO)
- desc->setmode(chip,VIDEO_SOUND_STEREO);
- else if (mode & VIDEO_SOUND_LANG1)
+ if (mode == chip->prevmode)
+ return;
+
+ dprintk("%s: thread checkmode\n", chip->c.name);
+ chip->prevmode = mode;
+
+ if (mode & VIDEO_SOUND_LANG1)
desc->setmode(chip,VIDEO_SOUND_LANG1);
+ else if (mode & VIDEO_SOUND_STEREO)
+ desc->setmode(chip,VIDEO_SOUND_STEREO);
else
desc->setmode(chip,VIDEO_SOUND_MONO);
}
@@ -331,6 +349,9 @@
#define TDA9840_ST_STEREO 0x40 /* Stereo sound identified */
#define TDA9840_PONRES 0x80 /* Power-on reset detected if = 1 */
+#define TDA9840_TEST_INT1SN 0x1 /* Integration time 0.5s when set */
+#define TDA9840_TEST_INTFU 0x02 /* Disables integrator function */
+
int tda9840_getmode(struct CHIPSTATE *chip)
{
int val, mode;
@@ -528,6 +549,7 @@
* 1, 0 external stereo
* 0, 1 external mono
*/
+#define TDA9873_INP_MASK 3
#define TDA9873_INTERNAL 0
#define TDA9873_EXT_STEREO 2
#define TDA9873_EXT_MONO 1
@@ -543,6 +565,7 @@
* 0, 1, 1 Dual BA
*/
+#define TDA9873_TR_MASK (7 << 2)
#define TDA9873_TR_MONO 4
#define TDA9873_TR_STEREO 1 << 4
#define TDA9873_TR_REVERSE (1 << 3) & (1 << 2)
@@ -643,10 +666,10 @@
void tda9873_setmode(struct CHIPSTATE *chip, int mode)
{
- int sw_data = chip->shadow.bytes[TDA9873_SW+1] & 0xe3;
+ int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK;
/* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
- if (sw_data & 3) {
+ if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
dprintk("tda9873_setmode(): external input\n");
return;
}
@@ -667,9 +690,13 @@
case VIDEO_SOUND_LANG2:
sw_data |= TDA9873_TR_DUALB;
break;
+ default:
+ chip->mode = 0;
+ return;
}
- dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n", mode, sw_data);
- chip_write(chip,TDA9873_SW,sw_data);
+
+ dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n",
+ mode, sw_data);
}
int tda9873_checkit(struct CHIPSTATE *chip)
@@ -777,7 +804,8 @@
setmode: tda9840_setmode,
checkmode: generic_checkmode,
- init: { 2, { TDA9840_SW, 0x2a } }
+ init: { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
+ /* ,TDA9840_SW, TDA9840_MONO */} }
},
{
name: "tda9873h",
@@ -795,8 +823,9 @@
init: { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
inputreg: TDA9873_SW,
- inputmute: 0xc0,
- inputmap: {0xa4, 0xa2, 0xa4, 0xa4, 0xc0}
+ inputmute: TDA9873_MUTE | TDA9873_AUTOMUTE,
+ inputmap: {0xa0, 0xa2, 0xa0, 0xa0, 0xc0},
+ inputmask: TDA9873_INP_MASK | TDA9873_MUTE | TDA9873_AUTOMUTE
},
{
@@ -932,7 +961,7 @@
chip->c.data = chip;
/* find description for the chip */
- dprintk("tvaudio: chip @ addr=0x%x\n",addr<<1);
+ dprintk("tvaudio: chip @ addr=0x%x\n", addr<<1);
for (desc = chiplist; desc->name != NULL; desc++) {
if (0 == *(desc->insmodopt))
continue;
@@ -956,7 +985,7 @@
strcpy(chip->c.name,desc->name);
chip->type = desc-chiplist;
chip->shadow.count = desc->registers+1;
-
+ chip->prevmode = -1;
/* register */
MOD_INC_USE_COUNT;
i2c_attach_client(&chip->c);
@@ -1002,6 +1031,7 @@
{
struct CHIPSTATE *chip = client->data;
+ del_timer(&chip->wt);
if (NULL != chip->thread) {
/* shutdown async thread */
DECLARE_MUTEX_LOCKED(sem);
@@ -1034,9 +1064,9 @@
case AUDC_SET_INPUT:
if (desc->flags & CHIP_HAS_INPUTSEL) {
if (*sarg & 0x80)
- chip_write(chip,desc->inputreg,desc->inputmute);
+ chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
else
- chip_write(chip,desc->inputreg,desc->inputmap[*sarg]);
+ chip_write_masked(chip,desc->inputreg,desc->inputmap[*sarg],desc->inputmask);
}
break;
/* --- v4l ioctls --- */
@@ -1090,9 +1120,11 @@
}
case VIDIOCSFREQ:
{
- chip->mode = 0; /* automatic */
+ chip->mode = 0; /* automatic */
if (desc->checkmode) {
desc->setmode(chip,VIDEO_SOUND_MONO);
+ if (chip->prevmode != VIDEO_SOUND_MONO)
+ chip->prevmode = -1; /* reset previous mode */
mod_timer(&chip->wt, jiffies+2*HZ);
/* the thread will call checkmode() later */
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)