patch-2.4.22 linux-2.4.22/drivers/media/video/tvaudio.c
Next file: linux-2.4.22/drivers/media/video/tvaudio.h
Previous file: linux-2.4.22/drivers/media/video/tuner.h
Back to the patch index
Back to the overall index
- Lines: 475
- Date:
2003-08-25 04:44:42.000000000 -0700
- Orig file:
linux-2.4.21/drivers/media/video/tvaudio.c
- Orig date:
2003-06-13 07:51:34.000000000 -0700
diff -urN linux-2.4.21/drivers/media/video/tvaudio.c linux-2.4.22/drivers/media/video/tvaudio.c
@@ -30,9 +30,10 @@
#include <linux/smp_lock.h>
#include "audiochip.h"
-#include "tvaudio.h"
#include "id.h"
+#include "i2c-compat.h"
+#include "tvaudio.h"
/* ---------------------------------------------------------------------- */
/* insmod args */
@@ -40,12 +41,13 @@
MODULE_PARM(debug,"i");
static int debug = 0; /* insmod parameter */
-#define dprintk if (debug) printk
-
MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
MODULE_LICENSE("GPL");
+#define UNSET (-1U)
+#define dprintk if (debug) printk
+
/* ---------------------------------------------------------------------- */
/* our structs */
@@ -160,22 +162,24 @@
unsigned char buffer[2];
if (-1 == subaddr) {
- dprintk("%s: chip_write: 0x%x\n", chip->c.name, val);
+ dprintk("%s: chip_write: 0x%x\n",
+ i2c_clientname(&chip->c), val);
chip->shadow.bytes[1] = val;
buffer[0] = val;
if (1 != i2c_master_send(&chip->c,buffer,1)) {
printk(KERN_WARNING "%s: I/O error (write 0x%x)\n",
- chip->c.name, val);
+ i2c_clientname(&chip->c), val);
return -1;
}
} else {
- dprintk("%s: chip_write: reg%d=0x%x\n", chip->c.name, subaddr, val);
+ dprintk("%s: chip_write: reg%d=0x%x\n",
+ i2c_clientname(&chip->c), subaddr, val);
chip->shadow.bytes[subaddr+1] = val;
buffer[0] = subaddr;
buffer[1] = val;
if (2 != i2c_master_send(&chip->c,buffer,2)) {
printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n",
- chip->c.name, subaddr, val);
+ i2c_clientname(&chip->c), subaddr, val);
return -1;
}
}
@@ -200,10 +204,10 @@
if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
printk(KERN_WARNING "%s: I/O error (read)\n",
- chip->c.name);
+ i2c_clientname(&chip->c));
return -1;
}
- dprintk("%s: chip_read: 0x%x\n",chip->c.name,buffer);
+ dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer);
return buffer;
}
@@ -219,11 +223,11 @@
if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
printk(KERN_WARNING "%s: I/O error (read2)\n",
- chip->c.name);
+ i2c_clientname(&chip->c));
return -1;
}
dprintk("%s: chip_read2: reg%d=0x%x\n",
- chip->c.name,subaddr,read[0]);
+ i2c_clientname(&chip->c),subaddr,read[0]);
return read[0];
}
@@ -236,7 +240,7 @@
/* update our shadow register set; print bytes if (debug > 0) */
dprintk("%s: chip_cmd(%s): reg=%d, data:",
- chip->c.name,name,cmd->bytes[0]);
+ i2c_clientname(&chip->c),name,cmd->bytes[0]);
for (i = 1; i < cmd->count; i++) {
dprintk(" 0x%x",cmd->bytes[i]);
chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
@@ -245,7 +249,7 @@
/* send data to the chip */
if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
- printk(KERN_WARNING "%s: I/O error (%s)\n", chip->c.name, name);
+ printk(KERN_WARNING "%s: I/O error (%s)\n", i2c_clientname(&chip->c), name);
return -1;
}
return 0;
@@ -269,24 +273,20 @@
struct CHIPSTATE *chip = data;
struct CHIPDESC *desc = chiplist + chip->type;
-#ifdef CONFIG_SMP
lock_kernel();
-#endif
daemonize();
sigfillset(¤t->blocked);
- strcpy(current->comm,chip->c.name);
+ strcpy(current->comm,i2c_clientname(&chip->c));
chip->thread = current;
-#ifdef CONFIG_SMP
unlock_kernel();
-#endif
- dprintk("%s: thread started\n", chip->c.name);
+ dprintk("%s: thread started\n", i2c_clientname(&chip->c));
if(chip->notify != NULL)
up(chip->notify);
for (;;) {
interruptible_sleep_on(&chip->wq);
- dprintk("%s: thread wakeup\n", chip->c.name);
+ dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
if (chip->done || signal_pending(current))
break;
@@ -302,7 +302,7 @@
}
chip->thread = NULL;
- dprintk("%s: thread exiting\n", chip->c.name);
+ dprintk("%s: thread exiting\n", i2c_clientname(&chip->c));
if(chip->notify != NULL)
up(chip->notify);
@@ -317,7 +317,7 @@
if (mode == chip->prevmode)
return;
- dprintk("%s: thread checkmode\n", chip->c.name);
+ dprintk("%s: thread checkmode\n", i2c_clientname(&chip->c));
chip->prevmode = mode;
if (mode & VIDEO_SOUND_STEREO)
@@ -765,9 +765,9 @@
static int tda9874a_dic = -1; /* device id. code */
/* insmod options for tda9874a */
-static int tda9874a_SIF = -1;
-static int tda9874a_AMSEL = -1;
-static int tda9874a_STD = -1;
+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");
@@ -982,7 +982,7 @@
dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
if((dic == 0x11)||(dic == 0x07)) {
- dprintk("tvaudio: found tda9874%s.\n",(dic == 0x11) ? "a (new)":"h (old)");
+ printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h");
tda9874a_dic = dic; /* remember device id. */
return 1;
}
@@ -991,35 +991,27 @@
static int tda9874a_initialize(struct CHIPSTATE *chip)
{
- if(tda9874a_SIF != -1) {
- if(tda9874a_SIF == 1)
- tda9874a_GCONR = 0xc0; /* sound IF input 1 */
- else if(tda9874a_SIF == 2)
- tda9874a_GCONR = 0xc1; /* sound IF input 2 */
- else
- printk(KERN_WARNING "tda9874a: SIF parameter must be 1 or 2.\n");
- }
+ if (tda9874a_SIF > 2)
+ tda9874a_SIF = 1;
+ if (tda9874a_STD >= 8)
+ tda9874a_STD = 0;
+ if(tda9874a_AMSEL > 1)
+ tda9874a_AMSEL = 0;
- if(tda9874a_STD != -1) {
- if((tda9874a_STD >= 0)&&(tda9874a_STD <= 8)) {
- tda9874a_ESP = tda9874a_STD;
- tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
- } else {
- printk(KERN_WARNING "tda9874a: STD parameter must be between 0 and 8.\n");
- }
- }
+ if(tda9874a_SIF == 1)
+ tda9874a_GCONR = 0xc0; /* sound IF input 1 */
+ else
+ tda9874a_GCONR = 0xc1; /* sound IF input 2 */
- if(tda9874a_AMSEL != -1) {
- if(tda9874a_AMSEL == 0)
- tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
- else if(tda9874a_AMSEL == 1)
- tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
- else
- printk(KERN_WARNING "tda9874a: AMSEL parameter must be 0 or 1.\n");
- }
+ tda9874a_ESP = tda9874a_STD;
+ tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
- tda9874a_setup(chip);
+ if(tda9874a_AMSEL == 0)
+ tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
+ else
+ tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
+ tda9874a_setup(chip);
return 0;
}
@@ -1133,6 +1125,87 @@
#define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */
#define PIC16C54_MISC_SWITCH_LINE 0x80 /* bit 7 , Switch to Tuner */
+/* ---------------------------------------------------------------------- */
+/* audio chip descriptions - defines+functions for TA8874Z */
+
+// write 1st byte
+#define TA8874Z_LED_STE 0x80
+#define TA8874Z_LED_BIL 0x40
+#define TA8874Z_LED_EXT 0x20
+#define TA8874Z_MONO_SET 0x10
+#define TA8874Z_MUTE 0x08
+#define TA8874Z_F_MONO 0x04
+#define TA8874Z_MODE_SUB 0x02
+#define TA8874Z_MODE_MAIN 0x01
+
+// write 2nd byte
+//#define TA8874Z_TI 0x80 // test mode
+#define TA8874Z_SEPARATION 0x3f
+#define TA8874Z_SEPARATION_DEFAULT 0x10
+
+// read
+#define TA8874Z_B1 0x80
+#define TA8874Z_B0 0x40
+#define TA8874Z_CHAG_FLAG 0x20
+
+// B1 B0
+// mono L H
+// stereo L L
+// BIL H L
+
+static int ta8874z_getmode(struct CHIPSTATE *chip)
+{
+ int val, mode;
+
+ val = chip_read(chip);
+ mode = VIDEO_SOUND_MONO;
+ if (val & TA8874Z_B1){
+ mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+ }else if (!(val & TA8874Z_B0)){
+ mode |= VIDEO_SOUND_STEREO;
+ }
+ //dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode);
+ return mode;
+}
+
+static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}};
+static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}};
+static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}};
+static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}};
+
+static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
+{
+ int update = 1;
+ audiocmd *t = NULL;
+ dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode);
+
+ switch(mode){
+ case VIDEO_SOUND_MONO:
+ t = &ta8874z_mono;
+ break;
+ case VIDEO_SOUND_STEREO:
+ t = &ta8874z_stereo;
+ break;
+ case VIDEO_SOUND_LANG1:
+ t = &ta8874z_main;
+ break;
+ case VIDEO_SOUND_LANG2:
+ t = &ta8874z_sub;
+ break;
+ default:
+ update = 0;
+ }
+
+ if(update)
+ chip_cmd(chip, "TA8874Z", t);
+}
+
+static int ta8874z_checkit(struct CHIPSTATE *chip)
+{
+ int rc;
+ rc = chip_read(chip);
+ return ((rc & 0x1f) == 0x1f) ? 1 : 0;
+}
/* ---------------------------------------------------------------------- */
/* audio chip descriptions - struct CHIPDESC */
@@ -1144,9 +1217,11 @@
int tda9855 = 1;
int tda9873 = 1;
int tda9874a = 1;
-int tea6300 = 0;
+int tea6300 = 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");
@@ -1156,6 +1231,7 @@
MODULE_PARM(tea6300,"i");
MODULE_PARM(tea6420,"i");
MODULE_PARM(pic16c54,"i");
+MODULE_PARM(ta8874z,"i");
static struct CHIPDESC chiplist[] = {
{
@@ -1320,7 +1396,23 @@
PIC16C54_MISC_SND_NOTMUTE},
.inputmute = PIC16C54_MISC_SND_MUTE,
},
- { name: NULL } /* EOF */
+ {
+ .name = "ta8874z",
+ .id = -1,
+ //.id = I2C_DRIVERID_TA8874Z,
+ .checkit = ta8874z_checkit,
+ .insmodopt = &ta8874z,
+ .addr_lo = I2C_TDA9840 >> 1,
+ .addr_hi = I2C_TDA9840 >> 1,
+ .registers = 2,
+
+ .getmode = ta8874z_getmode,
+ .setmode = ta8874z_setmode,
+ .checkmode = generic_checkmode,
+
+ .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
+ },
+ { .name = NULL } /* EOF */
};
@@ -1332,6 +1424,7 @@
{
struct CHIPSTATE *chip;
struct CHIPDESC *desc;
+ int rc;
chip = kmalloc(sizeof(*chip),GFP_KERNEL);
if (!chip)
@@ -1340,7 +1433,7 @@
memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
chip->c.adapter = adap;
chip->c.addr = addr;
- chip->c.data = chip;
+ i2c_set_clientdata(&chip->c, chip);
/* find description for the chip */
dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1);
@@ -1358,14 +1451,14 @@
dprintk("tvaudio: no matching chip description found\n");
return -EIO;
}
- printk("tvaudio: found %s\n",desc->name);
+ printk("tvaudio: found %s @ 0x%x\n", desc->name, addr<<1);
dprintk("tvaudio: matches:%s%s%s.\n",
(desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
(desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
(desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
/* fill required data structures */
- strcpy(chip->c.name,desc->name);
+ strcpy(i2c_clientname(&chip->c),desc->name);
chip->type = desc-chiplist;
chip->shadow.count = desc->registers+1;
chip->prevmode = -1;
@@ -1400,8 +1493,12 @@
chip->wt.function = chip_thread_wake;
chip->wt.data = (unsigned long)chip;
init_waitqueue_head(&chip->wq);
- kernel_thread(chip_thread,(void *)chip,0);
- down(&sem);
+ rc = kernel_thread(chip_thread,(void *)chip,0);
+ if (rc < 0)
+ printk(KERN_WARNING "%s: kernel_thread() failed\n",
+ i2c_clientname(&chip->c));
+ else
+ down(&sem);
chip->notify = NULL;
wake_up_interruptible(&chip->wq);
}
@@ -1413,16 +1510,15 @@
switch (adap->id) {
case I2C_ALGO_BIT | I2C_HW_B_BT848:
case I2C_ALGO_BIT | I2C_HW_B_RIVA:
+ case I2C_ALGO_SAA7134:
return i2c_probe(adap, &addr_data, chip_attach);
- default:
- /* ignore this i2c bus */
- return 0;
}
+ return 0;
}
static int chip_detach(struct i2c_client *client)
{
- struct CHIPSTATE *chip = client->data;
+ struct CHIPSTATE *chip = i2c_get_clientdata(client);
del_timer(&chip->wt);
if (NULL != chip->thread) {
@@ -1448,10 +1544,10 @@
unsigned int cmd, void *arg)
{
__u16 *sarg = arg;
- struct CHIPSTATE *chip = client->data;
+ struct CHIPSTATE *chip = i2c_get_clientdata(client);
struct CHIPDESC *desc = chiplist + chip->type;
- dprintk("%s: chip_command 0x%x\n",chip->c.name,cmd);
+ dprintk("%s: chip_command 0x%x\n",i2c_clientname(&chip->c),cmd);
switch (cmd) {
case AUDC_SET_INPUT:
@@ -1479,8 +1575,8 @@
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 = max(chip->left,chip->right);
+ va->balance = (32768*min(chip->left,chip->right))/
(va->volume ? va->volume : 1);
}
if (desc->flags & CHIP_HAS_BASSTREBLE) {
@@ -1502,9 +1598,9 @@
struct video_audio *va = arg;
if (desc->flags & CHIP_HAS_VOLUME) {
- chip->left = (MIN(65536 - va->balance,32768) *
+ chip->left = (min(65536 - va->balance,32768) *
va->volume) / 32768;
- chip->right = (MIN(va->balance,32768) *
+ chip->right = (min(va->balance,(__u16)32768) *
va->volume) / 32768;
chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
@@ -1558,9 +1654,9 @@
static struct i2c_client client_template =
{
- .name = "(unset)",
- .flags = I2C_CLIENT_ALLOW_USE,
- .driver = &driver,
+ I2C_DEVNAME("(unset)"),
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
};
static int audiochip_init_module(void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)