static void msp3400c_setcarrier(bktr_ptr_t client, int cdo1, int cdo2) { msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff); msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12); msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff); msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12); msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ }
//---------------------------- msp3400c_setcarrier ----------------------------- static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) { msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff); msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12); msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff); msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12); msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); // LOAD_REG_1/2 }
static void msp3400c_settreble(bktr_ptr_t client, int treble) { int val = ((treble-32768) * 0x60 / 65535) << 8; dprintk("msp34xx: settreble: %d 0x%02x\n",treble, val>>8); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ }
static void msp3400c_setbass(bktr_ptr_t client, int bass) { int val = ((bass-32768) * 0x60 / 65535) << 8; dprintk("msp34xx: setbass: %d 0x%02x\n",bass, val>>8); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ }
static void msp3400c_settreble(struct i2c_client *client, int treble) { int val = ((treble-32768) * 0x60 / 65535) << 8; dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ }
static void msp3400c_setbass(struct i2c_client *client, int bass) { int val = ((bass-32768) * 0x60 / 65535) << 8; dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ }
//----------------------------- msp3400c_setvolume ----------------------------- static void msp3400c_setvolume(struct i2c_client *client ,int muted,int left,int right) { int vol=0,val=0,balance=0; if(!muted) { vol=(left>right) ? left : right; val=(vol * 0x73 /65535)<<8; } if(vol>0) balance=((right-left)*127)/vol; CPK(printk("msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n" ,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 // scart - on/off only msp3400c_write(client,I2C_MSP3400C_DFP,0x0007,val ? 0x4000 : 0); msp3400c_write(client,I2C_MSP3400C_DFP,0x0001,balance << 8); }
//----------------------------- msp3400c_set_scart ----------------------------- static void msp3400c_set_scart(struct i2c_client *client,int in,int out) { struct msp3400c *msp=(struct msp3400c*)i2c_get_clientdata(client); if(-1==scarts[out][in]) return; CPK(printk("msp34xx: scart switch: %s => %d\n",scart_names[in],out)); msp->acb&=~scarts[out][SCART_MASK]; msp->acb|= scarts[out][in]; msp3400c_write(client,I2C_MSP3400C_DFP,0x0013,msp->acb); }
//---------------------------- msp3400c_restore_dfp ---------------------------- static void msp3400c_restore_dfp(struct i2c_client *client) { struct msp3400c *msp=(struct msp3400c*)i2c_get_clientdata(client); int i; for(i=0;i<DFP_COUNT;i++) { if(-1==msp->dfp_regs[i]) continue; msp3400c_write(client,I2C_MSP3400C_DFP,i,msp->dfp_regs[i]); } }
static void msp3400c_setvolume(struct i2c_client *client, int muted, int volume, int balance) { int val = 0, bal = 0; if (!muted) { val = (volume * 0x73 / 65535) << 8; } if (val) { bal = (balance / 256) - 128; } dprintk(KERN_DEBUG "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", muted ? "on" : "off", volume, balance, val>>8, bal); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ /* scart - on/off only */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); }
static void msp3400c_restore_dfp(bktr_ptr_t client) { struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; int i; for (i = 0; i < DFP_COUNT; i++) { if (-1 == msp->dfp_regs[i]) continue; msp3400c_write(client,I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); } }
static void msp3400c_setvolume(bktr_ptr_t client, int muted, int left, int right) { int vol = 0,val = 0,balance = 0; if (!muted) { vol = (left > right) ? left : right; val = (vol * 0x73 / 65535) << 8; } if (vol > 0) { balance = ((right-left) * 127) / vol; } dprintk("msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", 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 */ /* scart - on/off only */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, balance << 8); }
static void msp3400c_set_scart(bktr_ptr_t client, int in, int out) { struct msp3400c *msp = client->msp3400c_info; if (-1 == scarts[out][in]) return; dprintk("msp34xx: scart switch: %s => %d\n",scart_names[in],out); msp->acb &= ~scarts[out][SCART_MASK]; msp->acb |= scarts[out][in]; msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); }
/* turn on/off nicam + stereo */ static void msp3400c_setstereo(bktr_ptr_t client, int mode) { static char *strmode[] = { "0", "mono", "stereo", "3", "lang1", "5", "6", "7", "lang2" }; struct msp3400c *msp = client->msp3400c_info; 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: %s\n",strmode[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 MSP_MODE_FM_SAT: dprintk("msp3400: SAT setstereo: %s\n",strmode[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: NICAM setstereo: %s\n",strmode[mode]); msp3400c_setcarrier(client,msp->second,msp->main); if (msp->nicam_on) nicam=0x0100; break; case MSP_MODE_BTSC: dprintk("msp3400: BTSC setstereo: %s\n",strmode[mode]); nicam=0x0300; break; case MSP_MODE_EXTERN: dprintk("msp3400: extern setstereo: %s\n",strmode[mode]); nicam = 0x0200; break; case MSP_MODE_FM_RADIO: dprintk("msp3400: FM-Radio setstereo: %s\n",strmode[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; } dprintk("msp3400: setstereo final source/matrix = 0x%x\n", src); if (client->dolby) { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); } else { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); } }
static void msp3400c_setmode(bktr_ptr_t client, int type) { struct msp3400c *msp = client->msp3400c_info; int i; dprintk("msp3400: setmode: %d\n",type); msp->mode = type; msp->stereo = VIDEO_SOUND_MONO; msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */ msp_init_data[type].ad_cv); for (i = 5; i >= 0; i--) /* fir 1 */ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001, msp_init_data[type].fir1[i]); msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */ msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040); msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000); for (i = 5; i >= 0; i--) msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, msp_init_data[type].fir2[i]); msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */ msp_init_data[type].mode_reg); msp3400c_setcarrier(client, msp_init_data[type].cdo1, msp_init_data[type].cdo2); msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ if (client->dolby) { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, 0x0520); /* I2S1 */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, 0x0620); /* I2S2 */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, msp_init_data[type].dfp_src); } else { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, msp_init_data[type].dfp_src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, msp_init_data[type].dfp_src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, msp_init_data[type].dfp_src); } msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a, msp_init_data[type].dfp_src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, msp_init_data[type].dfp_matrix); if (msp->nicam) { /* nicam prescale */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */ } }
//----------------------------- msp3400c_setstereo ----------------------------- static void msp3400c_setstereo(struct i2c_client *client, int mode) { /* static char *strmode[16] = { #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 = (struct msp3400c*) i2c_get_clientdata(client); int nicam=0; /* channel source: FM/AM or nicam */ int src=0; /* switch demodulator */ switch (msp->mode) { case MSP_MODE_FM_TERRA: CPK(dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n",strmode[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 MSP_MODE_FM_SAT: CPK(dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n",strmode[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: CPK(dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n",strmode[mode])); msp3400c_setcarrier(client,msp->second,msp->main); if (msp->nicam_on) nicam=0x0100; break; case MSP_MODE_BTSC: CPK(dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n",strmode[mode])); nicam=0x0300; break; case MSP_MODE_EXTERN: CPK(dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n",strmode[mode])); nicam = 0x0200; break; case MSP_MODE_FM_RADIO: CPK(dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n",strmode[mode])); break; default: CPK(dprintk(KERN_DEBUG "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) { CPK(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; } CPK(dprintk(KERN_DEBUG "msp3400: setstereo final source/matrix = 0x%x\n", src)); if (dolby) { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); } else { msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); } }