static int adv7170_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adv7170 *encoder; int i; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; encoder->norm = VIDEO_MODE_NTSC; encoder->input = 0; encoder->enable = 1; i2c_set_clientdata(client, encoder); i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (i >= 0) { i = adv7170_write(client, 0x07, TR0MODE | TR0RST); i = adv7170_write(client, 0x07, TR0MODE); i = adv7170_read(client, 0x12); v4l_dbg(1, debug, client, "revision %d\n", i & 1); } if (i < 0) v4l_dbg(1, debug, client, "init error 0x%x\n", i); return 0; }
static void msp3400c_print_mode(struct i2c_client *client) { struct msp_state *state = to_state(i2c_get_clientdata(client)); if (state->main == state->second) v4l_dbg(1, msp_debug, client, "mono sound carrier: %d.%03d MHz\n", state->main / 910000, (state->main / 910) % 1000); else v4l_dbg(1, msp_debug, client, "main sound carrier: %d.%03d MHz\n", state->main / 910000, (state->main / 910) % 1000); if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2) v4l_dbg(1, msp_debug, client, "NICAM/FM carrier : %d.%03d MHz\n", state->second / 910000, (state->second/910) % 1000); if (state->mode == MSP_MODE_AM_NICAM) v4l_dbg(1, msp_debug, client, "NICAM/AM carrier : %d.%03d MHz\n", state->second / 910000, (state->second / 910) % 1000); if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) { v4l_dbg(1, msp_debug, client, "FM-stereo carrier : %d.%03d MHz\n", state->second / 910000, (state->second / 910) % 1000); } }
void msp3400c_set_mode(struct i2c_client *client, int mode) { struct msp_state *state = i2c_get_clientdata(client); struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; int tuner = (state->routing.input >> 3) & 1; int i; v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode); state->mode = mode; state->rxsubchans = V4L2_TUNER_SUB_MONO; msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0)); for (i = 5; i >= 0; i--) /* fir 1 */ msp_write_dem(client, 0x0001, data->fir1[i]); msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ msp_write_dem(client, 0x0005, 0x0040); msp_write_dem(client, 0x0005, 0x0000); for (i = 5; i >= 0; i--) msp_write_dem(client, 0x0005, data->fir2[i]); msp_write_dem(client, 0x0083, data->mode_reg); msp3400c_set_carrier(client, data->cdo1, data->cdo2); msp_set_source(client, data->dsp_src); /* set prescales */ /* volume prescale for SCART (AM mono input) */ msp_write_dsp(client, 0x000d, 0x1900); msp_write_dsp(client, 0x000e, data->dsp_matrix); if (state->has_nicam) /* nicam prescale */ msp_write_dsp(client, 0x0010, 0x5a00); }
static int tea6420_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; int err, i; /* let's see whether this adapter can support what we need */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) return -EIO; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); if (sd == NULL) return -ENOMEM; v4l2_i2c_subdev_init(sd, client, &tea6420_ops); /* set initial values: set "mute"-input to all outputs at gain 0 */ err = 0; for (i = 1; i < 5; i++) err += tea6420_s_routing(sd, 6, i, 0); if (err) { v4l_dbg(1, debug, client, "could not initialize tea6420\n"); return -ENODEV; } return 0; }
static int tea6420_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; int err, i; /* */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) return -EIO; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); if (sd == NULL) return -ENOMEM; v4l2_i2c_subdev_init(sd, client, &tea6420_ops); /* */ err = 0; for (i = 1; i < 5; i++) err += tea6420_s_routing(sd, 6, i, 0); if (err) { v4l_dbg(1, debug, client, "could not initialize tea6420\n"); return -ENODEV; } return 0; }
static int msp3400c_detect_stereo(struct i2c_client *client) { struct msp_state *state = to_state(i2c_get_clientdata(client)); int val; int rxsubchans = state->rxsubchans; int newnicam = state->nicam_on; int update = 0; switch (state->mode) { case MSP_MODE_FM_TERRA: val = msp_read_dsp(client, 0x18); if (val > 32767) val -= 65536; v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val); if (val > 8192) { rxsubchans = V4L2_TUNER_SUB_STEREO; } else if (val < -4096) { rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; } else { rxsubchans = V4L2_TUNER_SUB_MONO; } newnicam = 0; break; case MSP_MODE_FM_NICAM1: case MSP_MODE_FM_NICAM2: case MSP_MODE_AM_NICAM: val = msp_read_dem(client, 0x23); v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n", val & 1, (val & 0x1e) >> 1); if (val & 1) { /* nicam synced */ switch ((val & 0x1e) >> 1) { case 0: case 8: rxsubchans = V4L2_TUNER_SUB_STEREO; break; case 1: case 9: rxsubchans = V4L2_TUNER_SUB_MONO; break; case 2: case 10: rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; break; default: rxsubchans = V4L2_TUNER_SUB_MONO; break; } newnicam = 1; } else { newnicam = 0; rxsubchans = V4L2_TUNER_SUB_MONO; } break; }
static int cs53l32a_probe(struct i2c_client *client, const struct i2c_device_id *id) { int i; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; if (!id) strlcpy(client->name, "cs53l32a", sizeof(client->name)); v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); for (i = 1; i <= 7; i++) { u8 v = cs53l32a_read(client, i); v4l_dbg(1, debug, client, "Read Reg %d %02x\n", i, v); } /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ cs53l32a_write(client, 0x01, (u8) 0x21); cs53l32a_write(client, 0x02, (u8) 0x29); cs53l32a_write(client, 0x03, (u8) 0x30); cs53l32a_write(client, 0x04, (u8) 0x00); cs53l32a_write(client, 0x05, (u8) 0x00); cs53l32a_write(client, 0x06, (u8) 0x00); cs53l32a_write(client, 0x07, (u8) 0x00); /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */ for (i = 1; i <= 7; i++) { u8 v = cs53l32a_read(client, i); v4l_dbg(1, debug, client, "Read Reg %d %02x\n", i, v); } return 0; }
static int determine_norm(struct i2c_client *client) { DEFINE_WAIT(wait); struct saa7110 *decoder = i2c_get_clientdata(client); int status; /* mode changed, start automatic detection */ saa7110_write_block(client, initseq, sizeof(initseq)); saa7110_selmux(client, decoder->input); prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(250)); finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if (status & 0x40) { v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status); return decoder->norm; // no change } if ((status & 3) == 0) { saa7110_write(client, 0x06, 0x83); if (status & 0x20) { v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); //saa7110_write(client,0x2E,0x81); return VIDEO_MODE_NTSC; } v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); //saa7110_write(client,0x2E,0x9A); return VIDEO_MODE_PAL; } //saa7110_write(client,0x06,0x03); if (status & 0x20) { /* 60Hz */ v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status); saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client,0x2E,0x81); return VIDEO_MODE_NTSC; } /* 50Hz -> PAL/SECAM */ saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client,0x2E,0x9A); prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(250)); finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if ((status & 0x03) == 0x01) { v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); saa7110_write(client, 0x0D, 0x87); return VIDEO_MODE_SECAM; } v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); return VIDEO_MODE_PAL; }
void msp3400c_setmode(struct i2c_client *client, int type) { struct msp_state *state = i2c_get_clientdata(client); int i; v4l_dbg(1, msp_debug, client, "setmode: %d\n", type); state->mode = type; state->audmode = V4L2_TUNER_MODE_MONO; state->rxsubchans = V4L2_TUNER_SUB_MONO; msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv); for (i = 5; i >= 0; i--) /* fir 1 */ msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]); msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ msp_write_dem(client, 0x0005, 0x0040); msp_write_dem(client, 0x0005, 0x0000); for (i = 5; i >= 0; i--) msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]); msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg); msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1, msp3400c_init_data[type].cdo2); msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ if (msp_dolby) { msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); } else { msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src); msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src); msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); } msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src); msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix); if (state->has_nicam) { /* nicam prescale */ msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */ } }
static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs) { struct saa711x_state *state = i2c_get_clientdata(client); unsigned char reg, data; while (*regs != 0x00) { reg = *(regs++); data = *(regs++); /* According with datasheets, reserved regs should be filled with 0 - seems better not to touch on they */ if (saa711x_has_reg(state->ident,reg)) { if (saa711x_write(client, reg, data) < 0) return -1; } else { v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg); } } return 0; }
/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP, nor do they support stereo BTSC. */ static void msp3400c_set_audmode(struct i2c_client *client) { static char *strmode[] = { "mono", "stereo", "lang2", "lang1", "lang1+lang2" }; struct msp_state *state = i2c_get_clientdata(client); char *modestr = (state->audmode >= 0 && state->audmode < 5) ? strmode[state->audmode] : "unknown"; int src = 0; /* channel source: FM/AM, nicam or SCART */ int audmode = state->audmode; if (state->opmode == OPMODE_AUTOSELECT) { /* this method would break everything, let's make sure * it's never called */ v4l_dbg(1, msp_debug, client, "set_audmode called with mode=%d instead of set_source (ignored)\n", state->audmode); return; } /* Note: for the C and D revs no NTSC stereo + SAP is possible as the hardware does not support SAP. So the rxsubchans combination of STEREO | LANG2 does not occur. */ if (state->mode != MSP_MODE_EXTERN) { /* switch to mono if only mono is available */ if (state->rxsubchans == V4L2_TUNER_SUB_MONO) audmode = V4L2_TUNER_MODE_MONO; /* if bilingual */ else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { /* and mono or stereo, then fallback to lang1 */ if (audmode == V4L2_TUNER_MODE_MONO || audmode == V4L2_TUNER_MODE_STEREO) audmode = V4L2_TUNER_MODE_LANG1; } /* if stereo, and audmode is not mono, then switch to stereo */ else if (audmode != V4L2_TUNER_MODE_MONO) audmode = V4L2_TUNER_MODE_STEREO; } /* switch demodulator */ switch (state->mode) { case MSP_MODE_FM_TERRA: v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr); switch (audmode) { case V4L2_TUNER_MODE_STEREO: msp_write_dsp(client, 0x000e, 0x3001); break; case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_LANG1: case V4L2_TUNER_MODE_LANG2: case V4L2_TUNER_MODE_LANG1_LANG2: msp_write_dsp(client, 0x000e, 0x3000); break; } break; case MSP_MODE_FM_SAT: v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr); switch (audmode) { case V4L2_TUNER_MODE_MONO: msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); break; case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); break; case V4L2_TUNER_MODE_LANG1: msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); break; case V4L2_TUNER_MODE_LANG2: msp3400c_set_carrier(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: v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr); if (state->nicam_on) src = 0x0100; /* NICAM */ break; case MSP_MODE_BTSC: v4l_dbg(1, msp_debug, client, "BTSC set_audmode: %s\n",modestr); break; case MSP_MODE_EXTERN: v4l_dbg(1, msp_debug, client, "extern set_audmode: %s\n",modestr); src = 0x0200; /* SCART */ break; case MSP_MODE_FM_RADIO: v4l_dbg(1, msp_debug, client, "FM-Radio set_audmode: %s\n",modestr); break; default: v4l_dbg(1, msp_debug, client, "mono set_audmode\n"); return; } /* switch audio */ v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode); switch (audmode) { case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: src |= 0x0020; break; case V4L2_TUNER_MODE_MONO: if (state->mode == MSP_MODE_AM_NICAM) { v4l_dbg(1, msp_debug, client, "switching to AM mono\n"); /* AM mono decoding is handled by tuner, not MSP chip */ /* SCART switching control register */ msp_set_scart(client, SCART_MONO, 0); src = 0x0200; break; } if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) src = 0x0030; break; case V4L2_TUNER_MODE_LANG1: break; case V4L2_TUNER_MODE_LANG2: src |= 0x0010; break; } v4l_dbg(1, msp_debug, client, "set_audmode final source/matrix = 0x%x\n", src); msp_set_source(client, src); }
/* makes a connection between the input-pin 'i' and the output-pin 'o' for the tea6415c-client 'client' */ static int switch_matrix(struct i2c_client *client, int i, int o) { u8 byte = 0; int ret; v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); /* check if the pins are valid */ if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o))) return -1; /* to understand this, have a look at the tea6415c-specs (p.5) */ switch (o) { case 18: byte = 0x00; break; case 14: byte = 0x20; break; case 16: byte = 0x10; break; case 17: byte = 0x08; break; case 15: byte = 0x18; break; case 13: byte = 0x28; break; }; switch (i) { case 5: byte |= 0x00; break; case 8: byte |= 0x04; break; case 3: byte |= 0x02; break; case 20: byte |= 0x06; break; case 6: byte |= 0x01; break; case 10: byte |= 0x05; break; case 1: byte |= 0x03; break; case 11: byte |= 0x07; break; }; ret = i2c_smbus_write_byte(client, byte); if (ret) { v4l_dbg(1, debug, client, "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } return ret; }
static int saa7110_command (struct i2c_client *client, unsigned int cmd, void *arg) { struct saa7110 *decoder = i2c_get_clientdata(client); int v; switch (cmd) { case 0: //saa7110_write_block(client, initseq, sizeof(initseq)); break; case DECODER_GET_CAPABILITIES: { struct video_decoder_capability *dc = arg; dc->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; dc->inputs = SAA7110_MAX_INPUT; dc->outputs = SAA7110_MAX_OUTPUT; break; } case DECODER_GET_STATUS: { int status; int res = 0; status = saa7110_read(client); v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", status, decoder->norm); if (!(status & 0x40)) res |= DECODER_STATUS_GOOD; if (status & 0x03) res |= DECODER_STATUS_COLOR; switch (decoder->norm) { case VIDEO_MODE_NTSC: res |= DECODER_STATUS_NTSC; break; case VIDEO_MODE_PAL: res |= DECODER_STATUS_PAL; break; case VIDEO_MODE_SECAM: res |= DECODER_STATUS_SECAM; break; } *(int *) arg = res; break; } case DECODER_SET_NORM: v = *(int *) arg; if (decoder->norm != v) { decoder->norm = v; //saa7110_write(client, 0x06, 0x03); switch (v) { case VIDEO_MODE_NTSC: saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client, 0x2E, 0x81); v4l_dbg(1, debug, client, "switched to NTSC\n"); break; case VIDEO_MODE_PAL: saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); v4l_dbg(1, debug, client, "switched to PAL\n"); break; case VIDEO_MODE_SECAM: saa7110_write(client, 0x0D, 0x87); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); v4l_dbg(1, debug, client, "switched to SECAM\n"); break; case VIDEO_MODE_AUTO: v4l_dbg(1, debug, client, "switched to AUTO\n"); decoder->norm = determine_norm(client); *(int *) arg = decoder->norm; break; default: return -EPERM; } } break; case DECODER_SET_INPUT: v = *(int *) arg; if (v < 0 || v > SAA7110_MAX_INPUT) { v4l_dbg(1, debug, client, "input=%d not available\n", v); return -EINVAL; } if (decoder->input != v) { saa7110_selmux(client, v); v4l_dbg(1, debug, client, "switched to input=%d\n", v); } break; case DECODER_SET_OUTPUT: v = *(int *) arg; /* not much choice of outputs */ if (v != 0) return -EINVAL; break; case DECODER_ENABLE_OUTPUT: v = *(int *) arg; if (decoder->enable != v) { decoder->enable = v; saa7110_write(client, 0x0E, v ? 0x18 : 0x80); v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off"); } break; case DECODER_SET_PICTURE: { struct video_picture *pic = arg; if (decoder->bright != pic->brightness) { /* We want 0 to 255 we get 0-65535 */ decoder->bright = pic->brightness; saa7110_write(client, 0x19, decoder->bright >> 8); } if (decoder->contrast != pic->contrast) { /* We want 0 to 127 we get 0-65535 */ decoder->contrast = pic->contrast; saa7110_write(client, 0x13, decoder->contrast >> 9); } if (decoder->sat != pic->colour) { /* We want 0 to 127 we get 0-65535 */ decoder->sat = pic->colour; saa7110_write(client, 0x12, decoder->sat >> 9); }
int autodetect_stereo(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); int val; int rxsubchans = state->rxsubchans; int newnicam = state->nicam_on; int update = 0; switch (state->mode) { case MSP_MODE_FM_TERRA: val = msp_read_dsp(client, 0x18); if (val > 32767) val -= 65536; v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val); if (val > 4096) { rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; } else if (val < -4096) { rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; } else { rxsubchans = V4L2_TUNER_SUB_MONO; } newnicam = 0; break; case MSP_MODE_FM_NICAM1: case MSP_MODE_FM_NICAM2: case MSP_MODE_AM_NICAM: val = msp_read_dem(client, 0x23); v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n", val & 1, (val & 0x1e) >> 1); if (val & 1) { /* nicam synced */ switch ((val & 0x1e) >> 1) { case 0: case 8: rxsubchans = V4L2_TUNER_SUB_STEREO; break; case 1: case 9: rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_LANG1; break; case 2: case 10: rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; break; default: rxsubchans = V4L2_TUNER_SUB_MONO; break; } newnicam = 1; } else { newnicam = 0; rxsubchans = V4L2_TUNER_SUB_MONO; } break; case MSP_MODE_BTSC: val = msp_read_dem(client, 0x200); v4l_dbg(2, msp_debug, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n", val, (val & 0x0002) ? "no" : "yes", (val & 0x0004) ? "no" : "yes", (val & 0x0040) ? "stereo" : "mono", (val & 0x0080) ? ", nicam 2nd mono" : "", (val & 0x0100) ? ", bilingual/SAP" : ""); rxsubchans = V4L2_TUNER_SUB_MONO; if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; break; }
/* turn on/off nicam + stereo */ void msp3400c_setstereo(struct i2c_client *client, int mode) { static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; struct msp_state *state = i2c_get_clientdata(client); int nicam = 0; /* channel source: FM/AM or nicam */ int src = 0; if (state->opmode == OPMODE_AUTOSELECT) { /* this method would break everything, let's make sure * it's never called */ v4l_dbg(1, msp_debug, client, "setstereo called with mode=%d instead of set_source (ignored)\n", mode); return; } /* switch demodulator */ switch (state->mode) { case MSP_MODE_FM_TERRA: v4l_dbg(1, msp_debug, client, "FM setstereo: %s\n", strmode[mode]); msp3400c_setcarrier(client, state->second, state->main); switch (mode) { case V4L2_TUNER_MODE_STEREO: msp_write_dsp(client, 0x000e, 0x3001); break; case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_LANG1: case V4L2_TUNER_MODE_LANG2: msp_write_dsp(client, 0x000e, 0x3000); break; } break; case MSP_MODE_FM_SAT: v4l_dbg(1, msp_debug, client, "SAT setstereo: %s\n", strmode[mode]); switch (mode) { case V4L2_TUNER_MODE_MONO: msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); break; case V4L2_TUNER_MODE_STEREO: msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); break; case V4L2_TUNER_MODE_LANG1: msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); break; case V4L2_TUNER_MODE_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: v4l_dbg(1, msp_debug, client, "NICAM setstereo: %s\n",strmode[mode]); msp3400c_setcarrier(client,state->second,state->main); if (state->nicam_on) nicam=0x0100; break; case MSP_MODE_BTSC: v4l_dbg(1, msp_debug, client, "BTSC setstereo: %s\n",strmode[mode]); nicam=0x0300; break; case MSP_MODE_EXTERN: v4l_dbg(1, msp_debug, client, "extern setstereo: %s\n",strmode[mode]); nicam = 0x0200; break; case MSP_MODE_FM_RADIO: v4l_dbg(1, msp_debug, client, "FM-Radio setstereo: %s\n",strmode[mode]); break; default: v4l_dbg(1, msp_debug, client, "mono setstereo\n"); return; } /* switch audio */ switch (mode) { case V4L2_TUNER_MODE_STEREO: src = 0x0020 | nicam; break; case V4L2_TUNER_MODE_MONO: if (state->mode == MSP_MODE_AM_NICAM) { v4l_dbg(1, msp_debug, client, "switching to AM mono\n"); /* AM mono decoding is handled by tuner, not MSP chip */ /* SCART switching control register */ msp_set_scart(client, SCART_MONO, 0); src = 0x0200; break; } case V4L2_TUNER_MODE_LANG1: src = 0x0000 | nicam; break; case V4L2_TUNER_MODE_LANG2: src = 0x0010 | nicam; break; } v4l_dbg(1, msp_debug, client, "setstereo final source/matrix = 0x%x\n", src); if (msp_dolby) { msp_write_dsp(client, 0x0008, 0x0520); msp_write_dsp(client, 0x0009, 0x0620); msp_write_dsp(client, 0x000a, src); msp_write_dsp(client, 0x000b, src); } else { msp_write_dsp(client, 0x0008, src); msp_write_dsp(client, 0x0009, src); msp_write_dsp(client, 0x000a, src); msp_write_dsp(client, 0x000b, src); msp_write_dsp(client, 0x000c, src); if (state->has_scart23_in_scart2_out) msp_write_dsp(client, 0x0041, src); } }
static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) { struct adv7170 *encoder = i2c_get_clientdata(client); switch (cmd) { case 0: #if 0 /* This is just for testing!!! */ adv7170_write_block(client, init_common, sizeof(init_common)); adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); #endif break; case ENCODER_GET_CAPABILITIES: { struct video_encoder_capability *cap = arg; cap->flags = VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC; cap->inputs = 2; cap->outputs = 1; break; } case ENCODER_SET_NORM: { int iarg = *(int *) arg; v4l_dbg(1, debug, client, "set norm %d\n", iarg); switch (iarg) { case VIDEO_MODE_NTSC: adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (encoder->input == 0) adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); break; case VIDEO_MODE_PAL: adv7170_write_block(client, init_PAL, sizeof(init_PAL)); if (encoder->input == 0) adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); break; default: v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); return -EINVAL; } v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); encoder->norm = iarg; break; } case ENCODER_SET_INPUT: { int iarg = *(int *) arg; /* RJ: *iarg = 0: input is from decoder *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ v4l_dbg(1, debug, client, "set input from %s\n", iarg == 0 ? "decoder" : "ZR36060"); switch (iarg) { case 0: adv7170_write(client, 0x01, 0x20); adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); /* udelay(10); */ break; case 1: adv7170_write(client, 0x01, 0x00); adv7170_write(client, 0x08, TR1PLAY); /* TR1 */ adv7170_write(client, 0x02, 0x08); adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); /* udelay(10); */ break; default: v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); return -EINVAL; } v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); encoder->input = iarg; break; } case ENCODER_SET_OUTPUT: { int *iarg = arg; /* not much choice of outputs */ if (*iarg != 0) { return -EINVAL; } break; } case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; break; } default: return -EINVAL; } return 0; }