18 #include <linux/module.h>
20 #include <linux/i2c.h>
21 #include <linux/videodev2.h>
22 #include <linux/slab.h>
34 #define IF_I2C_ADDR 0x43
35 #define MPX_I2C_ADDR 0x44
38 static char force_band_str[] =
"-";
40 static int force_mpx_mode = -1;
61 {
"Sony PAL+SECAM (BTF-PG472Z)", 0, 0,
62 16*144.25, 16*427.25, 0x01, 0x02, 0x04, 0xc6, 623},
63 {
"Sony NTSC_JP (BTF-PK467Z)", 0, 0,
64 16*220.25, 16*467.25, 0x01, 0x02, 0x04, 0xc6, 940},
65 {
"Sony NTSC (BTF-PB463Z)", 0, 0,
66 16*130.25, 16*364.25, 0x01, 0x02, 0x04, 0xc6, 732},
87 tun = &sony_tuners[t->
type - 200];
90 band_select = tun->
VHF_L;
91 }
else if (freq < tun->
thresh2) {
93 band_select = tun->
VHF_H;
96 band_select = tun->
UHF;
99 freq / 16, (freq % 16) * 625, band_name);
103 buffer[1] = n & 0xff;
105 buffer[3] = band_select;
117 buffer[1] = addr >> 8;
118 buffer[2] = addr & 0xff;
119 buffer[3] = val >> 8;
120 buffer[4] = val & 0xff;
181 enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L }
audio_mode;
190 } mpx_audio_modes[] = {
191 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
192 0x5000, 0x0000, 0x0001, 0x7500 },
193 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
194 0x5000, 0x0000, 0x0003, 0x7500 },
195 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
196 0x5000, 0x0000, 0x0003, 0x7500 },
197 { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
198 0x5000, 0x0000, 0x0008, 0x7500 },
199 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
200 0x7900, 0x0000, 0x000A, 0x7500 },
201 { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
202 0x7900, 0x0000, 0x000A, 0x7500 },
203 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
204 0x5000, 0x0000, 0x0004, 0x7500 },
205 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
206 0x5000, 0x0000, 0x0004, 0x7500 },
207 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
208 0x5000, 0x0000, 0x0005, 0x7500 },
209 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
210 0x5000, 0x0000, 0x0007, 0x7500 },
211 { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
212 0x5000, 0x0000, 0x000B, 0x7500 },
213 { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
214 0x5000, 0x2200, 0x0009, 0x7500 },
215 { AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
216 0x5000, 0x0000, 0x0009, 0x7500 },
219 #define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
221 static int mpx_setup(
struct i2c_client *client)
240 if (mpx_audio_modes[t->
mpxmode].audio_mode != AUD_MONO) {
243 switch (mpx_audio_modes[t->
mpxmode].audio_mode) {
245 source = mpx_audio_modes[t->
mpxmode].source;
258 source = mpx_audio_modes[t->
mpxmode].source;
267 source |= mpx_audio_modes[t->
mpxmode].source & 0x00ff;
269 source = mpx_audio_modes[t->
mpxmode].source;
271 mpx_write(client, 0x10, 0x0030, mpx_audio_modes[t->
mpxmode].modus);
272 mpx_write(client, 0x12, 0x0008, source);
273 mpx_write(client, 0x12, 0x0013, mpx_audio_modes[t->
mpxmode].acb);
274 mpx_write(client, 0x12, 0x000e,
275 mpx_audio_modes[t->
mpxmode].fm_prescale);
276 mpx_write(client, 0x12, 0x0010,
277 mpx_audio_modes[t->
mpxmode].nicam_prescale);
278 mpx_write(client, 0x12, 0x000d,
279 mpx_audio_modes[t->
mpxmode].scart_prescale);
280 mpx_write(client, 0x10, 0x0020, mpx_audio_modes[t->
mpxmode].system);
281 mpx_write(client, 0x12, 0x0000, mpx_audio_modes[t->
mpxmode].volume);
282 if (mpx_audio_modes[t->
mpxmode].audio_mode == AUD_A2)
283 mpx_write(client, 0x10, 0x0022,
292 "%04x %04x %04x %04x %04x %04x\n",
293 mpx_audio_modes[t->
mpxmode].modus,
295 mpx_audio_modes[t->
mpxmode].acb,
296 mpx_audio_modes[t->
mpxmode].fm_prescale,
297 mpx_audio_modes[t->
mpxmode].nicam_prescale,
298 mpx_audio_modes[t->
mpxmode].scart_prescale,
299 mpx_audio_modes[t->
mpxmode].system,
300 mpx_audio_modes[t->
mpxmode].volume);
342 int default_mpx_mode = 0;
350 default_mpx_mode = 1;
355 default_mpx_mode = 4;
360 default_mpx_mode = 6;
365 default_mpx_mode = 11;
385 static int tuner_command(
struct i2c_client *client,
unsigned int cmd,
void *
arg)
391 #ifdef TUNER_SET_TYPE_ADDR
392 case TUNER_SET_TYPE_ADDR:
394 struct tuner_setup *tun_setup =
arg;
395 int *
type = &tun_setup->type;
403 if (t->
type != *type)
405 "set to %d, ignoring request for %d\n",
412 switch (force_band_str[0]) {
418 "tuner to PAL-B/G bands\n");
424 "tuner to PAL-I band\n");
432 "tuner to PAL-D/K bands\n");
438 "tuner to SECAM-L band\n");
459 "supported by this module\n", *type);
464 "wis-sony-tuner: type set to %d (%s)\n",
481 set_freq(client, t->
freq);
490 switch (std->
index) {
513 if (std->
index != 0) {
521 if (std->
index != 0) {
544 if (force_band && (*std & force_band) != *std &&
548 "requested TV standard in "
549 "favor of force_band value\n");
594 *std = V4L2_STD_PAL_BG | V4L2_STD_PAL_I |
610 memset(tun, 0,
sizeof(*tun));
657 static int wis_sony_tuner_probe(
struct i2c_client *client,
674 i2c_set_clientdata(client, t);
677 "wis-sony-tuner: initializing tuner at address %d on %s\n",
683 static int wis_sony_tuner_remove(
struct i2c_client *client)
692 {
"wis_sony_tuner", 0 },
697 static struct i2c_driver wis_sony_tuner_driver = {
699 .name =
"WIS Sony TV Tuner I2C driver",
701 .probe = wis_sony_tuner_probe,
702 .remove = wis_sony_tuner_remove,
703 .command = tuner_command,
704 .id_table = wis_sony_tuner_id,
707 static int __init wis_sony_tuner_init(
void)
709 return i2c_add_driver(&wis_sony_tuner_driver);
712 static void __exit wis_sony_tuner_cleanup(
void)