1 #include <linux/module.h>
2 #include <linux/kernel.h>
4 #include <linux/types.h>
5 #include <linux/videodev.h>
6 #include <linux/init.h>
7 #include <linux/errno.h>
8 #include <linux/slab.h>
10 #include <media/audiochip.h>
15 TDA9886 (PAL, SECAM, NTSC)
16 TDA9887 (PAL, SECAM, NTSC, FM Radio)
19 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
20 TDA9887 (world), TDA9885 (USA)
21 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
22 - KNC One TV-Station RDS (saa7134)
26 /* Addresses to scan */
27 static unsigned short normal_i2c[] = {I2C_CLIENT_END};
28 static unsigned short normal_i2c_range[] = {0x86>>1,0x86>>1,I2C_CLIENT_END};
33 static char *pal = "b";
34 static char *secam = "l";
35 MODULE_PARM(debug,"i");
37 MODULE_PARM(secam,"s");
38 MODULE_LICENSE("GPL");
40 /* ---------------------------------------------------------------------- */
42 #define dprintk if (debug) printk
45 struct i2c_client client;
50 static struct i2c_driver driver;
51 static struct i2c_client client_template;
53 /* ---------------------------------------------------------------------- */
60 #define cVideoTrapBypassOFF 0x00 // bit b0
61 #define cVideoTrapBypassON 0x01 // bit b0
63 #define cAutoMuteFmInactive 0x00 // bit b1
64 #define cAutoMuteFmActive 0x02 // bit b1
66 #define cIntercarrier 0x00 // bit b2
67 #define cQSS 0x04 // bit b2
69 #define cPositiveAmTV 0x00 // bit b3:4
70 #define cFmRadio 0x08 // bit b3:4
71 #define cNegativeFmTV 0x10 // bit b3:4
74 #define cForcedMuteAudioON 0x20 // bit b5
75 #define cForcedMuteAudioOFF 0x00 // bit b5
77 #define cOutputPort1Active 0x00 // bit b6
78 #define cOutputPort1Inactive 0x40 // bit b6
80 #define cOutputPort2Active 0x00 // bit b7
81 #define cOutputPort2Inactive 0x80 // bit b7
85 #define cDeemphasisOFF 0x00 // bit c5
86 #define cDeemphasisON 0x20 // bit c5
88 #define cDeemphasis75 0x00 // bit c6
89 #define cDeemphasis50 0x40 // bit c6
91 #define cAudioGain0 0x00 // bit c7
92 #define cAudioGain6 0x80 // bit c7
96 #define cAudioIF_4_5 0x00 // bit e0:1
97 #define cAudioIF_5_5 0x01 // bit e0:1
98 #define cAudioIF_6_0 0x02 // bit e0:1
99 #define cAudioIF_6_5 0x03 // bit e0:1
102 #define cVideoIF_58_75 0x00 // bit e2:4
103 #define cVideoIF_45_75 0x04 // bit e2:4
104 #define cVideoIF_38_90 0x08 // bit e2:4
105 #define cVideoIF_38_00 0x0C // bit e2:4
106 #define cVideoIF_33_90 0x10 // bit e2:4
107 #define cVideoIF_33_40 0x14 // bit e2:4
108 #define cRadioIF_45_75 0x18 // bit e2:4
109 #define cRadioIF_38_90 0x1C // bit e2:4
112 #define cTunerGainNormal 0x00 // bit e5
113 #define cTunerGainLow 0x20 // bit e5
115 #define cGating_18 0x00 // bit e6
116 #define cGating_36 0x40 // bit e6
118 #define cAgcOutON 0x80 // bit e7
119 #define cAgcOutOFF 0x00 // bit e7
121 static int tda9887_miro(struct tda9887 *t)
131 u8 bOutPort1 = cOutputPort1Inactive;
133 u8 bOutPort2 = cOutputPort2Inactive & mbTADState; // store i2c tuner state
135 u8 bOutPort2 = cOutputPort2Inactive;
137 u8 bVideoTrap = cVideoTrapBypassOFF;
139 u8 bTopAdjust = 0x0e /* -2dB */;
145 if (mParams.fVideoTrap)
146 bVideoTrap = cVideoTrapBypassON;
150 bVideoTrap = cVideoTrapBypassOFF;
152 bModulation = cFmRadio;
153 bOutPort1 = cOutputPort1Inactive;
154 bDeEmphasis = cDeemphasisON;
155 if (3 == t->pinnacle_id) {
157 bDeEmphVal = cDeemphasis75;
158 bAudioIF = cAudioIF_4_5;
159 bVideoIF = cRadioIF_45_75;
162 bAudioIF = cAudioIF_5_5;
163 bVideoIF = cRadioIF_38_90;
164 bDeEmphVal = cDeemphasis50;
167 } else if (t->tvnorm == VIDEO_MODE_PAL) {
168 bDeEmphasis = cDeemphasisON;
169 bDeEmphVal = cDeemphasis50;
170 bModulation = cNegativeFmTV;
171 bOutPort1 = cOutputPort1Inactive;
172 if (1 == t->pinnacle_id) {
173 bCarrierMode = cIntercarrier;
182 bVideoIF = cVideoIF_38_90;
183 bAudioIF = cAudioIF_5_5;
186 bVideoIF = cVideoIF_38_00;
187 bAudioIF = cAudioIF_6_5;
190 bVideoIF = cVideoIF_38_90;
191 bAudioIF = cAudioIF_6_0;
195 bVideoIF = cVideoIF_45_75;
196 bAudioIF = cAudioIF_4_5;
197 bDeEmphVal = cDeemphasis75;
198 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
199 bCarrierMode = cIntercarrier;
206 } else if (t->tvnorm == VIDEO_MODE_SECAM) {
207 bAudioIF = cAudioIF_6_5;
208 bDeEmphasis = cDeemphasisON;
209 bDeEmphVal = cDeemphasis50;
210 bModulation = cNegativeFmTV;
212 bOutPort1 = cOutputPort1Inactive;
215 bVideoIF = cVideoIF_38_00;
218 bVideoIF = cVideoIF_38_90;
221 bVideoIF = cVideoIF_38_90;
222 bDeEmphasis = cDeemphasisOFF;
223 bDeEmphVal = cDeemphasis75;
224 bModulation = cPositiveAmTV;
227 bVideoIF = cVideoIF_33_90;
228 bDeEmphasis = cDeemphasisOFF;
229 bDeEmphVal = cDeemphasis75;
230 bModulation = cPositiveAmTV;
234 } else if (t->tvnorm == VIDEO_MODE_NTSC) {
235 bVideoIF = cVideoIF_45_75;
236 bAudioIF = cAudioIF_4_5;
237 bDeEmphasis = cDeemphasisON;
238 bDeEmphVal = cDeemphasis75;
239 bModulation = cNegativeFmTV;
240 bOutPort1 = cOutputPort1Inactive;
241 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
242 bCarrierMode = cIntercarrier;
248 bData[1] = bVideoTrap | // B0: video trap bypass
249 cAutoMuteFmInactive | // B1: auto mute
250 bCarrierMode | // B2: InterCarrier for PAL else QSS
251 bModulation | // B3 - B4: positive AM TV for SECAM only
252 cForcedMuteAudioOFF | // B5: forced Audio Mute (off)
253 bOutPort1 | // B6: Out Port 1
254 bOutPort2; // B7: Out Port 2
255 bData[2] = bTopAdjust | // C0 - C4: Top Adjust 0 == -16dB 31 == 15dB
256 bDeEmphasis | // C5: De-emphasis on/off
257 bDeEmphVal | // C6: De-emphasis 50/75 microsec
258 cAudioGain0; // C7: normal audio gain
259 bData[3] = bAudioIF | // E0 - E1: Sound IF
260 bVideoIF | // E2 - E4: Video IF
261 cTunerGainNormal | // E5: Tuner gain (normal)
262 cGating_18 | // E6: Gating (18%)
263 cAgcOutOFF; // E7: VAGC (off)
265 dprintk("tda9885/6/7: 0x%02x 0x%02x 0x%02x [pinnacle_id=%d]\n",
266 bData[1],bData[2],bData[3],t->pinnacle_id);
267 if (4 != (rc = i2c_master_send(&t->client,bData,4)))
268 printk("tda9885/6/7: i2c i/o error: rc == %d (should be 4)\n",rc);
272 /* ---------------------------------------------------------------------- */
275 /* just for reference: old knc-one saa7134 stuff */
276 static unsigned char buf_pal_bg[] = { 0x00, 0x16, 0x70, 0x49 };
277 static unsigned char buf_pal_i[] = { 0x00, 0x16, 0x70, 0x4a };
278 static unsigned char buf_pal_dk[] = { 0x00, 0x16, 0x70, 0x4b };
279 static unsigned char buf_pal_l[] = { 0x00, 0x06, 0x50, 0x4b };
280 static unsigned char buf_fm_stereo[] = { 0x00, 0x0e, 0x0d, 0x77 };
283 static unsigned char buf_pal_bg[] = { 0x00, 0x96, 0x70, 0x49 };
284 static unsigned char buf_pal_i[] = { 0x00, 0x96, 0x70, 0x4a };
285 static unsigned char buf_pal_dk[] = { 0x00, 0x96, 0x70, 0x4b };
286 static unsigned char buf_pal_l[] = { 0x00, 0x86, 0x50, 0x4b };
287 static unsigned char buf_fm_stereo[] = { 0x00, 0x8e, 0x0d, 0x77 };
288 static unsigned char buf_ntsc[] = { 0x00, 0x96, 0x70, 0x44 };
289 static unsigned char buf_ntsc_jp[] = { 0x00, 0x96, 0x70, 0x40 };
291 static int tda9887_configure(struct tda9887 *t)
293 unsigned char *buf = NULL;
297 dprintk("tda9885/6/7: FM Radio mode\n");
300 } else if (t->tvnorm == VIDEO_MODE_PAL) {
301 dprintk("tda9885/6/7: PAL-%c mode\n",pal[0]);
319 } else if (t->tvnorm == VIDEO_MODE_NTSC) {
320 dprintk("tda9885/6/7: NTSC mode\n");
323 } else if (t->tvnorm == VIDEO_MODE_SECAM) {
324 dprintk("tda9885/6/7: SECAM mode\n");
327 } else if (t->tvnorm == 6 /* BTTV hack */) {
328 dprintk("tda9885/6/7: NTSC-Japan mode\n");
333 printk("tda9885/6/7 unknown norm=%d\n",t->tvnorm);
337 dprintk("tda9885/6/7: 0x%02x 0x%02x 0x%02x\n",
338 buf[1],buf[2],buf[3]);
339 if (4 != (rc = i2c_master_send(&t->client,buf,4)))
340 printk("tda9885/6/7: i2c i/o error: rc == %d (should be 4)\n",rc);
344 /* ---------------------------------------------------------------------- */
346 static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
350 client_template.adapter = adap;
351 client_template.addr = addr;
353 printk("tda9887: chip found @ 0x%x\n", addr<<1);
355 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
357 memset(t,0,sizeof(*t));
358 t->client = client_template;
360 t->tvnorm=VIDEO_MODE_PAL;
361 i2c_set_clientdata(&t->client, t);
362 i2c_attach_client(&t->client);
367 static int tda9887_probe(struct i2c_adapter *adap)
369 if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
370 return i2c_probe(adap, &addr_data, tda9887_attach);
374 static int tda9887_detach(struct i2c_client *client)
376 struct tda9887 *t = i2c_get_clientdata(client);
378 i2c_detach_client(client);
384 tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
386 struct tda9887 *t = i2c_get_clientdata(client);
390 /* --- configuration --- */
393 if (-1 != t->pinnacle_id)
396 tda9887_configure(t);
399 case AUDC_CONFIG_PINNACLE:
407 /* --- v4l ioctls --- */
408 /* take care: bttv does userspace copying, we'll get a
409 kernel pointer here... */
412 struct video_channel *vc = arg;
415 t->tvnorm = vc->norm;
416 if (-1 != t->pinnacle_id)
419 tda9887_configure(t);
429 /* ----------------------------------------------------------------------- */
431 static struct i2c_driver driver = {
432 .owner = THIS_MODULE,
433 .name = "i2c tda9887 driver",
434 .id = -1, /* FIXME */
435 .flags = I2C_DF_NOTIFY,
436 .attach_adapter = tda9887_probe,
437 .detach_client = tda9887_detach,
438 .command = tda9887_command,
440 static struct i2c_client client_template =
442 .flags = I2C_CLIENT_ALLOW_USE,
449 static int tda9887_init_module(void)
451 i2c_add_driver(&driver);
455 static void tda9887_cleanup_module(void)
457 i2c_del_driver(&driver);
460 module_init(tda9887_init_module);
461 module_exit(tda9887_cleanup_module);
464 * Overrides for Emacs so that we follow Linus's tabbing style.
465 * ---------------------------------------------------------------------------