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