[go: nahoru, domu]

1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/i2c.h>
4#include <linux/types.h>
5#include <linux/init.h>
6#include <linux/errno.h>
7#include <linux/delay.h>
8#include <linux/videodev2.h>
9#include <media/v4l2-common.h>
10#include <media/tuner.h>
11#include "tuner-i2c.h"
12#include "tda9887.h"
13
14
15/* Chips:
16   TDA9885 (PAL, NTSC)
17   TDA9886 (PAL, SECAM, NTSC)
18   TDA9887 (PAL, SECAM, NTSC, FM Radio)
19
20   Used as part of several tuners
21*/
22
23static int debug;
24module_param(debug, int, 0644);
25MODULE_PARM_DESC(debug, "enable verbose debug messages");
26
27static DEFINE_MUTEX(tda9887_list_mutex);
28static LIST_HEAD(hybrid_tuner_instance_list);
29
30struct tda9887_priv {
31	struct tuner_i2c_props i2c_props;
32	struct list_head hybrid_tuner_instance_list;
33
34	unsigned char 	   data[4];
35	unsigned int       config;
36	unsigned int       mode;
37	unsigned int       audmode;
38	v4l2_std_id        std;
39
40	bool               standby;
41};
42
43/* ---------------------------------------------------------------------- */
44
45#define UNSET       (-1U)
46
47struct tvnorm {
48	v4l2_std_id       std;
49	char              *name;
50	unsigned char     b;
51	unsigned char     c;
52	unsigned char     e;
53};
54
55/* ---------------------------------------------------------------------- */
56
57//
58// TDA defines
59//
60
61//// first reg (b)
62#define cVideoTrapBypassOFF     0x00    // bit b0
63#define cVideoTrapBypassON      0x01    // bit b0
64
65#define cAutoMuteFmInactive     0x00    // bit b1
66#define cAutoMuteFmActive       0x02    // bit b1
67
68#define cIntercarrier           0x00    // bit b2
69#define cQSS                    0x04    // bit b2
70
71#define cPositiveAmTV           0x00    // bit b3:4
72#define cFmRadio                0x08    // bit b3:4
73#define cNegativeFmTV           0x10    // bit b3:4
74
75
76#define cForcedMuteAudioON      0x20    // bit b5
77#define cForcedMuteAudioOFF     0x00    // bit b5
78
79#define cOutputPort1Active      0x00    // bit b6
80#define cOutputPort1Inactive    0x40    // bit b6
81
82#define cOutputPort2Active      0x00    // bit b7
83#define cOutputPort2Inactive    0x80    // bit b7
84
85
86//// second reg (c)
87#define cDeemphasisOFF          0x00    // bit c5
88#define cDeemphasisON           0x20    // bit c5
89
90#define cDeemphasis75           0x00    // bit c6
91#define cDeemphasis50           0x40    // bit c6
92
93#define cAudioGain0             0x00    // bit c7
94#define cAudioGain6             0x80    // bit c7
95
96#define cTopMask                0x1f    // bit c0:4
97#define cTopDefault		0x10 	// bit c0:4
98
99//// third reg (e)
100#define cAudioIF_4_5             0x00    // bit e0:1
101#define cAudioIF_5_5             0x01    // bit e0:1
102#define cAudioIF_6_0             0x02    // bit e0:1
103#define cAudioIF_6_5             0x03    // bit e0:1
104
105
106#define cVideoIFMask		0x1c	// bit e2:4
107/* Video IF selection in TV Mode (bit B3=0) */
108#define cVideoIF_58_75           0x00    // bit e2:4
109#define cVideoIF_45_75           0x04    // bit e2:4
110#define cVideoIF_38_90           0x08    // bit e2:4
111#define cVideoIF_38_00           0x0C    // bit e2:4
112#define cVideoIF_33_90           0x10    // bit e2:4
113#define cVideoIF_33_40           0x14    // bit e2:4
114#define cRadioIF_45_75           0x18    // bit e2:4
115#define cRadioIF_38_90           0x1C    // bit e2:4
116
117/* IF1 selection in Radio Mode (bit B3=1) */
118#define cRadioIF_33_30		0x00	// bit e2,4 (also 0x10,0x14)
119#define cRadioIF_41_30		0x04	// bit e2,4
120
121/* Output of AFC pin in radio mode when bit E7=1 */
122#define cRadioAGC_SIF		0x00	// bit e3
123#define cRadioAGC_FM		0x08	// bit e3
124
125#define cTunerGainNormal         0x00    // bit e5
126#define cTunerGainLow            0x20    // bit e5
127
128#define cGating_18               0x00    // bit e6
129#define cGating_36               0x40    // bit e6
130
131#define cAgcOutON                0x80    // bit e7
132#define cAgcOutOFF               0x00    // bit e7
133
134/* ---------------------------------------------------------------------- */
135
136static struct tvnorm tvnorms[] = {
137	{
138		.std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
139		.name  = "PAL-BGHN",
140		.b     = ( cNegativeFmTV  |
141			   cQSS           ),
142		.c     = ( cDeemphasisON  |
143			   cDeemphasis50  |
144			   cTopDefault),
145		.e     = ( cGating_36     |
146			   cAudioIF_5_5   |
147			   cVideoIF_38_90 ),
148	},{
149		.std   = V4L2_STD_PAL_I,
150		.name  = "PAL-I",
151		.b     = ( cNegativeFmTV  |
152			   cQSS           ),
153		.c     = ( cDeemphasisON  |
154			   cDeemphasis50  |
155			   cTopDefault),
156		.e     = ( cGating_36     |
157			   cAudioIF_6_0   |
158			   cVideoIF_38_90 ),
159	},{
160		.std   = V4L2_STD_PAL_DK,
161		.name  = "PAL-DK",
162		.b     = ( cNegativeFmTV  |
163			   cQSS           ),
164		.c     = ( cDeemphasisON  |
165			   cDeemphasis50  |
166			   cTopDefault),
167		.e     = ( cGating_36     |
168			   cAudioIF_6_5   |
169			   cVideoIF_38_90 ),
170	},{
171		.std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
172		.name  = "PAL-M/Nc",
173		.b     = ( cNegativeFmTV  |
174			   cQSS           ),
175		.c     = ( cDeemphasisON  |
176			   cDeemphasis75  |
177			   cTopDefault),
178		.e     = ( cGating_36     |
179			   cAudioIF_4_5   |
180			   cVideoIF_45_75 ),
181	},{
182		.std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
183		.name  = "SECAM-BGH",
184		.b     = ( cNegativeFmTV  |
185			   cQSS           ),
186		.c     = ( cTopDefault),
187		.e     = ( cAudioIF_5_5   |
188			   cVideoIF_38_90 ),
189	},{
190		.std   = V4L2_STD_SECAM_L,
191		.name  = "SECAM-L",
192		.b     = ( cPositiveAmTV  |
193			   cQSS           ),
194		.c     = ( cTopDefault),
195		.e     = ( cGating_36	  |
196			   cAudioIF_6_5   |
197			   cVideoIF_38_90 ),
198	},{
199		.std   = V4L2_STD_SECAM_LC,
200		.name  = "SECAM-L'",
201		.b     = ( cOutputPort2Inactive |
202			   cPositiveAmTV  |
203			   cQSS           ),
204		.c     = ( cTopDefault),
205		.e     = ( cGating_36	  |
206			   cAudioIF_6_5   |
207			   cVideoIF_33_90 ),
208	},{
209		.std   = V4L2_STD_SECAM_DK,
210		.name  = "SECAM-DK",
211		.b     = ( cNegativeFmTV  |
212			   cQSS           ),
213		.c     = ( cDeemphasisON  |
214			   cDeemphasis50  |
215			   cTopDefault),
216		.e     = ( cGating_36     |
217			   cAudioIF_6_5   |
218			   cVideoIF_38_90 ),
219	},{
220		.std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
221		.name  = "NTSC-M",
222		.b     = ( cNegativeFmTV  |
223			   cQSS           ),
224		.c     = ( cDeemphasisON  |
225			   cDeemphasis75  |
226			   cTopDefault),
227		.e     = ( cGating_36     |
228			   cAudioIF_4_5   |
229			   cVideoIF_45_75 ),
230	},{
231		.std   = V4L2_STD_NTSC_M_JP,
232		.name  = "NTSC-M-JP",
233		.b     = ( cNegativeFmTV  |
234			   cQSS           ),
235		.c     = ( cDeemphasisON  |
236			   cDeemphasis50  |
237			   cTopDefault),
238		.e     = ( cGating_36     |
239			   cAudioIF_4_5   |
240			   cVideoIF_58_75 ),
241	}
242};
243
244static struct tvnorm radio_stereo = {
245	.name = "Radio Stereo",
246	.b    = ( cFmRadio       |
247		  cQSS           ),
248	.c    = ( cDeemphasisOFF |
249		  cAudioGain6    |
250		  cTopDefault),
251	.e    = ( cTunerGainLow  |
252		  cAudioIF_5_5   |
253		  cRadioIF_38_90 ),
254};
255
256static struct tvnorm radio_mono = {
257	.name = "Radio Mono",
258	.b    = ( cFmRadio       |
259		  cQSS           ),
260	.c    = ( cDeemphasisON  |
261		  cDeemphasis75  |
262		  cTopDefault),
263	.e    = ( cTunerGainLow  |
264		  cAudioIF_5_5   |
265		  cRadioIF_38_90 ),
266};
267
268/* ---------------------------------------------------------------------- */
269
270static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf)
271{
272	struct tda9887_priv *priv = fe->analog_demod_priv;
273
274	static char *afc[16] = {
275		"- 12.5 kHz",
276		"- 37.5 kHz",
277		"- 62.5 kHz",
278		"- 87.5 kHz",
279		"-112.5 kHz",
280		"-137.5 kHz",
281		"-162.5 kHz",
282		"-187.5 kHz [min]",
283		"+187.5 kHz [max]",
284		"+162.5 kHz",
285		"+137.5 kHz",
286		"+112.5 kHz",
287		"+ 87.5 kHz",
288		"+ 62.5 kHz",
289		"+ 37.5 kHz",
290		"+ 12.5 kHz",
291	};
292	tuner_info("read: 0x%2x\n", buf[0]);
293	tuner_info("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
294	tuner_info("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);
295	tuner_info("  fmif level     : %s\n", (buf[0] & 0x20) ? "high" : "low");
296	tuner_info("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");
297	tuner_info("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");
298}
299
300static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf)
301{
302	struct tda9887_priv *priv = fe->analog_demod_priv;
303
304	static char *sound[4] = {
305		"AM/TV",
306		"FM/radio",
307		"FM/TV",
308		"FM/radio"
309	};
310	static char *adjust[32] = {
311		"-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
312		"-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",
313		"0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",
314		"+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"
315	};
316	static char *deemph[4] = {
317		"no", "no", "75", "50"
318	};
319	static char *carrier[4] = {
320		"4.5 MHz",
321		"5.5 MHz",
322		"6.0 MHz",
323		"6.5 MHz / AM"
324	};
325	static char *vif[8] = {
326		"58.75 MHz",
327		"45.75 MHz",
328		"38.9 MHz",
329		"38.0 MHz",
330		"33.9 MHz",
331		"33.4 MHz",
332		"45.75 MHz + pin13",
333		"38.9 MHz + pin13",
334	};
335	static char *rif[4] = {
336		"44 MHz",
337		"52 MHz",
338		"52 MHz",
339		"44 MHz",
340	};
341
342	tuner_info("write: byte B 0x%02x\n", buf[1]);
343	tuner_info("  B0   video mode      : %s\n",
344		   (buf[1] & 0x01) ? "video trap" : "sound trap");
345	tuner_info("  B1   auto mute fm    : %s\n",
346		   (buf[1] & 0x02) ? "yes" : "no");
347	tuner_info("  B2   carrier mode    : %s\n",
348		   (buf[1] & 0x04) ? "QSS" : "Intercarrier");
349	tuner_info("  B3-4 tv sound/radio  : %s\n",
350		   sound[(buf[1] & 0x18) >> 3]);
351	tuner_info("  B5   force mute audio: %s\n",
352		   (buf[1] & 0x20) ? "yes" : "no");
353	tuner_info("  B6   output port 1   : %s\n",
354		   (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
355	tuner_info("  B7   output port 2   : %s\n",
356		   (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
357
358	tuner_info("write: byte C 0x%02x\n", buf[2]);
359	tuner_info("  C0-4 top adjustment  : %s dB\n",
360		   adjust[buf[2] & 0x1f]);
361	tuner_info("  C5-6 de-emphasis     : %s\n",
362		   deemph[(buf[2] & 0x60) >> 5]);
363	tuner_info("  C7   audio gain      : %s\n",
364		   (buf[2] & 0x80) ? "-6" : "0");
365
366	tuner_info("write: byte E 0x%02x\n", buf[3]);
367	tuner_info("  E0-1 sound carrier   : %s\n",
368		   carrier[(buf[3] & 0x03)]);
369	tuner_info("  E6   l pll gating   : %s\n",
370		   (buf[3] & 0x40) ? "36" : "13");
371
372	if (buf[1] & 0x08) {
373		/* radio */
374		tuner_info("  E2-4 video if        : %s\n",
375			   rif[(buf[3] & 0x0c) >> 2]);
376		tuner_info("  E7   vif agc output  : %s\n",
377			   (buf[3] & 0x80)
378			   ? ((buf[3] & 0x10) ? "fm-agc radio" :
379						"sif-agc radio")
380			   : "fm radio carrier afc");
381	} else {
382		/* video */
383		tuner_info("  E2-4 video if        : %s\n",
384			   vif[(buf[3] & 0x1c) >> 2]);
385		tuner_info("  E5   tuner gain      : %s\n",
386			   (buf[3] & 0x80)
387			   ? ((buf[3] & 0x20) ? "external" : "normal")
388			   : ((buf[3] & 0x20) ? "minimum"  : "normal"));
389		tuner_info("  E7   vif agc output  : %s\n",
390			   (buf[3] & 0x80) ? ((buf[3] & 0x20)
391				? "pin3 port, pin22 vif agc out"
392				: "pin22 port, pin3 vif acg ext in")
393				: "pin3+pin22 port");
394	}
395	tuner_info("--\n");
396}
397
398/* ---------------------------------------------------------------------- */
399
400static int tda9887_set_tvnorm(struct dvb_frontend *fe)
401{
402	struct tda9887_priv *priv = fe->analog_demod_priv;
403	struct tvnorm *norm = NULL;
404	char *buf = priv->data;
405	int i;
406
407	if (priv->mode == V4L2_TUNER_RADIO) {
408		if (priv->audmode == V4L2_TUNER_MODE_MONO)
409			norm = &radio_mono;
410		else
411			norm = &radio_stereo;
412	} else {
413		for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
414			if (tvnorms[i].std & priv->std) {
415				norm = tvnorms+i;
416				break;
417			}
418		}
419	}
420	if (NULL == norm) {
421		tuner_dbg("Unsupported tvnorm entry - audio muted\n");
422		return -1;
423	}
424
425	tuner_dbg("configure for: %s\n", norm->name);
426	buf[1] = norm->b;
427	buf[2] = norm->c;
428	buf[3] = norm->e;
429	return 0;
430}
431
432static unsigned int port1  = UNSET;
433static unsigned int port2  = UNSET;
434static unsigned int qss    = UNSET;
435static unsigned int adjust = UNSET;
436
437module_param(port1, int, 0644);
438module_param(port2, int, 0644);
439module_param(qss, int, 0644);
440module_param(adjust, int, 0644);
441
442static int tda9887_set_insmod(struct dvb_frontend *fe)
443{
444	struct tda9887_priv *priv = fe->analog_demod_priv;
445	char *buf = priv->data;
446
447	if (UNSET != port1) {
448		if (port1)
449			buf[1] |= cOutputPort1Inactive;
450		else
451			buf[1] &= ~cOutputPort1Inactive;
452	}
453	if (UNSET != port2) {
454		if (port2)
455			buf[1] |= cOutputPort2Inactive;
456		else
457			buf[1] &= ~cOutputPort2Inactive;
458	}
459
460	if (UNSET != qss) {
461		if (qss)
462			buf[1] |= cQSS;
463		else
464			buf[1] &= ~cQSS;
465	}
466
467	if (adjust < 0x20) {
468		buf[2] &= ~cTopMask;
469		buf[2] |= adjust;
470	}
471	return 0;
472}
473
474static int tda9887_do_config(struct dvb_frontend *fe)
475{
476	struct tda9887_priv *priv = fe->analog_demod_priv;
477	char *buf = priv->data;
478
479	if (priv->config & TDA9887_PORT1_ACTIVE)
480		buf[1] &= ~cOutputPort1Inactive;
481	if (priv->config & TDA9887_PORT1_INACTIVE)
482		buf[1] |= cOutputPort1Inactive;
483	if (priv->config & TDA9887_PORT2_ACTIVE)
484		buf[1] &= ~cOutputPort2Inactive;
485	if (priv->config & TDA9887_PORT2_INACTIVE)
486		buf[1] |= cOutputPort2Inactive;
487
488	if (priv->config & TDA9887_QSS)
489		buf[1] |= cQSS;
490	if (priv->config & TDA9887_INTERCARRIER)
491		buf[1] &= ~cQSS;
492
493	if (priv->config & TDA9887_AUTOMUTE)
494		buf[1] |= cAutoMuteFmActive;
495	if (priv->config & TDA9887_DEEMPHASIS_MASK) {
496		buf[2] &= ~0x60;
497		switch (priv->config & TDA9887_DEEMPHASIS_MASK) {
498		case TDA9887_DEEMPHASIS_NONE:
499			buf[2] |= cDeemphasisOFF;
500			break;
501		case TDA9887_DEEMPHASIS_50:
502			buf[2] |= cDeemphasisON | cDeemphasis50;
503			break;
504		case TDA9887_DEEMPHASIS_75:
505			buf[2] |= cDeemphasisON | cDeemphasis75;
506			break;
507		}
508	}
509	if (priv->config & TDA9887_TOP_SET) {
510		buf[2] &= ~cTopMask;
511		buf[2] |= (priv->config >> 8) & cTopMask;
512	}
513	if ((priv->config & TDA9887_INTERCARRIER_NTSC) &&
514	    (priv->std & V4L2_STD_NTSC))
515		buf[1] &= ~cQSS;
516	if (priv->config & TDA9887_GATING_18)
517		buf[3] &= ~cGating_36;
518
519	if (priv->mode == V4L2_TUNER_RADIO) {
520		if (priv->config & TDA9887_RIF_41_3) {
521			buf[3] &= ~cVideoIFMask;
522			buf[3] |= cRadioIF_41_30;
523		}
524		if (priv->config & TDA9887_GAIN_NORMAL)
525			buf[3] &= ~cTunerGainLow;
526	}
527
528	return 0;
529}
530
531/* ---------------------------------------------------------------------- */
532
533static int tda9887_status(struct dvb_frontend *fe)
534{
535	struct tda9887_priv *priv = fe->analog_demod_priv;
536	unsigned char buf[1];
537	int rc;
538
539	rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, 1);
540	if (rc != 1)
541		tuner_info("i2c i/o error: rc == %d (should be 1)\n", rc);
542	dump_read_message(fe, buf);
543	return 0;
544}
545
546static void tda9887_configure(struct dvb_frontend *fe)
547{
548	struct tda9887_priv *priv = fe->analog_demod_priv;
549	int rc;
550
551	memset(priv->data,0,sizeof(priv->data));
552	tda9887_set_tvnorm(fe);
553
554	/* A note on the port settings:
555	   These settings tend to depend on the specifics of the board.
556	   By default they are set to inactive (bit value 1) by this driver,
557	   overwriting any changes made by the tvnorm. This means that it
558	   is the responsibility of the module using the tda9887 to set
559	   these values in case of changes in the tvnorm.
560	   In many cases port 2 should be made active (0) when selecting
561	   SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
562
563	   For the other standards the tda9887 application note says that
564	   the ports should be set to active (0), but, again, that may
565	   differ depending on the precise hardware configuration.
566	 */
567	priv->data[1] |= cOutputPort1Inactive;
568	priv->data[1] |= cOutputPort2Inactive;
569
570	tda9887_do_config(fe);
571	tda9887_set_insmod(fe);
572
573	if (priv->standby)
574		priv->data[1] |= cForcedMuteAudioON;
575
576	tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
577		  priv->data[1], priv->data[2], priv->data[3]);
578	if (debug > 1)
579		dump_write_message(fe, priv->data);
580
581	if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
582		tuner_info("i2c i/o error: rc == %d (should be 4)\n", rc);
583
584	if (debug > 2) {
585		msleep_interruptible(1000);
586		tda9887_status(fe);
587	}
588}
589
590/* ---------------------------------------------------------------------- */
591
592static void tda9887_tuner_status(struct dvb_frontend *fe)
593{
594	struct tda9887_priv *priv = fe->analog_demod_priv;
595	tuner_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n",
596		   priv->data[1], priv->data[2], priv->data[3]);
597}
598
599static int tda9887_get_afc(struct dvb_frontend *fe, s32 *afc)
600{
601	struct tda9887_priv *priv = fe->analog_demod_priv;
602	static const int AFC_BITS_2_kHz[] = {
603		-12500,  -37500,  -62500,  -97500,
604		-112500, -137500, -162500, -187500,
605		187500,  162500,  137500,  112500,
606		97500 ,  62500,   37500 ,  12500
607	};
608	__u8 reg = 0;
609
610	if (priv->mode != V4L2_TUNER_RADIO)
611		return 0;
612	if (1 == tuner_i2c_xfer_recv(&priv->i2c_props, &reg, 1))
613		*afc = AFC_BITS_2_kHz[(reg >> 1) & 0x0f];
614	return 0;
615}
616
617static void tda9887_standby(struct dvb_frontend *fe)
618{
619	struct tda9887_priv *priv = fe->analog_demod_priv;
620
621	priv->standby = true;
622
623	tda9887_configure(fe);
624}
625
626static void tda9887_set_params(struct dvb_frontend *fe,
627			       struct analog_parameters *params)
628{
629	struct tda9887_priv *priv = fe->analog_demod_priv;
630
631	priv->standby = false;
632	priv->mode    = params->mode;
633	priv->audmode = params->audmode;
634	priv->std     = params->std;
635	tda9887_configure(fe);
636}
637
638static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg)
639{
640	struct tda9887_priv *priv = fe->analog_demod_priv;
641
642	priv->config = *(unsigned int *)priv_cfg;
643	tda9887_configure(fe);
644
645	return 0;
646}
647
648static void tda9887_release(struct dvb_frontend *fe)
649{
650	struct tda9887_priv *priv = fe->analog_demod_priv;
651
652	mutex_lock(&tda9887_list_mutex);
653
654	if (priv)
655		hybrid_tuner_release_state(priv);
656
657	mutex_unlock(&tda9887_list_mutex);
658
659	fe->analog_demod_priv = NULL;
660}
661
662static struct analog_demod_ops tda9887_ops = {
663	.info		= {
664		.name	= "tda9887",
665	},
666	.set_params     = tda9887_set_params,
667	.standby        = tda9887_standby,
668	.tuner_status   = tda9887_tuner_status,
669	.get_afc        = tda9887_get_afc,
670	.release        = tda9887_release,
671	.set_config     = tda9887_set_config,
672};
673
674struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
675				    struct i2c_adapter *i2c_adap,
676				    u8 i2c_addr)
677{
678	struct tda9887_priv *priv = NULL;
679	int instance;
680
681	mutex_lock(&tda9887_list_mutex);
682
683	instance = hybrid_tuner_request_state(struct tda9887_priv, priv,
684					      hybrid_tuner_instance_list,
685					      i2c_adap, i2c_addr, "tda9887");
686	switch (instance) {
687	case 0:
688		mutex_unlock(&tda9887_list_mutex);
689		return NULL;
690	case 1:
691		fe->analog_demod_priv = priv;
692		priv->standby = true;
693		tuner_info("tda988[5/6/7] found\n");
694		break;
695	default:
696		fe->analog_demod_priv = priv;
697		break;
698	}
699
700	mutex_unlock(&tda9887_list_mutex);
701
702	memcpy(&fe->ops.analog_ops, &tda9887_ops,
703	       sizeof(struct analog_demod_ops));
704
705	return fe;
706}
707EXPORT_SYMBOL_GPL(tda9887_attach);
708
709MODULE_LICENSE("GPL");
710
711/*
712 * Overrides for Emacs so that we follow Linus's tabbing style.
713 * ---------------------------------------------------------------------------
714 * Local variables:
715 * c-basic-offset: 8
716 * End:
717 */
718