Hi Gerd, On top of those 4 patches from the other day, here's one more that fixes that bug with going nicam->composite, and adds instance numbers to the logging messages. Bit longer 'cos of all the printk changes. Regards, Steve --- bttv-0.7.80/driver/msp3400.c-before-multicard-fixes Sat Oct 6 16:34:40 2001 +++ bttv-0.7.80/driver/msp3400.c Sat Oct 6 20:53:45 2001 @@ -92,6 +92,7 @@ }; struct msp3400c { + int nr; /* Which msp instance? */ int simple; int nicam; int mode; @@ -352,7 +353,7 @@ if (-1 == scarts[out][in]) return; - dprintk("msp34xx: scart switch: %s => %d\n",scart_names[in],out); + dprintk("msp34xx[%d]: scart switch: %s => %d\n",msp->nr,scart_names[in],out); msp->acb &= ~scarts[out][SCART_MASK]; msp->acb |= scarts[out][in]; msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); @@ -382,7 +383,8 @@ balance = ((right-left) * 127) / vol; } - dprintk("msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", + dprintk("msp34xx[%d]: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", + ((struct msp3400c *)(client->data))->nr, muted ? "on" : "off", left, right, val>>8, balance); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ @@ -395,7 +397,9 @@ { int val = ((bass-32768) * 0x60 / 65535) << 8; - dprintk("msp34xx: setbass: %d 0x%02x\n",bass, val>>8); + dprintk("msp34xx[%d]: setbass: %d 0x%02x\n", + ((struct msp3400c *)(client->data))->nr, + bass, val>>8); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ } @@ -403,7 +407,9 @@ { int val = ((treble-32768) * 0x60 / 65535) << 8; - dprintk("msp34xx: settreble: %d 0x%02x\n",treble, val>>8); + dprintk("msp34xx[%d]: settreble: %d 0x%02x\n", + ((struct msp3400c *)(client->data))->nr, + treble, val>>8); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ } @@ -412,7 +418,7 @@ struct msp3400c *msp = client->data; int i; - dprintk("msp3400: setmode: %d\n",type); + dprintk("msp3400[%d]: setmode: %d\n",msp->nr, type); msp->mode = type; msp->stereo = VIDEO_SOUND_MONO; @@ -469,87 +475,91 @@ int nicam=0; /* channel source: FM/AM or nicam */ int src=0; - /* switch demodulator */ - switch (msp->mode) { - case MSP_MODE_FM_TERRA: - dprintk("msp3400: FM setstereo: %d\n",mode); - msp3400c_setcarrier(client,msp->second,msp->main); - switch (mode) { - case VIDEO_SOUND_STEREO: - msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); + if (msp->scart) { + dprintk("msp3400[%d]: setstereo - in SCART mode so setting stereo\n", msp->nr); + src = 0x220; /* FIXME: Maybe honour stereo/mono? */ + } + else { + /* switch demodulator */ + switch (msp->mode) { + case MSP_MODE_FM_TERRA: + dprintk("msp3400[%d]: FM setstereo: %d\n",msp->nr, mode); + msp3400c_setcarrier(client,msp->second,msp->main); + switch (mode) { + case VIDEO_SOUND_STEREO: + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); + break; + case VIDEO_SOUND_MONO: + case VIDEO_SOUND_LANG1: + case VIDEO_SOUND_LANG2: + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000); + break; + } break; - case VIDEO_SOUND_MONO: - case VIDEO_SOUND_LANG1: - case VIDEO_SOUND_LANG2: - msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000); + case MSP_MODE_FM_SAT: + dprintk("msp3400[%d]: SAT setstereo: %d\n",msp->nr, mode); + switch (mode) { + case VIDEO_SOUND_MONO: + msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); + break; + case VIDEO_SOUND_STEREO: + msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); + break; + case VIDEO_SOUND_LANG1: + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + break; + case VIDEO_SOUND_LANG2: + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + break; + } + break; + case MSP_MODE_FM_NICAM1: + case MSP_MODE_FM_NICAM2: + case MSP_MODE_AM_NICAM: + dprintk("msp3400[%d]: NICAM setstereo: %d\n",msp->nr, mode); + msp3400c_setcarrier(client,msp->second,msp->main); + if (msp->nicam_on) + nicam=0x0100; + break; + case MSP_MODE_BTSC: + dprintk("msp3400[%d]: BTSC setstereo: %d\n",msp->nr, mode); + nicam=0x0300; break; + case MSP_MODE_FM_RADIO: + dprintk("msp3400[%d]: FM-Radio setstereo: %d\n",msp->nr, mode); + break; + default: + dprintk("msp3400[%d]: mono setstereo\n",msp->nr); + return; /* FIXME: Really??? */ } - break; - case MSP_MODE_FM_SAT: - dprintk("msp3400: SAT setstereo: %d\n",mode); + + /* switch audio */ switch (mode) { - case VIDEO_SOUND_MONO: - msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); - break; case VIDEO_SOUND_STEREO: - msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); + src = 0x0020 | nicam; +#if 0 + /* spatial effect */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000); +#endif break; + case VIDEO_SOUND_MONO: + if (msp->mode == MSP_MODE_AM_NICAM) { + dprintk("msp3400[%d]: switching to AM mono\n",msp->nr); + /* AM mono decoding is handled by tuner, not MSP chip */ + /* SCART switching control register */ + msp3400c_set_scart(client,SCART_MONO,0); + src = 0x0200; + break; + } case VIDEO_SOUND_LANG1: - msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + src = 0x0000 | nicam; break; case VIDEO_SOUND_LANG2: - msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + src = 0x0010 | nicam; break; } - break; - case MSP_MODE_FM_NICAM1: - case MSP_MODE_FM_NICAM2: - case MSP_MODE_AM_NICAM: - dprintk("msp3400: NICAM setstereo: %d\n",mode); - msp3400c_setcarrier(client,msp->second,msp->main); - if (msp->nicam_on) - nicam=0x0100; - break; - case MSP_MODE_BTSC: - dprintk("msp3400: BTSC setstereo: %d\n",mode); - nicam=0x0300; - break; - case MSP_MODE_FM_RADIO: - dprintk("msp3400: FM-Radio setstereo: %d\n", mode); - break; - default: - dprintk("msp3400: mono setstereo\n"); - return; } - - /* switch audio */ - switch (mode) { - case VIDEO_SOUND_STEREO: - src = 0x0020 | nicam; -#if 0 - /* spatial effect */ - msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000); -#endif - break; - case VIDEO_SOUND_MONO: - if (msp->mode == MSP_MODE_AM_NICAM) { - dprintk("msp3400: switching to AM mono\n"); - /* AM mono decoding is handled by tuner, not MSP chip */ - /* SCART switching control register */ - msp3400c_set_scart(client,SCART_MONO,0); - src = 0x0200; - break; - } - case VIDEO_SOUND_LANG1: - src = 0x0000 | nicam; - break; - case VIDEO_SOUND_LANG2: - src = 0x0010 | nicam; - break; - } - if (msp->scart) - src |= 0x0200; - dprintk("msp3400: setstereo final source/matrix = 0x%x\n", src); + dprintk("msp3400[%d]: setstereo final source/matrix = 0x%x\n",msp->nr, src); if (dolby) { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620); @@ -567,22 +577,22 @@ msp3400c_print_mode(struct msp3400c *msp) { if (msp->main == msp->second) { - printk("msp3400: mono sound carrier: %d.%03d MHz\n", + printk("msp3400[%d]: mono sound carrier: %d.%03d MHz\n",msp->nr, msp->main/910000,(msp->main/910)%1000); } else { - printk("msp3400: main sound carrier: %d.%03d MHz\n", + printk("msp3400[%d]: main sound carrier: %d.%03d MHz\n",msp->nr, msp->main/910000,(msp->main/910)%1000); } if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2) - printk("msp3400: NICAM/FM carrier : %d.%03d MHz\n", + printk("msp3400[%d]: NICAM/FM carrier : %d.%03d MHz\n",msp->nr, msp->second/910000,(msp->second/910)%1000); if (msp->mode == MSP_MODE_AM_NICAM) - printk("msp3400: NICAM/AM carrier : %d.%03d MHz\n", + printk("msp3400[%d]: NICAM/AM carrier : %d.%03d MHz\n",msp->nr, msp->second/910000,(msp->second/910)%1000); if (msp->mode == MSP_MODE_FM_TERRA && msp->main != msp->second) { - printk("msp3400: FM-stereo carrier : %d.%03d MHz\n", + printk("msp3400[%d]: FM-stereo carrier : %d.%03d MHz\n",msp->nr, msp->second/910000,(msp->second/910)%1000); } } @@ -629,7 +639,7 @@ val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); if (val > 32768) val -= 65536; - dprintk("msp34xx: stereo detect register: %d\n",val); + dprintk("msp34xx[%d]: stereo detect register: %d\n",msp->nr, val); if (val > 4096) { newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO; @@ -644,7 +654,8 @@ case MSP_MODE_FM_NICAM2: case MSP_MODE_AM_NICAM: val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); - dprintk("msp34xx: nicam sync=%d, mode=%d\n",val & 1, (val & 0x1e) >> 1); + dprintk("msp34xx[%d]: nicam sync=%d, mode=%d\n",msp->nr, + val & 1, (val & 0x1e) >> 1); if (val & 1) { /* nicam synced */ @@ -676,7 +687,7 @@ break; case MSP_MODE_BTSC: val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); - dprintk("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n", + dprintk("msp3410[%d]: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",msp->nr, val, (val & 0x0002) ? "no" : "yes", (val & 0x0004) ? "no" : "yes", @@ -690,13 +701,13 @@ } if (newstereo != msp->stereo) { update = 1; - dprintk("msp34xx: watch: stereo %d => %d\n", + dprintk("msp34xx[%d]: watch: stereo %d => %d\n",msp->nr, msp->stereo,newstereo); msp->stereo = newstereo; } if (newnicam != msp->nicam_on) { update = 1; - dprintk("msp34xx: watch: nicam %d => %d\n", + dprintk("msp34xx[%d]: watch: nicam %d => %d\n",msp->nr, msp->nicam_on,newnicam); msp->nicam_on = newnicam; } @@ -748,7 +759,7 @@ daemonize(); sigfillset(¤t->blocked); - strcpy(current->comm,"msp3400"); + sprintf(current->comm,"msp3400[%d]",msp->nr); msp->thread = current; @@ -756,7 +767,7 @@ unlock_kernel(); #endif - printk("msp3400: daemon started\n"); + printk("msp3400[%d]: daemon started\n",msp->nr); if(msp->notify != NULL) up(msp->notify); @@ -764,10 +775,10 @@ if (msp->rmmod) goto done; if (debug > 1) - printk("msp3400: thread: sleep\n"); + printk("msp3400[%d]: thread: sleep\n",msp->nr); interruptible_sleep_on(&msp->wq); if (debug > 1) - printk("msp3400: thread: wakeup\n"); + printk("msp3400[%d]: thread: wakeup\n",msp->nr); if (msp->rmmod || signal_pending(current)) goto done; @@ -810,7 +821,7 @@ /* autodetect doesn't work well with AM ... */ max1 = 3; count = 0; - dprintk("msp3400: AM sound override\n"); + dprintk("msp3400[%d]: AM sound override\n",msp->nr); } for (this = 0; this < count; this++) { @@ -828,7 +839,8 @@ val -= 65536; if (val1 < val) val1 = val, max1 = this; - dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); + dprintk("msp3400[%d]: carrier1 val: %5d / %s\n",msp->nr, + val,cd[this].name); } /* carrier detect pass #2 -- second (stereo) carrier */ @@ -865,7 +877,8 @@ val -= 65536; if (val2 < val) val2 = val, max2 = this; - dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); + dprintk("msp3400[%d]: carrier2 val: %5d / %s\n",msp->nr, + val,cd[this].name); } /* programm the msp3400 according to the results */ @@ -954,7 +967,7 @@ } done: - dprintk("msp3400: thread: exit\n"); + dprintk("msp3400[%d]: thread: exit\n",msp->nr); msp->active = 0; msp->thread = NULL; @@ -1006,7 +1019,7 @@ daemonize(); sigfillset(¤t->blocked); - strcpy(current->comm,"msp3410 [auto]"); + sprintf(current->comm,"msp3410[%d]-auto", msp->nr); msp->thread = current; @@ -1014,7 +1027,7 @@ unlock_kernel(); #endif - printk("msp3410: daemon started\n"); + printk("msp3410[%d]: daemon started\n",msp->nr); if(msp->notify != NULL) up(msp->notify); @@ -1022,10 +1035,10 @@ if (msp->rmmod) goto done; if (debug > 1) - printk("msp3410: thread: sleep\n"); + printk("msp3410[%d]: thread: sleep\n",msp->nr); interruptible_sleep_on(&msp->wq); if (debug > 1) - printk("msp3410: thread: wakeup\n"); + printk("msp3410[%d]: thread: wakeup\n",msp->nr); if (msp->rmmod || signal_pending(current)) goto done; @@ -1087,7 +1100,7 @@ for (i = 0; modelist[i].name != NULL; i++) if (modelist[i].retval == std) break; - printk("msp3410: setting mode: %s (0x%04x)\n", + printk("msp3410[%d]: setting mode: %s (0x%04x)\n",msp->nr, modelist[i].name ? modelist[i].name : "unknown",std); } @@ -1108,13 +1121,13 @@ val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); if (val < 0x07ff) break; - dprintk("msp3410: detection still in progress\n"); + dprintk("msp3410[%d]: detection still in progress\n",msp->nr); } } for (i = 0; modelist[i].name != NULL; i++) if (modelist[i].retval == val) break; - dprintk("msp3410: current mode: %s (0x%04x)\n", + dprintk("msp3410[%d]: current mode: %s (0x%04x)\n",msp->nr, modelist[i].name ? modelist[i].name : "unknown", val); msp->main = modelist[i].main; @@ -1122,7 +1135,8 @@ if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { /* autodetection has failed, let backup */ - dprintk("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)\n", + dprintk("msp3410[%d]: autodetection failed, " + "switching to backup mode: %s (0x%04x)\n", msp->nr, modelist[8].name ? modelist[8].name : "unknown",val); val = 0x0009; msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val); @@ -1194,7 +1208,7 @@ } done: - dprintk("msp3410: thread: exit\n"); + dprintk("msp3410[%d]: thread: exit\n",msp->nr); msp->active = 0; msp->thread = NULL; @@ -1232,13 +1246,13 @@ DECLARE_MUTEX_LOCKED(sem); struct msp3400c *msp; struct i2c_client *c; - int rev1,rev2,i; + int rev1,rev2,i,nr; client_template.adapter = adap; client_template.addr = addr; if (-1 == msp3400c_reset(&client_template)) { - dprintk("msp3400: no chip found\n"); + dprintk("msp3400: no chip found at 0x%x\n", addr); return -1; } @@ -1251,6 +1265,15 @@ } memset(msp,0,sizeof(struct msp3400c)); + + /* Find a instance number */ + for (nr = 0; nr < MSP3400_MAX; nr++) { + if (NULL == msps[nr]) { + break; + } + } + + msp->nr = nr; msp->left = 65535; msp->right = 65535; msp->bass = 32768; @@ -1262,8 +1285,8 @@ init_waitqueue_head(&msp->wq); if (-1 == msp3400c_reset(c)) { + dprintk("msp3400[%d]: no chip found\n", nr); kfree(msp); - dprintk("msp3400: no chip found\n"); return -1; } @@ -1271,8 +1294,8 @@ if (-1 != rev1) rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); if ((-1 == rev1) || (0 == rev1 && 0 == rev2)) { + printk("msp3400[%d]: error while reading chip version\n", nr); kfree(msp); - printk("msp3400: error while reading chip version\n"); return -1; } @@ -1281,17 +1304,21 @@ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0014, 0x1040); #endif - sprintf(c->name,"MSP34%02d%c-%c%d", - (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); + sprintf(c->name,"MSP34%02d%c-%c%d[%d]", + (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f, nr); msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0; if (simple == -1) { /* default mode */ /* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */ msp->simple = ((rev1&0xff)+'@' > 'C'); + printk("msp3400[%d]: %s simple mode (sensed)\n", + nr, msp->simple ? "Using" : "Not using"); } else { /* use insmod option */ msp->simple = simple; + printk("msp3400[%d]: %s simple mode (option setting)\n", + nr, simple ? "Using" : "Not using"); } /* timer for stereo checking */ @@ -1299,7 +1326,7 @@ msp->wake_stereo.data = (unsigned long)msp; /* hello world :-) */ - printk(KERN_INFO "msp34xx: init: chip=%s",c->name); + printk(KERN_INFO "msp34xx[%d]: init: chip=%s",nr, c->name); if (msp->nicam) printk(", has NICAM support"); printk("\n"); @@ -1314,12 +1341,7 @@ wake_up_interruptible(&msp->wq); /* update our own array */ - for (i = 0; i < MSP3400_MAX; i++) { - if (NULL == msps[i]) { - msps[i] = c; - break; - } - } + msps[nr] = c; /* done */ i2c_attach_client(c); @@ -1345,6 +1367,7 @@ msp3400c_reset(client); /* update our own array */ + /* SLD: could perhaps use ->nr and save the loop */ for (i = 0; i < MSP3400_MAX; i++) { if (client == msps[i]) { msps[i] = NULL; @@ -1380,8 +1403,7 @@ /* scart switching - IN1 is often used for external input - Hauppauge uses IN2 for the radio */ - dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); - msp->scart = 0; + dprintk(KERN_DEBUG "msp34xx[%d]: AUDC_SET_INPUT(%d)\n",msp->nr,*sarg); switch (*sarg) { case AUDIO_RADIO: msp->stereo = 2; @@ -1396,6 +1418,7 @@ msp3400c_setstereo(client,msp->stereo); break; case AUDIO_TUNER: + msp->scart = 0; msp3400c_setstereo(client,msp->stereo); /* SLD: Run the detection thread now to find the audio */ msp3400c_setvolume(client,msp->muted,0,0); @@ -1422,7 +1445,7 @@ msp->norm = VIDEO_MODE_RADIO; msp->watch_stereo=0; del_timer(&msp->wake_stereo); - dprintk("msp34xx: switching to radio mode\n"); + dprintk("msp34xx[%d]: switching to radio mode\n", msp->nr); if (msp->simple) { /* the thread will do for us */ msp3400c_setvolume(client,msp->muted,0,0); @@ -1518,7 +1541,7 @@ { struct video_channel *vc = arg; - dprintk("msp34xx: switching to TV mode\n"); + dprintk("msp34xx[%d]: switching to TV mode\n", msp->nr); msp->norm = vc->norm; break; }