Commit 7c39c153 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] v4l: #5 - i2c module updates.

From: Gerd Knorr <kraxel@bytesex.org>

This patch updates a number of video4linux-related i2c modules.  There are a
number of bugfixes which accumulated over time, also some no-op i2c changes
due to merging the i2c cleanups back into my tree and tweak them to make the
modules compile on both 2.5.x and 2.4.x.
parent e508ffb3
...@@ -45,13 +45,11 @@ ...@@ -45,13 +45,11 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include <asm/semaphore.h>
#include <linux/init.h> #include <linux/init.h>
#ifdef CONFIG_SMP
#include <asm/pgtable.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#endif #include <asm/semaphore.h>
#include <asm/pgtable.h>
/* kernel_thread */ /* kernel_thread */
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
#include <linux/unistd.h> #include <linux/unistd.h>
...@@ -59,18 +57,13 @@ ...@@ -59,18 +57,13 @@
#include <media/audiochip.h> #include <media/audiochip.h>
#include "msp3400.h" #include "msp3400.h"
/* Addresses to scan */
static unsigned short normal_i2c[] = {I2C_CLIENT_END};
static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END};
I2C_CLIENT_INSMOD;
/* insmod parameters */ /* insmod parameters */
static int debug = 0; /* debug output */ static int debug = 0; /* debug output */
static int once = 0; /* no continous stereo monitoring */ static int once = 0; /* no continous stereo monitoring */
static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france),
the autoscan seems work well only with FM... */ the autoscan seems work well only with FM... */
static int simple = -1; /* use short programming (>= msp3410 only) */ static int simple = -1; /* use short programming (>= msp3410 only) */
static int dolby = 0; static int dolby = 0;
#define DFP_COUNT 0x41 #define DFP_COUNT 0x41
static const int bl_dfp[] = { static const int bl_dfp[] = {
...@@ -79,8 +72,9 @@ static const int bl_dfp[] = { ...@@ -79,8 +72,9 @@ static const int bl_dfp[] = {
}; };
struct msp3400c { struct msp3400c {
int rev1,rev2;
int simple; int simple;
int nicam;
int mode; int mode;
int norm; int norm;
int stereo; int stereo;
...@@ -107,6 +101,10 @@ struct msp3400c { ...@@ -107,6 +101,10 @@ struct msp3400c {
struct timer_list wake_stereo; struct timer_list wake_stereo;
}; };
#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
#define MSP3400_MAX 4 #define MSP3400_MAX 4
static struct i2c_client *msps[MSP3400_MAX]; static struct i2c_client *msps[MSP3400_MAX];
...@@ -124,14 +122,25 @@ MODULE_PARM(dolby,"i"); ...@@ -124,14 +122,25 @@ MODULE_PARM(dolby,"i");
MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
MODULE_AUTHOR("Gerd Knorr"); MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL"); MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
#define I2C_MSP3400C 0x80 #define I2C_MSP3400C 0x80
#define I2C_MSP3400C_ALT 0x88
#define I2C_MSP3400C_DEM 0x10 #define I2C_MSP3400C_DEM 0x10
#define I2C_MSP3400C_DFP 0x12 #define I2C_MSP3400C_DFP 0x12
/* Addresses to scan */
static unsigned short normal_i2c[] = {
I2C_MSP3400C >> 1,
I2C_MSP3400C_ALT >> 1,
I2C_CLIENT_END
};
static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* functions for talking to the MSP3400C Sound processor */ /* functions for talking to the MSP3400C Sound processor */
...@@ -354,7 +363,8 @@ msp3400c_set_scart(struct i2c_client *client, int in, int out) ...@@ -354,7 +363,8 @@ msp3400c_set_scart(struct i2c_client *client, int in, int out)
if (-1 == scarts[out][in]) if (-1 == scarts[out][in])
return; return;
dprintk("msp34xx: scart switch: %s => %d\n",scart_names[in],out); dprintk(KERN_DEBUG
"msp34xx: scart switch: %s => %d\n",scart_names[in],out);
msp->acb &= ~scarts[out][SCART_MASK]; msp->acb &= ~scarts[out][SCART_MASK];
msp->acb |= scarts[out][in]; msp->acb |= scarts[out][in];
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
...@@ -384,7 +394,8 @@ static void msp3400c_setvolume(struct i2c_client *client, ...@@ -384,7 +394,8 @@ static void msp3400c_setvolume(struct i2c_client *client,
balance = ((right-left) * 127) / vol; balance = ((right-left) * 127) / vol;
} }
dprintk("msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", dprintk(KERN_DEBUG
"msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
muted ? "on" : "off", left, right, val>>8, balance); muted ? "on" : "off", left, right, val>>8, balance);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
...@@ -397,7 +408,7 @@ static void msp3400c_setbass(struct i2c_client *client, int bass) ...@@ -397,7 +408,7 @@ static void msp3400c_setbass(struct i2c_client *client, int bass)
{ {
int val = ((bass-32768) * 0x60 / 65535) << 8; int val = ((bass-32768) * 0x60 / 65535) << 8;
dprintk("msp34xx: setbass: %d 0x%02x\n",bass, val>>8); dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
} }
...@@ -405,7 +416,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble) ...@@ -405,7 +416,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble)
{ {
int val = ((treble-32768) * 0x60 / 65535) << 8; int val = ((treble-32768) * 0x60 / 65535) << 8;
dprintk("msp34xx: settreble: %d 0x%02x\n",treble, val>>8); dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
} }
...@@ -414,7 +425,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type) ...@@ -414,7 +425,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
struct msp3400c *msp = i2c_get_clientdata(client); struct msp3400c *msp = i2c_get_clientdata(client);
int i; int i;
dprintk("msp3400: setmode: %d\n",type); dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type);
msp->mode = type; msp->mode = type;
msp->stereo = VIDEO_SOUND_MONO; msp->stereo = VIDEO_SOUND_MONO;
...@@ -460,7 +471,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type) ...@@ -460,7 +471,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
msp_init_data[type].dfp_matrix); msp_init_data[type].dfp_matrix);
if (msp->nicam) { if (HAVE_NICAM(msp)) {
/* nicam prescale */ /* nicam prescale */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
} }
...@@ -469,8 +480,15 @@ static void msp3400c_setmode(struct i2c_client *client, int type) ...@@ -469,8 +480,15 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
/* turn on/off nicam + stereo */ /* turn on/off nicam + stereo */
static void msp3400c_setstereo(struct i2c_client *client, int mode) static void msp3400c_setstereo(struct i2c_client *client, int mode)
{ {
static char *strmode[] = { "0", "mono", "stereo", "3", static char *strmode[16] = {
"lang1", "5", "6", "7", "lang2" }; #if __GNUC__ >= 3
[ 0 ... 15 ] = "invalid",
#endif
[ VIDEO_SOUND_MONO ] = "mono",
[ VIDEO_SOUND_STEREO ] = "stereo",
[ VIDEO_SOUND_LANG1 ] = "lang1",
[ VIDEO_SOUND_LANG2 ] = "lang2",
};
struct msp3400c *msp = i2c_get_clientdata(client); struct msp3400c *msp = i2c_get_clientdata(client);
int nicam=0; /* channel source: FM/AM or nicam */ int nicam=0; /* channel source: FM/AM or nicam */
int src=0; int src=0;
...@@ -478,7 +496,7 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -478,7 +496,7 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode)
/* switch demodulator */ /* switch demodulator */
switch (msp->mode) { switch (msp->mode) {
case MSP_MODE_FM_TERRA: case MSP_MODE_FM_TERRA:
dprintk("msp3400: FM setstereo: %s\n",strmode[mode]); dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n",strmode[mode]);
msp3400c_setcarrier(client,msp->second,msp->main); msp3400c_setcarrier(client,msp->second,msp->main);
switch (mode) { switch (mode) {
case VIDEO_SOUND_STEREO: case VIDEO_SOUND_STEREO:
...@@ -492,7 +510,7 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -492,7 +510,7 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode)
} }
break; break;
case MSP_MODE_FM_SAT: case MSP_MODE_FM_SAT:
dprintk("msp3400: SAT setstereo: %s\n",strmode[mode]); dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n",strmode[mode]);
switch (mode) { switch (mode) {
case VIDEO_SOUND_MONO: case VIDEO_SOUND_MONO:
msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
...@@ -511,24 +529,24 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -511,24 +529,24 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode)
case MSP_MODE_FM_NICAM1: case MSP_MODE_FM_NICAM1:
case MSP_MODE_FM_NICAM2: case MSP_MODE_FM_NICAM2:
case MSP_MODE_AM_NICAM: case MSP_MODE_AM_NICAM:
dprintk("msp3400: NICAM setstereo: %s\n",strmode[mode]); dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n",strmode[mode]);
msp3400c_setcarrier(client,msp->second,msp->main); msp3400c_setcarrier(client,msp->second,msp->main);
if (msp->nicam_on) if (msp->nicam_on)
nicam=0x0100; nicam=0x0100;
break; break;
case MSP_MODE_BTSC: case MSP_MODE_BTSC:
dprintk("msp3400: BTSC setstereo: %s\n",strmode[mode]); dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n",strmode[mode]);
nicam=0x0300; nicam=0x0300;
break; break;
case MSP_MODE_EXTERN: case MSP_MODE_EXTERN:
dprintk("msp3400: extern setstereo: %s\n",strmode[mode]); dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n",strmode[mode]);
nicam = 0x0200; nicam = 0x0200;
break; break;
case MSP_MODE_FM_RADIO: case MSP_MODE_FM_RADIO:
dprintk("msp3400: FM-Radio setstereo: %s\n",strmode[mode]); dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n",strmode[mode]);
break; break;
default: default:
dprintk("msp3400: mono setstereo\n"); dprintk(KERN_DEBUG "msp3400: mono setstereo\n");
return; return;
} }
...@@ -557,7 +575,8 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -557,7 +575,8 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode)
src = 0x0010 | nicam; src = 0x0010 | nicam;
break; break;
} }
dprintk("msp3400: setstereo final source/matrix = 0x%x\n", src); dprintk(KERN_DEBUG
"msp3400: setstereo final source/matrix = 0x%x\n", src);
if (dolby) { if (dolby) {
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
...@@ -576,22 +595,22 @@ static void ...@@ -576,22 +595,22 @@ static void
msp3400c_print_mode(struct msp3400c *msp) msp3400c_print_mode(struct msp3400c *msp)
{ {
if (msp->main == msp->second) { if (msp->main == msp->second) {
printk("msp3400: mono sound carrier: %d.%03d MHz\n", printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n",
msp->main/910000,(msp->main/910)%1000); msp->main/910000,(msp->main/910)%1000);
} else { } else {
printk("msp3400: main sound carrier: %d.%03d MHz\n", printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n",
msp->main/910000,(msp->main/910)%1000); msp->main/910000,(msp->main/910)%1000);
} }
if (msp->mode == MSP_MODE_FM_NICAM1 || if (msp->mode == MSP_MODE_FM_NICAM1 ||
msp->mode == MSP_MODE_FM_NICAM2) msp->mode == MSP_MODE_FM_NICAM2)
printk("msp3400: NICAM/FM carrier : %d.%03d MHz\n", printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
msp->second/910000,(msp->second/910)%1000); msp->second/910000,(msp->second/910)%1000);
if (msp->mode == MSP_MODE_AM_NICAM) if (msp->mode == MSP_MODE_AM_NICAM)
printk("msp3400: NICAM/AM carrier : %d.%03d MHz\n", printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n",
msp->second/910000,(msp->second/910)%1000); msp->second/910000,(msp->second/910)%1000);
if (msp->mode == MSP_MODE_FM_TERRA && if (msp->mode == MSP_MODE_FM_TERRA &&
msp->main != msp->second) { msp->main != msp->second) {
printk("msp3400: FM-stereo carrier : %d.%03d MHz\n", printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n",
msp->second/910000,(msp->second/910)%1000); msp->second/910000,(msp->second/910)%1000);
} }
} }
...@@ -638,8 +657,8 @@ autodetect_stereo(struct i2c_client *client) ...@@ -638,8 +657,8 @@ autodetect_stereo(struct i2c_client *client)
val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
if (val > 32767) if (val > 32767)
val -= 65536; val -= 65536;
dprintk("msp34xx: stereo detect register: %d\n",val); dprintk(KERN_DEBUG
"msp34xx: stereo detect register: %d\n",val);
if (val > 4096) { if (val > 4096) {
newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO; newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO;
} else if (val < -4096) { } else if (val < -4096) {
...@@ -653,7 +672,9 @@ autodetect_stereo(struct i2c_client *client) ...@@ -653,7 +672,9 @@ autodetect_stereo(struct i2c_client *client)
case MSP_MODE_FM_NICAM2: case MSP_MODE_FM_NICAM2:
case MSP_MODE_AM_NICAM: case MSP_MODE_AM_NICAM:
val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
dprintk("msp34xx: nicam sync=%d, mode=%d\n",val & 1, (val & 0x1e) >> 1); dprintk(KERN_DEBUG
"msp34xx: nicam sync=%d, mode=%d\n",
val & 1, (val & 0x1e) >> 1);
if (val & 1) { if (val & 1) {
/* nicam synced */ /* nicam synced */
...@@ -685,7 +706,8 @@ autodetect_stereo(struct i2c_client *client) ...@@ -685,7 +706,8 @@ autodetect_stereo(struct i2c_client *client)
break; break;
case MSP_MODE_BTSC: case MSP_MODE_BTSC:
val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
dprintk("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n", dprintk(KERN_DEBUG
"msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
val, val,
(val & 0x0002) ? "no" : "yes", (val & 0x0002) ? "no" : "yes",
(val & 0x0004) ? "no" : "yes", (val & 0x0004) ? "no" : "yes",
...@@ -699,13 +721,13 @@ autodetect_stereo(struct i2c_client *client) ...@@ -699,13 +721,13 @@ autodetect_stereo(struct i2c_client *client)
} }
if (newstereo != msp->stereo) { if (newstereo != msp->stereo) {
update = 1; update = 1;
dprintk("msp34xx: watch: stereo %d => %d\n", dprintk(KERN_DEBUG "msp34xx: watch: stereo %d => %d\n",
msp->stereo,newstereo); msp->stereo,newstereo);
msp->stereo = newstereo; msp->stereo = newstereo;
} }
if (newnicam != msp->nicam_on) { if (newnicam != msp->nicam_on) {
update = 1; update = 1;
dprintk("msp34xx: watch: nicam %d => %d\n", dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n",
msp->nicam_on,newnicam); msp->nicam_on,newnicam);
msp->nicam_on = newnicam; msp->nicam_on = newnicam;
} }
...@@ -734,6 +756,8 @@ static void watch_stereo(struct i2c_client *client) ...@@ -734,6 +756,8 @@ static void watch_stereo(struct i2c_client *client)
msp3400c_setstereo(client,VIDEO_SOUND_STEREO); msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
else if (msp->stereo & VIDEO_SOUND_LANG1) else if (msp->stereo & VIDEO_SOUND_LANG1)
msp3400c_setstereo(client,VIDEO_SOUND_LANG1); msp3400c_setstereo(client,VIDEO_SOUND_LANG1);
else if (msp->stereo & VIDEO_SOUND_LANG2)
msp3400c_setstereo(client,VIDEO_SOUND_LANG2);
else else
msp3400c_setstereo(client,VIDEO_SOUND_MONO); msp3400c_setstereo(client,VIDEO_SOUND_MONO);
} }
...@@ -751,17 +775,10 @@ static int msp3400c_thread(void *data) ...@@ -751,17 +775,10 @@ static int msp3400c_thread(void *data)
struct CARRIER_DETECT *cd; struct CARRIER_DETECT *cd;
int count, max1,max2,val1,val2, val,this; int count, max1,max2,val1,val2, val,this;
#ifdef CONFIG_SMP
lock_kernel(); lock_kernel();
#endif
daemonize("msp3400"); daemonize("msp3400");
msp->thread = current; msp->thread = current;
#ifdef CONFIG_SMP
unlock_kernel(); unlock_kernel();
#endif
printk("msp3400: daemon started\n"); printk("msp3400: daemon started\n");
if(msp->notify != NULL) if(msp->notify != NULL)
...@@ -778,10 +795,6 @@ static int msp3400c_thread(void *data) ...@@ -778,10 +795,6 @@ static int msp3400c_thread(void *data)
if (msp->rmmod || signal_pending(current)) if (msp->rmmod || signal_pending(current))
goto done; goto done;
if (VIDEO_MODE_RADIO == msp->norm ||
MSP_MODE_EXTERN == msp->mode)
continue; /* nothing to do */
msp->active = 1; msp->active = 1;
if (msp->watch_stereo) { if (msp->watch_stereo) {
...@@ -798,8 +811,13 @@ static int msp3400c_thread(void *data) ...@@ -798,8 +811,13 @@ static int msp3400c_thread(void *data)
restart: restart:
if (VIDEO_MODE_RADIO == msp->norm || if (VIDEO_MODE_RADIO == msp->norm ||
MSP_MODE_EXTERN == msp->mode) MSP_MODE_EXTERN == msp->mode) {
continue; /* nothing to do */ /* no carrier scan, just unmute */
printk("msp3400: thread: no carrier scan\n");
msp3400c_setvolume(client, msp->muted,
msp->left, msp->right);
continue;
}
msp->restart = 0; msp->restart = 0;
msp3400c_setvolume(client, msp->muted, 0, 0); msp3400c_setvolume(client, msp->muted, 0, 0);
msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
...@@ -884,7 +902,7 @@ static int msp3400c_thread(void *data) ...@@ -884,7 +902,7 @@ static int msp3400c_thread(void *data)
msp->nicam_on = 0; msp->nicam_on = 0;
msp3400c_setstereo(client, VIDEO_SOUND_MONO); msp3400c_setstereo(client, VIDEO_SOUND_MONO);
msp->watch_stereo = 1; msp->watch_stereo = 1;
} else if (max2 == 1 && msp->nicam) { } else if (max2 == 1 && HAVE_NICAM(msp)) {
/* B/G NICAM */ /* B/G NICAM */
msp->second = carrier_detect_55[max2].cdo; msp->second = carrier_detect_55[max2].cdo;
msp3400c_setmode(client, MSP_MODE_FM_NICAM1); msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
...@@ -922,7 +940,7 @@ static int msp3400c_thread(void *data) ...@@ -922,7 +940,7 @@ static int msp3400c_thread(void *data)
/* volume prescale for SCART (AM mono input) */ /* volume prescale for SCART (AM mono input) */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
msp->watch_stereo = 1; msp->watch_stereo = 1;
} else if (max2 == 0 && msp->nicam) { } else if (max2 == 0 && HAVE_NICAM(msp)) {
/* D/K NICAM */ /* D/K NICAM */
msp->second = carrier_detect_65[max2].cdo; msp->second = carrier_detect_65[max2].cdo;
msp3400c_setmode(client, MSP_MODE_FM_NICAM1); msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
...@@ -959,7 +977,7 @@ static int msp3400c_thread(void *data) ...@@ -959,7 +977,7 @@ static int msp3400c_thread(void *data)
} }
done: done:
dprintk("msp3400: thread: exit\n"); dprintk(KERN_DEBUG "msp3400: thread: exit\n");
msp->active = 0; msp->active = 0;
msp->thread = NULL; msp->thread = NULL;
...@@ -1005,17 +1023,10 @@ static int msp3410d_thread(void *data) ...@@ -1005,17 +1023,10 @@ static int msp3410d_thread(void *data)
struct msp3400c *msp = i2c_get_clientdata(client); struct msp3400c *msp = i2c_get_clientdata(client);
int mode,val,i,std; int mode,val,i,std;
#ifdef CONFIG_SMP
lock_kernel(); lock_kernel();
#endif
daemonize("msp3410 [auto]"); daemonize("msp3410 [auto]");
msp->thread = current; msp->thread = current;
#ifdef CONFIG_SMP
unlock_kernel(); unlock_kernel();
#endif
printk("msp3410: daemon started\n"); printk("msp3410: daemon started\n");
if(msp->notify != NULL) if(msp->notify != NULL)
...@@ -1025,16 +1036,13 @@ static int msp3410d_thread(void *data) ...@@ -1025,16 +1036,13 @@ static int msp3410d_thread(void *data)
if (msp->rmmod) if (msp->rmmod)
goto done; goto done;
if (debug > 1) if (debug > 1)
printk("msp3410: thread: sleep\n"); printk(KERN_DEBUG "msp3410: thread: sleep\n");
interruptible_sleep_on(&msp->wq); interruptible_sleep_on(&msp->wq);
if (debug > 1) if (debug > 1)
printk("msp3410: thread: wakeup\n"); printk(KERN_DEBUG "msp3410: thread: wakeup\n");
if (msp->rmmod || signal_pending(current)) if (msp->rmmod || signal_pending(current))
goto done; goto done;
if (msp->mode == MSP_MODE_EXTERN)
continue;
msp->active = 1; msp->active = 1;
if (msp->watch_stereo) { if (msp->watch_stereo) {
...@@ -1050,8 +1058,13 @@ static int msp3410d_thread(void *data) ...@@ -1050,8 +1058,13 @@ static int msp3410d_thread(void *data)
goto done; goto done;
restart: restart:
if (msp->mode == MSP_MODE_EXTERN) if (msp->mode == MSP_MODE_EXTERN) {
/* no carrier scan needed, just unmute */
dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n");
msp3400c_setvolume(client, msp->muted,
msp->left, msp->right);
continue; continue;
}
msp->restart = 0; msp->restart = 0;
del_timer(&msp->wake_stereo); del_timer(&msp->wake_stereo);
msp->watch_stereo = 0; msp->watch_stereo = 0;
...@@ -1073,7 +1086,7 @@ static int msp3410d_thread(void *data) ...@@ -1073,7 +1086,7 @@ static int msp3410d_thread(void *data)
mode = 0x0003; mode = 0x0003;
std = 1; std = 1;
break; break;
case VIDEO_MODE_RADIO: case VIDEO_MODE_RADIO:
mode = 0x0003; mode = 0x0003;
std = 0x0040; std = 0x0040;
break; break;
...@@ -1090,7 +1103,7 @@ static int msp3410d_thread(void *data) ...@@ -1090,7 +1103,7 @@ static int msp3410d_thread(void *data)
for (i = 0; modelist[i].name != NULL; i++) for (i = 0; modelist[i].name != NULL; i++)
if (modelist[i].retval == std) if (modelist[i].retval == std)
break; break;
printk("msp3410: setting mode: %s (0x%04x)\n", printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n",
modelist[i].name ? modelist[i].name : "unknown",std); modelist[i].name ? modelist[i].name : "unknown",std);
} }
...@@ -1111,13 +1124,13 @@ static int msp3410d_thread(void *data) ...@@ -1111,13 +1124,13 @@ static int msp3410d_thread(void *data)
val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
if (val < 0x07ff) if (val < 0x07ff)
break; break;
dprintk("msp3410: detection still in progress\n"); dprintk(KERN_DEBUG "msp3410: detection still in progress\n");
} }
} }
for (i = 0; modelist[i].name != NULL; i++) for (i = 0; modelist[i].name != NULL; i++)
if (modelist[i].retval == val) if (modelist[i].retval == val)
break; break;
dprintk("msp3410: current mode: %s (0x%04x)\n", dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n",
modelist[i].name ? modelist[i].name : "unknown", modelist[i].name ? modelist[i].name : "unknown",
val); val);
msp->main = modelist[i].main; msp->main = modelist[i].main;
...@@ -1125,7 +1138,8 @@ static int msp3410d_thread(void *data) ...@@ -1125,7 +1138,8 @@ static int msp3410d_thread(void *data)
if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
/* autodetection has failed, let backup */ /* autodetection has failed, let backup */
dprintk("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)\n", dprintk(KERN_DEBUG "msp3410: autodetection failed,"
" switching to backup mode: %s (0x%04x)\n",
modelist[8].name ? modelist[8].name : "unknown",val); modelist[8].name ? modelist[8].name : "unknown",val);
val = 0x0009; val = 0x0009;
msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val); msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
...@@ -1170,11 +1184,24 @@ static int msp3410d_thread(void *data) ...@@ -1170,11 +1184,24 @@ static int msp3410d_thread(void *data)
msp->stereo = VIDEO_SOUND_STEREO; msp->stereo = VIDEO_SOUND_STEREO;
msp->nicam_on = 0; msp->nicam_on = 0;
msp->watch_stereo = 0; msp->watch_stereo = 0;
/* not needed in theory if HAVE_RADIO(), but
short programming enables carrier mute */
msp3400c_setmode(client,MSP_MODE_FM_RADIO);
msp3400c_setcarrier(client, MSP_CARRIER(10.7),
MSP_CARRIER(10.7));
/* scart routing */ /* scart routing */
msp3400c_set_scart(client,SCART_IN2,0); msp3400c_set_scart(client,SCART_IN2,0);
#if 0
/* radio from SCART_IN2 */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220); msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220); msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
#else
/* msp34xx does radio decoding */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
#endif
break; break;
case 0x0003: case 0x0003:
msp->mode = MSP_MODE_FM_TERRA; msp->mode = MSP_MODE_FM_TERRA;
...@@ -1197,7 +1224,7 @@ static int msp3410d_thread(void *data) ...@@ -1197,7 +1224,7 @@ static int msp3410d_thread(void *data)
} }
done: done:
dprintk("msp3410: thread: exit\n"); dprintk(KERN_DEBUG "msp3410: thread: exit\n");
msp->active = 0; msp->active = 0;
msp->thread = NULL; msp->thread = NULL;
...@@ -1225,11 +1252,9 @@ static struct i2c_driver driver = { ...@@ -1225,11 +1252,9 @@ static struct i2c_driver driver = {
static struct i2c_client client_template = static struct i2c_client client_template =
{ {
.flags = I2C_CLIENT_ALLOW_USE, I2C_DEVNAME("(unset)"),
.driver = &driver, .flags = I2C_CLIENT_ALLOW_USE,
.dev = { .driver = &driver,
.name = "(unset)",
},
}; };
static int msp_attach(struct i2c_adapter *adap, int addr, int kind) static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
...@@ -1237,7 +1262,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1237,7 +1262,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
struct msp3400c *msp; struct msp3400c *msp;
struct i2c_client *c; struct i2c_client *c;
int rev1,rev2,i; int i;
client_template.adapter = adap; client_template.adapter = adap;
client_template.addr = addr; client_template.addr = addr;
...@@ -1275,10 +1300,10 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1275,10 +1300,10 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
return -1; return -1;
} }
rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
if (-1 != rev1) if (-1 != msp->rev1)
rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
if ((-1 == rev1) || (0 == rev1 && 0 == rev2)) { if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
kfree(msp); kfree(msp);
kfree(c); kfree(c);
printk("msp3400: error while reading chip version\n"); printk("msp3400: error while reading chip version\n");
...@@ -1292,13 +1317,12 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1292,13 +1317,12 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
msp3400c_setvolume(c,msp->muted,msp->left,msp->right); msp3400c_setvolume(c,msp->muted,msp->left,msp->right);
snprintf(c->dev.name, DEVICE_NAME_SIZE, "MSP34%02d%c-%c%d", snprintf(c->dev.name, DEVICE_NAME_SIZE, "MSP34%02d%c-%c%d",
(rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@',
msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0; ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
if (simple == -1) { if (simple == -1) {
/* default mode */ /* default mode */
/* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */ msp->simple = HAVE_SIMPLE(msp);
msp->simple = ((rev1&0xff)+'@' > 'C');
} else { } else {
/* use insmod option */ /* use insmod option */
msp->simple = simple; msp->simple = simple;
...@@ -1310,13 +1334,16 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1310,13 +1334,16 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
msp->wake_stereo.data = (unsigned long)msp; msp->wake_stereo.data = (unsigned long)msp;
/* hello world :-) */ /* hello world :-) */
printk(KERN_INFO "msp34xx: init: chip=%s",c->dev.name); printk(KERN_INFO "msp34xx: init: chip=%s",i2c_clientname(c));
if (msp->nicam) if (HAVE_NICAM(msp))
printk(", has NICAM support"); printk(" +nicam");
if (HAVE_SIMPLE(msp))
printk(" +simple");
if (HAVE_RADIO(msp))
printk(" +radio");
printk("\n"); printk("\n");
/* startup control thread */ /* startup control thread */
MOD_INC_USE_COUNT;
msp->notify = &sem; msp->notify = &sem;
kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread, kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread,
(void *)c, 0); (void *)c, 0);
...@@ -1340,7 +1367,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1340,7 +1367,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
static int msp_detach(struct i2c_client *client) static int msp_detach(struct i2c_client *client)
{ {
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
struct msp3400c *msp = i2c_get_clientdata(client); struct msp3400c *msp = i2c_get_clientdata(client);
int i; int i;
/* shutdown control thread */ /* shutdown control thread */
...@@ -1366,7 +1393,6 @@ static int msp_detach(struct i2c_client *client) ...@@ -1366,7 +1393,6 @@ static int msp_detach(struct i2c_client *client)
i2c_detach_client(client); i2c_detach_client(client);
kfree(msp); kfree(msp);
kfree(client); kfree(client);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -1379,7 +1405,7 @@ static int msp_probe(struct i2c_adapter *adap) ...@@ -1379,7 +1405,7 @@ static int msp_probe(struct i2c_adapter *adap)
static void msp_wake_thread(struct i2c_client *client) static void msp_wake_thread(struct i2c_client *client)
{ {
struct msp3400c *msp = i2c_get_clientdata(client); struct msp3400c *msp = i2c_get_clientdata(client);
msp3400c_setvolume(client,msp->muted,0,0); msp3400c_setvolume(client,msp->muted,0,0);
msp->watch_stereo=0; msp->watch_stereo=0;
...@@ -1391,7 +1417,7 @@ static void msp_wake_thread(struct i2c_client *client) ...@@ -1391,7 +1417,7 @@ static void msp_wake_thread(struct i2c_client *client)
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{ {
struct msp3400c *msp = i2c_get_clientdata(client); struct msp3400c *msp = i2c_get_clientdata(client);
__u16 *sarg = arg; __u16 *sarg = arg;
#if 0 #if 0
int *iarg = (int*)arg; int *iarg = (int*)arg;
...@@ -1440,7 +1466,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -1440,7 +1466,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
msp->norm = VIDEO_MODE_RADIO; msp->norm = VIDEO_MODE_RADIO;
msp->watch_stereo=0; msp->watch_stereo=0;
del_timer(&msp->wake_stereo); del_timer(&msp->wake_stereo);
dprintk("msp34xx: switching to radio mode\n"); dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n");
if (msp->simple) { if (msp->simple) {
/* the thread will do for us */ /* the thread will do for us */
msp_wake_thread(client); msp_wake_thread(client);
...@@ -1459,11 +1485,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -1459,11 +1485,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
case MSP_SET_DFPREG: case MSP_SET_DFPREG:
{ {
struct msp_dfpreg *r = arg; struct msp_dfpreg *r = arg;
int i; unsigned int i;
if (r->reg < 0 || r->reg >= DFP_COUNT) if (r->reg < 0 || r->reg >= DFP_COUNT)
return -EINVAL; return -EINVAL;
for (i = 0; i < sizeof(bl_dfp)/sizeof(int); i++) for (i = 0; i < ARRAY_SIZE(bl_dfp); i++)
if (r->reg == bl_dfp[i]) if (r->reg == bl_dfp[i])
return -EINVAL; return -EINVAL;
msp->dfp_regs[r->reg] = r->value; msp->dfp_regs[r->reg] = r->value;
...@@ -1527,11 +1553,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -1527,11 +1553,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
msp3400c_setbass(client,msp->bass); msp3400c_setbass(client,msp->bass);
msp3400c_settreble(client,msp->treble); msp3400c_settreble(client,msp->treble);
if (va->mode != 0) { if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) {
msp->watch_stereo=0; msp->watch_stereo=0;
del_timer(&msp->wake_stereo); del_timer(&msp->wake_stereo);
msp->stereo = va->mode; msp->stereo = va->mode & 0x0f;
msp3400c_setstereo(client,va->mode); msp3400c_setstereo(client,va->mode & 0x0f);
} }
break; break;
} }
...@@ -1540,7 +1566,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -1540,7 +1566,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
struct video_channel *vc = arg; struct video_channel *vc = arg;
dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN\n"); dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN\n");
dprintk("msp34xx: switching to TV mode\n");
msp->norm = vc->norm; msp->norm = vc->norm;
break; break;
} }
......
...@@ -330,8 +330,6 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -330,8 +330,6 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
i2c_set_clientdata(client, t); i2c_set_clientdata(client, t);
do_tda7432_init(client); do_tda7432_init(client);
MOD_INC_USE_COUNT;
strncpy(client->dev.name, "TDA7432", DEVICE_NAME_SIZE);
printk(KERN_INFO "tda7432: init\n"); printk(KERN_INFO "tda7432: init\n");
i2c_attach_client(client); i2c_attach_client(client);
...@@ -347,13 +345,12 @@ static int tda7432_probe(struct i2c_adapter *adap) ...@@ -347,13 +345,12 @@ static int tda7432_probe(struct i2c_adapter *adap)
static int tda7432_detach(struct i2c_client *client) static int tda7432_detach(struct i2c_client *client)
{ {
struct tda7432 *t = i2c_get_clientdata(client); struct tda7432 *t = i2c_get_clientdata(client);
do_tda7432_init(client); do_tda7432_init(client);
i2c_detach_client(client); i2c_detach_client(client);
kfree(t); kfree(t);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -525,11 +522,9 @@ static struct i2c_driver driver = { ...@@ -525,11 +522,9 @@ static struct i2c_driver driver = {
static struct i2c_client client_template = static struct i2c_client client_template =
{ {
.id = -1, I2C_DEVNAME("tda7432"),
.driver = &driver, .id = -1,
.dev = { .driver = &driver,
.name = "tda7432",
},
}; };
static int tda7432_init(void) static int tda7432_init(void)
......
...@@ -161,7 +161,8 @@ static void tda9875_set(struct i2c_client *client) ...@@ -161,7 +161,8 @@ static void tda9875_set(struct i2c_client *client)
struct tda9875 *tda = i2c_get_clientdata(client); struct tda9875 *tda = i2c_get_clientdata(client);
unsigned char a; unsigned char a;
dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",tda->lvol,tda->rvol,tda->bass,tda->treble); dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",
tda->lvol,tda->rvol,tda->bass,tda->treble);
a = tda->lvol & 0xff; a = tda->lvol & 0xff;
...@@ -263,8 +264,6 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -263,8 +264,6 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
} }
do_tda9875_init(client); do_tda9875_init(client);
MOD_INC_USE_COUNT;
strncpy(client->dev.name, "TDA9875", DEVICE_NAME_SIZE);
printk(KERN_INFO "tda9875: init\n"); printk(KERN_INFO "tda9875: init\n");
i2c_attach_client(client); i2c_attach_client(client);
...@@ -280,13 +279,12 @@ static int tda9875_probe(struct i2c_adapter *adap) ...@@ -280,13 +279,12 @@ static int tda9875_probe(struct i2c_adapter *adap)
static int tda9875_detach(struct i2c_client *client) static int tda9875_detach(struct i2c_client *client)
{ {
struct tda9875 *t = i2c_get_clientdata(client); struct tda9875 *t = i2c_get_clientdata(client);
do_tda9875_init(client); do_tda9875_init(client);
i2c_detach_client(client); i2c_detach_client(client);
kfree(t); kfree(t);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -395,11 +393,9 @@ static struct i2c_driver driver = { ...@@ -395,11 +393,9 @@ static struct i2c_driver driver = {
static struct i2c_client client_template = static struct i2c_client client_template =
{ {
.id = -1, I2C_DEVNAME("tda9875"),
.driver = &driver, .id = -1,
.dev = { .driver = &driver,
.name = "tda9875",
},
}; };
static int tda9875_init(void) static int tda9875_init(void)
......
...@@ -293,8 +293,6 @@ static int tda9887_configure(struct tda9887 *t) ...@@ -293,8 +293,6 @@ static int tda9887_configure(struct tda9887 *t)
unsigned char *buf = NULL; unsigned char *buf = NULL;
int rc; int rc;
printk("tda9887_configure\n");
if (t->radio) { if (t->radio) {
dprintk("tda9885/6/7: FM Radio mode\n"); dprintk("tda9885/6/7: FM Radio mode\n");
buf = buf_fm_stereo; buf = buf_fm_stereo;
...@@ -358,11 +356,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -358,11 +356,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
return -ENOMEM; return -ENOMEM;
memset(t,0,sizeof(*t)); memset(t,0,sizeof(*t));
t->client = client_template; t->client = client_template;
i2c_set_clientdata(&t->client, t);
t->pinnacle_id = -1; t->pinnacle_id = -1;
t->tvnorm=VIDEO_MODE_PAL;
i2c_set_clientdata(&t->client, t);
i2c_attach_client(&t->client); i2c_attach_client(&t->client);
MOD_INC_USE_COUNT;
return 0; return 0;
} }
...@@ -379,7 +377,6 @@ static int tda9887_detach(struct i2c_client *client) ...@@ -379,7 +377,6 @@ static int tda9887_detach(struct i2c_client *client)
i2c_detach_client(client); i2c_detach_client(client);
kfree(t); kfree(t);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -404,6 +401,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -404,6 +401,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
int *i = arg; int *i = arg;
t->pinnacle_id = *i; t->pinnacle_id = *i;
tda9887_miro(t);
break; break;
} }
/* --- v4l ioctls --- */ /* --- v4l ioctls --- */
...@@ -441,11 +439,9 @@ static struct i2c_driver driver = { ...@@ -441,11 +439,9 @@ static struct i2c_driver driver = {
}; };
static struct i2c_client client_template = static struct i2c_client client_template =
{ {
.flags = I2C_CLIENT_ALLOW_USE, .dev.name = "tda9887",
.driver = &driver, .flags = I2C_CLIENT_ALLOW_USE,
.dev = { .driver = &driver,
.name = "tda9887",
},
}; };
static int tda9887_init_module(void) static int tda9887_init_module(void)
......
...@@ -34,19 +34,19 @@ ...@@ -34,19 +34,19 @@
#include "tvaudio.h" #include "tvaudio.h"
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/* insmod args */ /* insmod args */
MODULE_PARM(debug,"i"); MODULE_PARM(debug,"i");
static int debug = 0; /* insmod parameter */ static int debug = 0; /* insmod parameter */
#define dprintk if (debug) printk
MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips"); MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr"); MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define UNSET (-1U)
#define dprintk if (debug) printk
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/* our structs */ /* our structs */
...@@ -161,22 +161,24 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) ...@@ -161,22 +161,24 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
unsigned char buffer[2]; unsigned char buffer[2];
if (-1 == subaddr) { if (-1 == subaddr) {
dprintk("%s: chip_write: 0x%x\n", chip->c.dev.name, val); dprintk("%s: chip_write: 0x%x\n",
i2c_clientname(&chip->c), val);
chip->shadow.bytes[1] = val; chip->shadow.bytes[1] = val;
buffer[0] = val; buffer[0] = val;
if (1 != i2c_master_send(&chip->c,buffer,1)) { if (1 != i2c_master_send(&chip->c,buffer,1)) {
printk(KERN_WARNING "%s: I/O error (write 0x%x)\n", printk(KERN_WARNING "%s: I/O error (write 0x%x)\n",
chip->c.dev.name, val); i2c_clientname(&chip->c), val);
return -1; return -1;
} }
} else { } else {
dprintk("%s: chip_write: reg%d=0x%x\n", chip->c.dev.name, subaddr, val); dprintk("%s: chip_write: reg%d=0x%x\n",
i2c_clientname(&chip->c), subaddr, val);
chip->shadow.bytes[subaddr+1] = val; chip->shadow.bytes[subaddr+1] = val;
buffer[0] = subaddr; buffer[0] = subaddr;
buffer[1] = val; buffer[1] = val;
if (2 != i2c_master_send(&chip->c,buffer,2)) { if (2 != i2c_master_send(&chip->c,buffer,2)) {
printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n", printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n",
chip->c.dev.name, subaddr, val); i2c_clientname(&chip->c), subaddr, val);
return -1; return -1;
} }
} }
...@@ -201,10 +203,10 @@ static int chip_read(struct CHIPSTATE *chip) ...@@ -201,10 +203,10 @@ static int chip_read(struct CHIPSTATE *chip)
if (1 != i2c_master_recv(&chip->c,&buffer,1)) { if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
printk(KERN_WARNING "%s: I/O error (read)\n", printk(KERN_WARNING "%s: I/O error (read)\n",
chip->c.dev.name); i2c_clientname(&chip->c));
return -1; return -1;
} }
dprintk("%s: chip_read: 0x%x\n",chip->c.dev.name,buffer); dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer);
return buffer; return buffer;
} }
...@@ -220,11 +222,11 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) ...@@ -220,11 +222,11 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr)
if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
printk(KERN_WARNING "%s: I/O error (read2)\n", printk(KERN_WARNING "%s: I/O error (read2)\n",
chip->c.dev.name); i2c_clientname(&chip->c));
return -1; return -1;
} }
dprintk("%s: chip_read2: reg%d=0x%x\n", dprintk("%s: chip_read2: reg%d=0x%x\n",
chip->c.dev.name,subaddr,read[0]); i2c_clientname(&chip->c),subaddr,read[0]);
return read[0]; return read[0];
} }
...@@ -237,7 +239,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) ...@@ -237,7 +239,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
/* update our shadow register set; print bytes if (debug > 0) */ /* update our shadow register set; print bytes if (debug > 0) */
dprintk("%s: chip_cmd(%s): reg=%d, data:", dprintk("%s: chip_cmd(%s): reg=%d, data:",
chip->c.dev.name,name,cmd->bytes[0]); i2c_clientname(&chip->c),name,cmd->bytes[0]);
for (i = 1; i < cmd->count; i++) { for (i = 1; i < cmd->count; i++) {
dprintk(" 0x%x",cmd->bytes[i]); dprintk(" 0x%x",cmd->bytes[i]);
chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i]; chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
...@@ -246,7 +248,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) ...@@ -246,7 +248,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
/* send data to the chip */ /* send data to the chip */
if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
printk(KERN_WARNING "%s: I/O error (%s)\n", chip->c.dev.name, name); printk(KERN_WARNING "%s: I/O error (%s)\n", i2c_clientname(&chip->c), name);
return -1; return -1;
} }
return 0; return 0;
...@@ -270,22 +272,18 @@ static int chip_thread(void *data) ...@@ -270,22 +272,18 @@ static int chip_thread(void *data)
struct CHIPSTATE *chip = data; struct CHIPSTATE *chip = data;
struct CHIPDESC *desc = chiplist + chip->type; struct CHIPDESC *desc = chiplist + chip->type;
#ifdef CONFIG_SMP
lock_kernel(); lock_kernel();
#endif daemonize("%s",i2c_clientname(&chip->c));
daemonize("%s", chip->c.dev.name);
chip->thread = current; chip->thread = current;
#ifdef CONFIG_SMP
unlock_kernel(); unlock_kernel();
#endif
dprintk("%s: thread started\n", chip->c.dev.name); dprintk("%s: thread started\n", i2c_clientname(&chip->c));
if(chip->notify != NULL) if(chip->notify != NULL)
up(chip->notify); up(chip->notify);
for (;;) { for (;;) {
interruptible_sleep_on(&chip->wq); interruptible_sleep_on(&chip->wq);
dprintk("%s: thread wakeup\n", chip->c.dev.name); dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
if (chip->done || signal_pending(current)) if (chip->done || signal_pending(current))
break; break;
...@@ -301,7 +299,7 @@ static int chip_thread(void *data) ...@@ -301,7 +299,7 @@ static int chip_thread(void *data)
} }
chip->thread = NULL; chip->thread = NULL;
dprintk("%s: thread exiting\n", chip->c.dev.name); dprintk("%s: thread exiting\n", i2c_clientname(&chip->c));
if(chip->notify != NULL) if(chip->notify != NULL)
up(chip->notify); up(chip->notify);
...@@ -316,7 +314,7 @@ static void generic_checkmode(struct CHIPSTATE *chip) ...@@ -316,7 +314,7 @@ static void generic_checkmode(struct CHIPSTATE *chip)
if (mode == chip->prevmode) if (mode == chip->prevmode)
return; return;
dprintk("%s: thread checkmode\n", chip->c.dev.name); dprintk("%s: thread checkmode\n", i2c_clientname(&chip->c));
chip->prevmode = mode; chip->prevmode = mode;
if (mode & VIDEO_SOUND_STEREO) if (mode & VIDEO_SOUND_STEREO)
...@@ -764,9 +762,9 @@ static int tda9874a_ESP = 0x07; /* default standard: NICAM D/K */ ...@@ -764,9 +762,9 @@ static int tda9874a_ESP = 0x07; /* default standard: NICAM D/K */
static int tda9874a_dic = -1; /* device id. code */ static int tda9874a_dic = -1; /* device id. code */
/* insmod options for tda9874a */ /* insmod options for tda9874a */
static int tda9874a_SIF = -1; static unsigned int tda9874a_SIF = UNSET;
static int tda9874a_AMSEL = -1; static unsigned int tda9874a_AMSEL = UNSET;
static int tda9874a_STD = -1; static unsigned int tda9874a_STD = UNSET;
MODULE_PARM(tda9874a_SIF,"i"); MODULE_PARM(tda9874a_SIF,"i");
MODULE_PARM(tda9874a_AMSEL,"i"); MODULE_PARM(tda9874a_AMSEL,"i");
MODULE_PARM(tda9874a_STD,"i"); MODULE_PARM(tda9874a_STD,"i");
...@@ -981,7 +979,7 @@ static int tda9874a_checkit(struct CHIPSTATE *chip) ...@@ -981,7 +979,7 @@ static int tda9874a_checkit(struct CHIPSTATE *chip)
dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
if((dic == 0x11)||(dic == 0x07)) { 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. */ tda9874a_dic = dic; /* remember device id. */
return 1; return 1;
} }
...@@ -990,35 +988,27 @@ static int tda9874a_checkit(struct CHIPSTATE *chip) ...@@ -990,35 +988,27 @@ static int tda9874a_checkit(struct CHIPSTATE *chip)
static int tda9874a_initialize(struct CHIPSTATE *chip) static int tda9874a_initialize(struct CHIPSTATE *chip)
{ {
if(tda9874a_SIF != -1) { if (tda9874a_SIF > 2)
if(tda9874a_SIF == 1) tda9874a_SIF = 1;
tda9874a_GCONR = 0xc0; /* sound IF input 1 */ if (tda9874a_STD >= 8)
else if(tda9874a_SIF == 2) tda9874a_STD = 0;
tda9874a_GCONR = 0xc1; /* sound IF input 2 */ if(tda9874a_AMSEL > 1)
else tda9874a_AMSEL = 0;
printk(KERN_WARNING "tda9874a: SIF parameter must be 1 or 2.\n");
} if(tda9874a_SIF == 1)
tda9874a_GCONR = 0xc0; /* sound IF input 1 */
else
tda9874a_GCONR = 0xc1; /* sound IF input 2 */
if(tda9874a_STD != -1) { tda9874a_ESP = tda9874a_STD;
if((tda9874a_STD >= 0)&&(tda9874a_STD <= 8)) { tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
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_AMSEL != -1) { if(tda9874a_AMSEL == 0)
if(tda9874a_AMSEL == 0) tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */ else
else if(tda9874a_AMSEL == 1) tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
else
printk(KERN_WARNING "tda9874a: AMSEL parameter must be 0 or 1.\n");
}
tda9874a_setup(chip); tda9874a_setup(chip);
return 0; return 0;
} }
...@@ -1132,6 +1122,87 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode) ...@@ -1132,6 +1122,87 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
#define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */ #define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */
#define PIC16C54_MISC_SWITCH_LINE 0x80 /* bit 7 , Switch to Tuner */ #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 */ /* audio chip descriptions - struct CHIPDESC */
...@@ -1143,9 +1214,11 @@ int tda9850 = 1; ...@@ -1143,9 +1214,11 @@ int tda9850 = 1;
int tda9855 = 1; int tda9855 = 1;
int tda9873 = 1; int tda9873 = 1;
int tda9874a = 1; int tda9874a = 1;
int tea6300 = 0; int tea6300 = 0; // address clash with msp34xx
int tea6420 = 1; int tea6420 = 1;
int pic16c54 = 1; int pic16c54 = 1;
int ta8874z = 0; // address clash with tda9840
MODULE_PARM(tda8425,"i"); MODULE_PARM(tda8425,"i");
MODULE_PARM(tda9840,"i"); MODULE_PARM(tda9840,"i");
MODULE_PARM(tda9850,"i"); MODULE_PARM(tda9850,"i");
...@@ -1155,6 +1228,7 @@ MODULE_PARM(tda9874a,"i"); ...@@ -1155,6 +1228,7 @@ MODULE_PARM(tda9874a,"i");
MODULE_PARM(tea6300,"i"); MODULE_PARM(tea6300,"i");
MODULE_PARM(tea6420,"i"); MODULE_PARM(tea6420,"i");
MODULE_PARM(pic16c54,"i"); MODULE_PARM(pic16c54,"i");
MODULE_PARM(ta8874z,"i");
static struct CHIPDESC chiplist[] = { static struct CHIPDESC chiplist[] = {
{ {
...@@ -1319,7 +1393,23 @@ static struct CHIPDESC chiplist[] = { ...@@ -1319,7 +1393,23 @@ static struct CHIPDESC chiplist[] = {
PIC16C54_MISC_SND_NOTMUTE}, PIC16C54_MISC_SND_NOTMUTE},
.inputmute = PIC16C54_MISC_SND_MUTE, .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 */
}; };
...@@ -1356,19 +1446,18 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1356,19 +1446,18 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
dprintk("tvaudio: no matching chip description found\n"); dprintk("tvaudio: no matching chip description found\n");
return -EIO; 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", dprintk("tvaudio: matches:%s%s%s.\n",
(desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
(desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
(desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
/* fill required data structures */ /* fill required data structures */
strncpy(chip->c.dev.name, desc->name, DEVICE_NAME_SIZE); strcpy(i2c_clientname(&chip->c),desc->name);
chip->type = desc-chiplist; chip->type = desc-chiplist;
chip->shadow.count = desc->registers+1; chip->shadow.count = desc->registers+1;
chip->prevmode = -1; chip->prevmode = -1;
/* register */ /* register */
MOD_INC_USE_COUNT;
i2c_attach_client(&chip->c); i2c_attach_client(&chip->c);
/* initialization */ /* initialization */
...@@ -1430,7 +1519,6 @@ static int chip_detach(struct i2c_client *client) ...@@ -1430,7 +1519,6 @@ static int chip_detach(struct i2c_client *client)
i2c_detach_client(&chip->c); i2c_detach_client(&chip->c);
kfree(chip); kfree(chip);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -1444,7 +1532,7 @@ static int chip_command(struct i2c_client *client, ...@@ -1444,7 +1532,7 @@ static int chip_command(struct i2c_client *client,
struct CHIPSTATE *chip = i2c_get_clientdata(client); struct CHIPSTATE *chip = i2c_get_clientdata(client);
struct CHIPDESC *desc = chiplist + chip->type; struct CHIPDESC *desc = chiplist + chip->type;
dprintk("%s: chip_command 0x%x\n",chip->c.dev.name,cmd); dprintk("%s: chip_command 0x%x\n",i2c_clientname(&chip->c),cmd);
switch (cmd) { switch (cmd) {
case AUDC_SET_INPUT: case AUDC_SET_INPUT:
...@@ -1552,11 +1640,9 @@ static struct i2c_driver driver = { ...@@ -1552,11 +1640,9 @@ static struct i2c_driver driver = {
static struct i2c_client client_template = static struct i2c_client client_template =
{ {
.flags = I2C_CLIENT_ALLOW_USE, I2C_DEVNAME("(unset)"),
.driver = &driver, .flags = I2C_CLIENT_ALLOW_USE,
.dev = { .driver = &driver,
.name = "(unset)",
},
}; };
static int audiochip_init_module(void) static int audiochip_init_module(void)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
*/ */
#define I2C_TDA8425 0x82 #define I2C_TDA8425 0x82
#define I2C_TDA9840 0x84 #define I2C_TDA9840 0x84 /* also used by TA8874Z */
#define I2C_TDA985x_L 0xb4 /* also used by 9873 */ #define I2C_TDA985x_L 0xb4 /* also used by 9873 */
#define I2C_TDA985x_H 0xb6 #define I2C_TDA985x_H 0xb6
#define I2C_TDA9874 0xb0 /* also used by 9875 */ #define I2C_TDA9874 0xb0 /* also used by 9875 */
......
...@@ -10,19 +10,16 @@ ...@@ -10,19 +10,16 @@
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <asm/semaphore.h>
#include <linux/sound.h> #include <linux/sound.h>
#include <linux/soundcard.h> #include <linux/soundcard.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#define DEV_MAX 4 #define DEV_MAX 4
static int debug = 0;
static int devnr = -1; static int devnr = -1;
MODULE_PARM(debug,"i");
MODULE_PARM(devnr,"i"); MODULE_PARM(devnr,"i");
MODULE_AUTHOR("Gerd Knorr"); MODULE_AUTHOR("Gerd Knorr");
...@@ -87,7 +84,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -87,7 +84,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (cmd == SOUND_MIXER_INFO) { if (cmd == SOUND_MIXER_INFO) {
mixer_info info; mixer_info info;
strncpy(info.id, "tv card", sizeof(info.id)); strncpy(info.id, "tv card", sizeof(info.id));
strncpy(info.name, client->dev.name, sizeof(info.name)); strncpy(info.name, i2c_clientname(client), sizeof(info.name));
info.modify_counter = 42 /* FIXME */; info.modify_counter = 42 /* FIXME */;
if (copy_to_user((void *)arg, &info, sizeof(info))) if (copy_to_user((void *)arg, &info, sizeof(info)))
return -EFAULT; return -EFAULT;
...@@ -96,7 +93,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -96,7 +93,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (cmd == SOUND_OLD_MIXER_INFO) { if (cmd == SOUND_OLD_MIXER_INFO) {
_old_mixer_info info; _old_mixer_info info;
strncpy(info.id, "tv card", sizeof(info.id)); strncpy(info.id, "tv card", sizeof(info.id));
strncpy(info.name, client->dev.name, sizeof(info.name)); strncpy(info.name, i2c_clientname(client), sizeof(info.name));
if (copy_to_user((void *)arg, &info, sizeof(info))) if (copy_to_user((void *)arg, &info, sizeof(info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -143,7 +140,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -143,7 +140,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
case MIXER_READ(SOUND_MIXER_VOLUME): case MIXER_READ(SOUND_MIXER_VOLUME):
left = (min(65536 - va.balance,32768) * left = (min(65536 - va.balance,32768) *
va.volume) / 32768; va.volume) / 32768;
right = (min(va.balance,32768) * right = (min(va.balance,(u16)32768) *
va.volume) / 32768; va.volume) / 32768;
ret = v4l_to_mix2(left,right); ret = v4l_to_mix2(left,right);
break; break;
...@@ -218,8 +215,8 @@ static struct i2c_driver driver = { ...@@ -218,8 +215,8 @@ static struct i2c_driver driver = {
.name = "tv card mixer driver", .name = "tv card mixer driver",
.id = I2C_DRIVERID_TVMIXER, .id = I2C_DRIVERID_TVMIXER,
.flags = I2C_DF_NOTIFY, .flags = I2C_DF_NOTIFY,
.attach_adapter = tvmixer_adapters,
.detach_adapter = tvmixer_adapters, .detach_adapter = tvmixer_adapters,
.attach_adapter = tvmixer_adapters,
.detach_client = tvmixer_clients, .detach_client = tvmixer_clients,
}; };
...@@ -238,9 +235,6 @@ static int tvmixer_adapters(struct i2c_adapter *adap) ...@@ -238,9 +235,6 @@ static int tvmixer_adapters(struct i2c_adapter *adap)
struct list_head *item; struct list_head *item;
struct i2c_client *client; struct i2c_client *client;
if (debug)
printk("tvmixer: adapter %s\n",adap->dev.name);
list_for_each(item,&adap->clients) { list_for_each(item,&adap->clients) {
client = list_entry(item, struct i2c_client, list); client = list_entry(item, struct i2c_client, list);
tvmixer_clients(client); tvmixer_clients(client);
...@@ -253,16 +247,8 @@ static int tvmixer_clients(struct i2c_client *client) ...@@ -253,16 +247,8 @@ static int tvmixer_clients(struct i2c_client *client)
struct video_audio va; struct video_audio va;
int i,minor; int i,minor;
/* TV card ??? */ if (!(client->adapter->class & I2C_ADAP_CLASS_TV_ANALOG))
if (!(client->adapter->class & I2C_ADAP_CLASS_TV_ANALOG)) {
/* ignore that one */
if (debug)
printk("tvmixer: %s is not a tv card\n",
client->adapter->dev.name);
return -1; return -1;
}
if (debug)
printk("tvmixer: debug: %s\n",client->dev.name);
/* unregister ?? */ /* unregister ?? */
for (i = 0; i < DEV_MAX; i++) { for (i = 0; i < DEV_MAX; i++) {
...@@ -271,7 +257,8 @@ static int tvmixer_clients(struct i2c_client *client) ...@@ -271,7 +257,8 @@ static int tvmixer_clients(struct i2c_client *client)
unregister_sound_mixer(devices[i].minor); unregister_sound_mixer(devices[i].minor);
devices[i].dev = NULL; devices[i].dev = NULL;
devices[i].minor = -1; devices[i].minor = -1;
printk("tvmixer: %s unregistered (#1)\n",client->dev.name); printk("tvmixer: %s unregistered (#1)\n",
i2c_clientname(client));
return 0; return 0;
} }
} }
...@@ -286,25 +273,13 @@ static int tvmixer_clients(struct i2c_client *client) ...@@ -286,25 +273,13 @@ static int tvmixer_clients(struct i2c_client *client)
} }
/* audio chip with mixer ??? */ /* audio chip with mixer ??? */
if (NULL == client->driver->command) { if (NULL == client->driver->command)
if (debug)
printk("tvmixer: %s: driver->command is NULL\n",
client->driver->name);
return -1; return -1;
}
memset(&va,0,sizeof(va)); memset(&va,0,sizeof(va));
if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) { if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
if (debug)
printk("tvmixer: %s: VIDIOCGAUDIO failed\n",
client->dev.name);
return -1; return -1;
} if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) {
if (debug)
printk("tvmixer: %s: has no volume control\n",
client->dev.name);
return -1; return -1;
}
/* everything is fine, register */ /* everything is fine, register */
if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) { if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
...@@ -342,7 +317,7 @@ static void tvmixer_cleanup_module(void) ...@@ -342,7 +317,7 @@ static void tvmixer_cleanup_module(void)
if (devices[i].minor != -1) { if (devices[i].minor != -1) {
unregister_sound_mixer(devices[i].minor); unregister_sound_mixer(devices[i].minor);
printk("tvmixer: %s unregistered (#2)\n", printk("tvmixer: %s unregistered (#2)\n",
devices[i].dev->dev.name); i2c_clientname(devices[i].dev));
} }
} }
} }
......
...@@ -18,6 +18,15 @@ ...@@ -18,6 +18,15 @@
#define AUDIO_MUTE 0x80 #define AUDIO_MUTE 0x80
#define AUDIO_UNMUTE 0x81 #define AUDIO_UNMUTE 0x81
/* all the stuff below is obsolete and just here for reference. I'll
* remove it once the driver is tested and works fine.
*
* Instead creating alot of tiny API's for all kinds of different
* chips, we'll just pass throuth the v4l ioctl structs (v4l2 not
* yet...). It is a bit less flexible, but most/all used i2c chips
* make sense in v4l context only. So I think that's acceptable...
*/
/* misc stuff to pass around config info to i2c chips */ /* misc stuff to pass around config info to i2c chips */
#define AUDC_CONFIG_PINNACLE _IOW('m',32,int) #define AUDC_CONFIG_PINNACLE _IOW('m',32,int)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment