diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-29 20:38:44 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-29 17:41:37 -0400 |
commit | 7c91f0624a9a2b8b9b122cf94fef34bc7f7347a6 (patch) | |
tree | e48220117475037125e86a3add48aa12cef7731f /drivers/media/video | |
parent | 5fe95e0b865060839449e1a61c1d5c67a4faab9a (diff) |
V4L/DVB(7767): Move tuners to common/tuners
There were several issues in the past, caused by the hybrid tuner design, since
now, the same tuner can be used by drivers/media/dvb and drivers/media/video.
Kconfig items were rearranged, to split V4L/DVB core from their drivers.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
28 files changed, 56 insertions, 7633 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index fe9a4cc14141..e99bfcf28112 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -1,4 +1,50 @@ | |||
1 | # | 1 | # |
2 | # Generic video config states | ||
3 | # | ||
4 | |||
5 | config VIDEO_V4L2 | ||
6 | tristate | ||
7 | depends on VIDEO_DEV && VIDEO_V4L2_COMMON | ||
8 | default VIDEO_DEV && VIDEO_V4L2_COMMON | ||
9 | |||
10 | config VIDEO_V4L1 | ||
11 | tristate | ||
12 | depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1 | ||
13 | default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1 | ||
14 | |||
15 | config VIDEOBUF_GEN | ||
16 | tristate | ||
17 | |||
18 | config VIDEOBUF_DMA_SG | ||
19 | depends on HAS_DMA | ||
20 | select VIDEOBUF_GEN | ||
21 | tristate | ||
22 | |||
23 | config VIDEOBUF_VMALLOC | ||
24 | select VIDEOBUF_GEN | ||
25 | tristate | ||
26 | |||
27 | config VIDEOBUF_DVB | ||
28 | tristate | ||
29 | select VIDEOBUF_GEN | ||
30 | select VIDEOBUF_DMA_SG | ||
31 | |||
32 | config VIDEO_BTCX | ||
33 | tristate | ||
34 | |||
35 | config VIDEO_IR_I2C | ||
36 | tristate | ||
37 | |||
38 | config VIDEO_IR | ||
39 | tristate | ||
40 | depends on INPUT | ||
41 | select VIDEO_IR_I2C if I2C | ||
42 | |||
43 | config VIDEO_TVEEPROM | ||
44 | tristate | ||
45 | depends on I2C | ||
46 | |||
47 | # | ||
2 | # Multimedia Video device configuration | 48 | # Multimedia Video device configuration |
3 | # | 49 | # |
4 | 50 | ||
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index be14227f3726..73f87aede074 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -86,16 +86,6 @@ obj-$(CONFIG_TUNER_3036) += tuner-3036.o | |||
86 | 86 | ||
87 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o | 87 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o |
88 | 88 | ||
89 | obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o | ||
90 | obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o | ||
91 | # tuner-types will be merged into tuner-simple, in the future | ||
92 | obj-$(CONFIG_TUNER_SIMPLE) += tuner-types.o | ||
93 | obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o | ||
94 | obj-$(CONFIG_TUNER_TDA8290) += tda8290.o | ||
95 | obj-$(CONFIG_TUNER_TEA5767) += tea5767.o | ||
96 | obj-$(CONFIG_TUNER_TEA5761) += tea5761.o | ||
97 | obj-$(CONFIG_TUNER_TDA9887) += tda9887.o | ||
98 | |||
99 | obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o | 89 | obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o |
100 | obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o | 90 | obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o |
101 | obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o | 91 | obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o |
@@ -147,3 +137,4 @@ obj-$(CONFIG_VIDEO_AU0828) += au0828/ | |||
147 | 137 | ||
148 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 138 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
149 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 139 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
140 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile index 9f4f572c89c5..cd2c58281b4e 100644 --- a/drivers/media/video/au0828/Makefile +++ b/drivers/media/video/au0828/Makefile | |||
@@ -2,7 +2,7 @@ au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o | |||
2 | 2 | ||
3 | obj-$(CONFIG_VIDEO_AU0828) += au0828.o | 3 | obj-$(CONFIG_VIDEO_AU0828) += au0828.o |
4 | 4 | ||
5 | EXTRA_CFLAGS += -Idrivers/media/video | 5 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
6 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 6 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
7 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 7 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
8 | 8 | ||
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile index 924d216d9570..e415f6fc447c 100644 --- a/drivers/media/video/bt8xx/Makefile +++ b/drivers/media/video/bt8xx/Makefile | |||
@@ -9,4 +9,5 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ | |||
9 | obj-$(CONFIG_VIDEO_BT848) += bttv.o | 9 | obj-$(CONFIG_VIDEO_BT848) += bttv.o |
10 | 10 | ||
11 | EXTRA_CFLAGS += -Idrivers/media/video | 11 | EXTRA_CFLAGS += -Idrivers/media/video |
12 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 13 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index d7b0721af062..29c23b44c13c 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile | |||
@@ -3,6 +3,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx2 | |||
3 | obj-$(CONFIG_VIDEO_CX23885) += cx23885.o | 3 | obj-$(CONFIG_VIDEO_CX23885) += cx23885.o |
4 | 4 | ||
5 | EXTRA_CFLAGS += -Idrivers/media/video | 5 | EXTRA_CFLAGS += -Idrivers/media/video |
6 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
6 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 7 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
7 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 8 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
8 | 9 | ||
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 532cee35eb3c..6ec30f242578 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -10,5 +10,6 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o | |||
10 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o | 10 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o |
11 | 11 | ||
12 | EXTRA_CFLAGS += -Idrivers/media/video | 12 | EXTRA_CFLAGS += -Idrivers/media/video |
13 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
13 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 14 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
14 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 15 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile index 3d1c3cc337fe..8137a8c94bfc 100644 --- a/drivers/media/video/em28xx/Makefile +++ b/drivers/media/video/em28xx/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o | |||
8 | obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o | 8 | obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o |
9 | 9 | ||
10 | EXTRA_CFLAGS += -Idrivers/media/video | 10 | EXTRA_CFLAGS += -Idrivers/media/video |
11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
11 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
12 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
13 | 14 | ||
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile index a0389014fa88..26ce0d6eaee1 100644 --- a/drivers/media/video/ivtv/Makefile +++ b/drivers/media/video/ivtv/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv.o | |||
8 | obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o | 8 | obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o |
9 | 9 | ||
10 | EXTRA_CFLAGS += -Idrivers/media/video | 10 | EXTRA_CFLAGS += -Idrivers/media/video |
11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
11 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
12 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
13 | 14 | ||
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c deleted file mode 100644 index fbcb28233737..000000000000 --- a/drivers/media/video/mt20xx.c +++ /dev/null | |||
@@ -1,670 +0,0 @@ | |||
1 | /* | ||
2 | * i2c tv tuner chip device driver | ||
3 | * controls microtune tuners, mt2032 + mt2050 at the moment. | ||
4 | * | ||
5 | * This "mt20xx" module was split apart from the original "tuner" module. | ||
6 | */ | ||
7 | #include <linux/delay.h> | ||
8 | #include <linux/i2c.h> | ||
9 | #include <linux/videodev.h> | ||
10 | #include "tuner-i2c.h" | ||
11 | #include "mt20xx.h" | ||
12 | |||
13 | static int debug; | ||
14 | module_param(debug, int, 0644); | ||
15 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
16 | |||
17 | /* ---------------------------------------------------------------------- */ | ||
18 | |||
19 | static unsigned int optimize_vco = 1; | ||
20 | module_param(optimize_vco, int, 0644); | ||
21 | |||
22 | static unsigned int tv_antenna = 1; | ||
23 | module_param(tv_antenna, int, 0644); | ||
24 | |||
25 | static unsigned int radio_antenna; | ||
26 | module_param(radio_antenna, int, 0644); | ||
27 | |||
28 | /* ---------------------------------------------------------------------- */ | ||
29 | |||
30 | #define MT2032 0x04 | ||
31 | #define MT2030 0x06 | ||
32 | #define MT2040 0x07 | ||
33 | #define MT2050 0x42 | ||
34 | |||
35 | static char *microtune_part[] = { | ||
36 | [ MT2030 ] = "MT2030", | ||
37 | [ MT2032 ] = "MT2032", | ||
38 | [ MT2040 ] = "MT2040", | ||
39 | [ MT2050 ] = "MT2050", | ||
40 | }; | ||
41 | |||
42 | struct microtune_priv { | ||
43 | struct tuner_i2c_props i2c_props; | ||
44 | |||
45 | unsigned int xogc; | ||
46 | //unsigned int radio_if2; | ||
47 | |||
48 | u32 frequency; | ||
49 | }; | ||
50 | |||
51 | static int microtune_release(struct dvb_frontend *fe) | ||
52 | { | ||
53 | kfree(fe->tuner_priv); | ||
54 | fe->tuner_priv = NULL; | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
60 | { | ||
61 | struct microtune_priv *priv = fe->tuner_priv; | ||
62 | *frequency = priv->frequency; | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | // IsSpurInBand()? | ||
67 | static int mt2032_spurcheck(struct dvb_frontend *fe, | ||
68 | int f1, int f2, int spectrum_from,int spectrum_to) | ||
69 | { | ||
70 | struct microtune_priv *priv = fe->tuner_priv; | ||
71 | int n1=1,n2,f; | ||
72 | |||
73 | f1=f1/1000; //scale to kHz to avoid 32bit overflows | ||
74 | f2=f2/1000; | ||
75 | spectrum_from/=1000; | ||
76 | spectrum_to/=1000; | ||
77 | |||
78 | tuner_dbg("spurcheck f1=%d f2=%d from=%d to=%d\n", | ||
79 | f1,f2,spectrum_from,spectrum_to); | ||
80 | |||
81 | do { | ||
82 | n2=-n1; | ||
83 | f=n1*(f1-f2); | ||
84 | do { | ||
85 | n2--; | ||
86 | f=f-f2; | ||
87 | tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f); | ||
88 | |||
89 | if( (f>spectrum_from) && (f<spectrum_to)) | ||
90 | tuner_dbg("mt2032 spurcheck triggered: %d\n",n1); | ||
91 | } while ( (f>(f2-spectrum_to)) || (n2>-5)); | ||
92 | n1++; | ||
93 | } while (n1<5); | ||
94 | |||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | static int mt2032_compute_freq(struct dvb_frontend *fe, | ||
99 | unsigned int rfin, | ||
100 | unsigned int if1, unsigned int if2, | ||
101 | unsigned int spectrum_from, | ||
102 | unsigned int spectrum_to, | ||
103 | unsigned char *buf, | ||
104 | int *ret_sel, | ||
105 | unsigned int xogc) //all in Hz | ||
106 | { | ||
107 | struct microtune_priv *priv = fe->tuner_priv; | ||
108 | unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, | ||
109 | desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; | ||
110 | |||
111 | fref= 5250 *1000; //5.25MHz | ||
112 | desired_lo1=rfin+if1; | ||
113 | |||
114 | lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); | ||
115 | lo1n=lo1/8; | ||
116 | lo1a=lo1-(lo1n*8); | ||
117 | |||
118 | s=rfin/1000/1000+1090; | ||
119 | |||
120 | if(optimize_vco) { | ||
121 | if(s>1890) sel=0; | ||
122 | else if(s>1720) sel=1; | ||
123 | else if(s>1530) sel=2; | ||
124 | else if(s>1370) sel=3; | ||
125 | else sel=4; // >1090 | ||
126 | } | ||
127 | else { | ||
128 | if(s>1790) sel=0; // <1958 | ||
129 | else if(s>1617) sel=1; | ||
130 | else if(s>1449) sel=2; | ||
131 | else if(s>1291) sel=3; | ||
132 | else sel=4; // >1090 | ||
133 | } | ||
134 | *ret_sel=sel; | ||
135 | |||
136 | lo1freq=(lo1a+8*lo1n)*fref; | ||
137 | |||
138 | tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", | ||
139 | rfin,lo1,lo1n,lo1a,sel,lo1freq); | ||
140 | |||
141 | desired_lo2=lo1freq-rfin-if2; | ||
142 | lo2=(desired_lo2)/fref; | ||
143 | lo2n=lo2/8; | ||
144 | lo2a=lo2-(lo2n*8); | ||
145 | lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith | ||
146 | lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; | ||
147 | |||
148 | tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", | ||
149 | rfin,lo2,lo2n,lo2a,lo2num,lo2freq); | ||
150 | |||
151 | if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { | ||
152 | tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", | ||
153 | lo1a, lo1n, lo2a,lo2n); | ||
154 | return(-1); | ||
155 | } | ||
156 | |||
157 | mt2032_spurcheck(fe, lo1freq, desired_lo2, spectrum_from, spectrum_to); | ||
158 | // should recalculate lo1 (one step up/down) | ||
159 | |||
160 | // set up MT2032 register map for transfer over i2c | ||
161 | buf[0]=lo1n-1; | ||
162 | buf[1]=lo1a | (sel<<4); | ||
163 | buf[2]=0x86; // LOGC | ||
164 | buf[3]=0x0f; //reserved | ||
165 | buf[4]=0x1f; | ||
166 | buf[5]=(lo2n-1) | (lo2a<<5); | ||
167 | if(rfin >400*1000*1000) | ||
168 | buf[6]=0xe4; | ||
169 | else | ||
170 | buf[6]=0xf4; // set PKEN per rev 1.2 | ||
171 | buf[7]=8+xogc; | ||
172 | buf[8]=0xc3; //reserved | ||
173 | buf[9]=0x4e; //reserved | ||
174 | buf[10]=0xec; //reserved | ||
175 | buf[11]=(lo2num&0xff); | ||
176 | buf[12]=(lo2num>>8) |0x80; // Lo2RST | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int mt2032_check_lo_lock(struct dvb_frontend *fe) | ||
182 | { | ||
183 | struct microtune_priv *priv = fe->tuner_priv; | ||
184 | int try,lock=0; | ||
185 | unsigned char buf[2]; | ||
186 | |||
187 | for(try=0;try<10;try++) { | ||
188 | buf[0]=0x0e; | ||
189 | tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | ||
190 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); | ||
191 | tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]); | ||
192 | lock=buf[0] &0x06; | ||
193 | |||
194 | if (lock==6) | ||
195 | break; | ||
196 | |||
197 | tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); | ||
198 | udelay(1000); | ||
199 | } | ||
200 | return lock; | ||
201 | } | ||
202 | |||
203 | static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock) | ||
204 | { | ||
205 | struct microtune_priv *priv = fe->tuner_priv; | ||
206 | unsigned char buf[2]; | ||
207 | int tad1; | ||
208 | |||
209 | buf[0]=0x0f; | ||
210 | tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | ||
211 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); | ||
212 | tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]); | ||
213 | tad1=buf[0]&0x07; | ||
214 | |||
215 | if(tad1 ==0) return lock; | ||
216 | if(tad1 ==1) return lock; | ||
217 | |||
218 | if(tad1==2) { | ||
219 | if(sel==0) | ||
220 | return lock; | ||
221 | else sel--; | ||
222 | } | ||
223 | else { | ||
224 | if(sel<4) | ||
225 | sel++; | ||
226 | else | ||
227 | return lock; | ||
228 | } | ||
229 | |||
230 | tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel); | ||
231 | |||
232 | buf[0]=0x0f; | ||
233 | buf[1]=sel; | ||
234 | tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | ||
235 | lock=mt2032_check_lo_lock(fe); | ||
236 | return lock; | ||
237 | } | ||
238 | |||
239 | |||
240 | static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin, | ||
241 | unsigned int if1, unsigned int if2, | ||
242 | unsigned int from, unsigned int to) | ||
243 | { | ||
244 | unsigned char buf[21]; | ||
245 | int lint_try,ret,sel,lock=0; | ||
246 | struct microtune_priv *priv = fe->tuner_priv; | ||
247 | |||
248 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", | ||
249 | rfin,if1,if2,from,to); | ||
250 | |||
251 | buf[0]=0; | ||
252 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | ||
253 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); | ||
254 | |||
255 | buf[0]=0; | ||
256 | ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc); | ||
257 | if (ret<0) | ||
258 | return; | ||
259 | |||
260 | // send only the relevant registers per Rev. 1.2 | ||
261 | buf[0]=0; | ||
262 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4); | ||
263 | buf[5]=5; | ||
264 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4); | ||
265 | buf[11]=11; | ||
266 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3); | ||
267 | if(ret!=3) | ||
268 | tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); | ||
269 | |||
270 | // wait for PLLs to lock (per manual), retry LINT if not. | ||
271 | for(lint_try=0; lint_try<2; lint_try++) { | ||
272 | lock=mt2032_check_lo_lock(fe); | ||
273 | |||
274 | if(optimize_vco) | ||
275 | lock=mt2032_optimize_vco(fe,sel,lock); | ||
276 | if(lock==6) break; | ||
277 | |||
278 | tuner_dbg("mt2032: re-init PLLs by LINT\n"); | ||
279 | buf[0]=7; | ||
280 | buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs | ||
281 | tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | ||
282 | mdelay(10); | ||
283 | buf[1]=8+priv->xogc; | ||
284 | tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | ||
285 | } | ||
286 | |||
287 | if (lock!=6) | ||
288 | tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); | ||
289 | |||
290 | buf[0]=2; | ||
291 | buf[1]=0x20; // LOGC for optimal phase noise | ||
292 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | ||
293 | if (ret!=2) | ||
294 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); | ||
295 | } | ||
296 | |||
297 | |||
298 | static int mt2032_set_tv_freq(struct dvb_frontend *fe, | ||
299 | struct analog_parameters *params) | ||
300 | { | ||
301 | int if2,from,to; | ||
302 | |||
303 | // signal bandwidth and picture carrier | ||
304 | if (params->std & V4L2_STD_525_60) { | ||
305 | // NTSC | ||
306 | from = 40750*1000; | ||
307 | to = 46750*1000; | ||
308 | if2 = 45750*1000; | ||
309 | } else { | ||
310 | // PAL | ||
311 | from = 32900*1000; | ||
312 | to = 39900*1000; | ||
313 | if2 = 38900*1000; | ||
314 | } | ||
315 | |||
316 | mt2032_set_if_freq(fe, params->frequency*62500, | ||
317 | 1090*1000*1000, if2, from, to); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int mt2032_set_radio_freq(struct dvb_frontend *fe, | ||
323 | struct analog_parameters *params) | ||
324 | { | ||
325 | struct microtune_priv *priv = fe->tuner_priv; | ||
326 | int if2; | ||
327 | |||
328 | if (params->std & V4L2_STD_525_60) { | ||
329 | tuner_dbg("pinnacle ntsc\n"); | ||
330 | if2 = 41300 * 1000; | ||
331 | } else { | ||
332 | tuner_dbg("pinnacle pal\n"); | ||
333 | if2 = 33300 * 1000; | ||
334 | } | ||
335 | |||
336 | // per Manual for FM tuning: first if center freq. 1085 MHz | ||
337 | mt2032_set_if_freq(fe, params->frequency * 125 / 2, | ||
338 | 1085*1000*1000,if2,if2,if2); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int mt2032_set_params(struct dvb_frontend *fe, | ||
344 | struct analog_parameters *params) | ||
345 | { | ||
346 | struct microtune_priv *priv = fe->tuner_priv; | ||
347 | int ret = -EINVAL; | ||
348 | |||
349 | switch (params->mode) { | ||
350 | case V4L2_TUNER_RADIO: | ||
351 | ret = mt2032_set_radio_freq(fe, params); | ||
352 | priv->frequency = params->frequency * 125 / 2; | ||
353 | break; | ||
354 | case V4L2_TUNER_ANALOG_TV: | ||
355 | case V4L2_TUNER_DIGITAL_TV: | ||
356 | ret = mt2032_set_tv_freq(fe, params); | ||
357 | priv->frequency = params->frequency * 62500; | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | static struct dvb_tuner_ops mt2032_tuner_ops = { | ||
365 | .set_analog_params = mt2032_set_params, | ||
366 | .release = microtune_release, | ||
367 | .get_frequency = microtune_get_frequency, | ||
368 | }; | ||
369 | |||
370 | // Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 | ||
371 | static int mt2032_init(struct dvb_frontend *fe) | ||
372 | { | ||
373 | struct microtune_priv *priv = fe->tuner_priv; | ||
374 | unsigned char buf[21]; | ||
375 | int ret,xogc,xok=0; | ||
376 | |||
377 | // Initialize Registers per spec. | ||
378 | buf[1]=2; // Index to register 2 | ||
379 | buf[2]=0xff; | ||
380 | buf[3]=0x0f; | ||
381 | buf[4]=0x1f; | ||
382 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4); | ||
383 | |||
384 | buf[5]=6; // Index register 6 | ||
385 | buf[6]=0xe4; | ||
386 | buf[7]=0x8f; | ||
387 | buf[8]=0xc3; | ||
388 | buf[9]=0x4e; | ||
389 | buf[10]=0xec; | ||
390 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6); | ||
391 | |||
392 | buf[12]=13; // Index register 13 | ||
393 | buf[13]=0x32; | ||
394 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2); | ||
395 | |||
396 | // Adjust XOGC (register 7), wait for XOK | ||
397 | xogc=7; | ||
398 | do { | ||
399 | tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); | ||
400 | mdelay(10); | ||
401 | buf[0]=0x0e; | ||
402 | tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | ||
403 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); | ||
404 | xok=buf[0]&0x01; | ||
405 | tuner_dbg("mt2032: xok = 0x%02x\n",xok); | ||
406 | if (xok == 1) break; | ||
407 | |||
408 | xogc--; | ||
409 | tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); | ||
410 | if (xogc == 3) { | ||
411 | xogc=4; // min. 4 per spec | ||
412 | break; | ||
413 | } | ||
414 | buf[0]=0x07; | ||
415 | buf[1]=0x88 + xogc; | ||
416 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | ||
417 | if (ret!=2) | ||
418 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); | ||
419 | } while (xok != 1 ); | ||
420 | priv->xogc=xogc; | ||
421 | |||
422 | memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
423 | |||
424 | return(1); | ||
425 | } | ||
426 | |||
427 | static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna) | ||
428 | { | ||
429 | struct microtune_priv *priv = fe->tuner_priv; | ||
430 | unsigned char buf[2]; | ||
431 | int ret; | ||
432 | |||
433 | buf[0] = 6; | ||
434 | buf[1] = antenna ? 0x11 : 0x10; | ||
435 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | ||
436 | tuner_dbg("mt2050: enabled antenna connector %d\n", antenna); | ||
437 | } | ||
438 | |||
439 | static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2) | ||
440 | { | ||
441 | struct microtune_priv *priv = fe->tuner_priv; | ||
442 | unsigned int if1=1218*1000*1000; | ||
443 | unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b; | ||
444 | int ret; | ||
445 | unsigned char buf[6]; | ||
446 | |||
447 | tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n", | ||
448 | freq,if1,if2); | ||
449 | |||
450 | f_lo1=freq+if1; | ||
451 | f_lo1=(f_lo1/1000000)*1000000; | ||
452 | |||
453 | f_lo2=f_lo1-freq-if2; | ||
454 | f_lo2=(f_lo2/50000)*50000; | ||
455 | |||
456 | lo1=f_lo1/4000000; | ||
457 | lo2=f_lo2/4000000; | ||
458 | |||
459 | f_lo1_modulo= f_lo1-(lo1*4000000); | ||
460 | f_lo2_modulo= f_lo2-(lo2*4000000); | ||
461 | |||
462 | num1=4*f_lo1_modulo/4000000; | ||
463 | num2=4096*(f_lo2_modulo/1000)/4000; | ||
464 | |||
465 | // todo spurchecks | ||
466 | |||
467 | div1a=(lo1/12)-1; | ||
468 | div1b=lo1-(div1a+1)*12; | ||
469 | |||
470 | div2a=(lo2/8)-1; | ||
471 | div2b=lo2-(div2a+1)*8; | ||
472 | |||
473 | if (debug > 1) { | ||
474 | tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); | ||
475 | tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", | ||
476 | num1,num2,div1a,div1b,div2a,div2b); | ||
477 | } | ||
478 | |||
479 | buf[0]=1; | ||
480 | buf[1]= 4*div1b + num1; | ||
481 | if(freq<275*1000*1000) buf[1] = buf[1]|0x80; | ||
482 | |||
483 | buf[2]=div1a; | ||
484 | buf[3]=32*div2b + num2/256; | ||
485 | buf[4]=num2-(num2/256)*256; | ||
486 | buf[5]=div2a; | ||
487 | if(num2!=0) buf[5]=buf[5]|0x40; | ||
488 | |||
489 | if (debug > 1) { | ||
490 | int i; | ||
491 | tuner_dbg("bufs is: "); | ||
492 | for(i=0;i<6;i++) | ||
493 | printk("%x ",buf[i]); | ||
494 | printk("\n"); | ||
495 | } | ||
496 | |||
497 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6); | ||
498 | if (ret!=6) | ||
499 | tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); | ||
500 | } | ||
501 | |||
502 | static int mt2050_set_tv_freq(struct dvb_frontend *fe, | ||
503 | struct analog_parameters *params) | ||
504 | { | ||
505 | unsigned int if2; | ||
506 | |||
507 | if (params->std & V4L2_STD_525_60) { | ||
508 | // NTSC | ||
509 | if2 = 45750*1000; | ||
510 | } else { | ||
511 | // PAL | ||
512 | if2 = 38900*1000; | ||
513 | } | ||
514 | if (V4L2_TUNER_DIGITAL_TV == params->mode) { | ||
515 | // DVB (pinnacle 300i) | ||
516 | if2 = 36150*1000; | ||
517 | } | ||
518 | mt2050_set_if_freq(fe, params->frequency*62500, if2); | ||
519 | mt2050_set_antenna(fe, tv_antenna); | ||
520 | |||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | static int mt2050_set_radio_freq(struct dvb_frontend *fe, | ||
525 | struct analog_parameters *params) | ||
526 | { | ||
527 | struct microtune_priv *priv = fe->tuner_priv; | ||
528 | int if2; | ||
529 | |||
530 | if (params->std & V4L2_STD_525_60) { | ||
531 | tuner_dbg("pinnacle ntsc\n"); | ||
532 | if2 = 41300 * 1000; | ||
533 | } else { | ||
534 | tuner_dbg("pinnacle pal\n"); | ||
535 | if2 = 33300 * 1000; | ||
536 | } | ||
537 | |||
538 | mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2); | ||
539 | mt2050_set_antenna(fe, radio_antenna); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | static int mt2050_set_params(struct dvb_frontend *fe, | ||
545 | struct analog_parameters *params) | ||
546 | { | ||
547 | struct microtune_priv *priv = fe->tuner_priv; | ||
548 | int ret = -EINVAL; | ||
549 | |||
550 | switch (params->mode) { | ||
551 | case V4L2_TUNER_RADIO: | ||
552 | ret = mt2050_set_radio_freq(fe, params); | ||
553 | priv->frequency = params->frequency * 125 / 2; | ||
554 | break; | ||
555 | case V4L2_TUNER_ANALOG_TV: | ||
556 | case V4L2_TUNER_DIGITAL_TV: | ||
557 | ret = mt2050_set_tv_freq(fe, params); | ||
558 | priv->frequency = params->frequency * 62500; | ||
559 | break; | ||
560 | } | ||
561 | |||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | static struct dvb_tuner_ops mt2050_tuner_ops = { | ||
566 | .set_analog_params = mt2050_set_params, | ||
567 | .release = microtune_release, | ||
568 | .get_frequency = microtune_get_frequency, | ||
569 | }; | ||
570 | |||
571 | static int mt2050_init(struct dvb_frontend *fe) | ||
572 | { | ||
573 | struct microtune_priv *priv = fe->tuner_priv; | ||
574 | unsigned char buf[2]; | ||
575 | int ret; | ||
576 | |||
577 | buf[0]=6; | ||
578 | buf[1]=0x10; | ||
579 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); // power | ||
580 | |||
581 | buf[0]=0x0f; | ||
582 | buf[1]=0x0f; | ||
583 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); // m1lo | ||
584 | |||
585 | buf[0]=0x0d; | ||
586 | ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | ||
587 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); | ||
588 | |||
589 | tuner_dbg("mt2050: sro is %x\n",buf[0]); | ||
590 | |||
591 | memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, | ||
597 | struct i2c_adapter* i2c_adap, | ||
598 | u8 i2c_addr) | ||
599 | { | ||
600 | struct microtune_priv *priv = NULL; | ||
601 | char *name; | ||
602 | unsigned char buf[21]; | ||
603 | int company_code; | ||
604 | |||
605 | priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL); | ||
606 | if (priv == NULL) | ||
607 | return NULL; | ||
608 | fe->tuner_priv = priv; | ||
609 | |||
610 | priv->i2c_props.addr = i2c_addr; | ||
611 | priv->i2c_props.adap = i2c_adap; | ||
612 | priv->i2c_props.name = "mt20xx"; | ||
613 | |||
614 | //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | ||
615 | |||
616 | memset(buf,0,sizeof(buf)); | ||
617 | |||
618 | name = "unknown"; | ||
619 | |||
620 | tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | ||
621 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); | ||
622 | if (debug) { | ||
623 | int i; | ||
624 | tuner_dbg("MT20xx hexdump:"); | ||
625 | for(i=0;i<21;i++) { | ||
626 | printk(" %02x",buf[i]); | ||
627 | if(((i+1)%8)==0) printk(" "); | ||
628 | } | ||
629 | printk("\n"); | ||
630 | } | ||
631 | company_code = buf[0x11] << 8 | buf[0x12]; | ||
632 | tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", | ||
633 | company_code,buf[0x13],buf[0x14]); | ||
634 | |||
635 | |||
636 | if (buf[0x13] < ARRAY_SIZE(microtune_part) && | ||
637 | NULL != microtune_part[buf[0x13]]) | ||
638 | name = microtune_part[buf[0x13]]; | ||
639 | switch (buf[0x13]) { | ||
640 | case MT2032: | ||
641 | mt2032_init(fe); | ||
642 | break; | ||
643 | case MT2050: | ||
644 | mt2050_init(fe); | ||
645 | break; | ||
646 | default: | ||
647 | tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", | ||
648 | name); | ||
649 | return NULL; | ||
650 | } | ||
651 | |||
652 | strlcpy(fe->ops.tuner_ops.info.name, name, | ||
653 | sizeof(fe->ops.tuner_ops.info.name)); | ||
654 | tuner_info("microtune %s found, OK\n",name); | ||
655 | return fe; | ||
656 | } | ||
657 | |||
658 | EXPORT_SYMBOL_GPL(microtune_attach); | ||
659 | |||
660 | MODULE_DESCRIPTION("Microtune tuner driver"); | ||
661 | MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | ||
662 | MODULE_LICENSE("GPL"); | ||
663 | |||
664 | /* | ||
665 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
666 | * --------------------------------------------------------------------------- | ||
667 | * Local variables: | ||
668 | * c-basic-offset: 8 | ||
669 | * End: | ||
670 | */ | ||
diff --git a/drivers/media/video/mt20xx.h b/drivers/media/video/mt20xx.h deleted file mode 100644 index aa848e14ce5e..000000000000 --- a/drivers/media/video/mt20xx.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or modify | ||
3 | it under the terms of the GNU General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or | ||
5 | (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU General Public License | ||
13 | along with this program; if not, write to the Free Software | ||
14 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef __MT20XX_H__ | ||
18 | #define __MT20XX_H__ | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | #if defined(CONFIG_TUNER_MT20XX) || (defined(CONFIG_TUNER_MT20XX_MODULE) && defined(MODULE)) | ||
24 | extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, | ||
25 | struct i2c_adapter* i2c_adap, | ||
26 | u8 i2c_addr); | ||
27 | #else | ||
28 | static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, | ||
29 | struct i2c_adapter* i2c_adap, | ||
30 | u8 i2c_addr) | ||
31 | { | ||
32 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
33 | return NULL; | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | #endif /* __MT20XX_H__ */ | ||
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile index 5b3083c89aa9..4fda2de69ab7 100644 --- a/drivers/media/video/pvrusb2/Makefile +++ b/drivers/media/video/pvrusb2/Makefile | |||
@@ -16,5 +16,6 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ | |||
16 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o | 16 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o |
17 | 17 | ||
18 | EXTRA_CFLAGS += -Idrivers/media/video | 18 | EXTRA_CFLAGS += -Idrivers/media/video |
19 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
19 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 20 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
20 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 21 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 9aff937ba7a5..3dbaa19a6d00 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -11,5 +11,6 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o | |||
11 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o | 11 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o |
12 | 12 | ||
13 | EXTRA_CFLAGS += -Idrivers/media/video | 13 | EXTRA_CFLAGS += -Idrivers/media/video |
14 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
14 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 15 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
15 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 16 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c deleted file mode 100644 index 0ebb5b525e57..000000000000 --- a/drivers/media/video/tda8290.c +++ /dev/null | |||
@@ -1,804 +0,0 @@ | |||
1 | /* | ||
2 | |||
3 | i2c tv tuner chip device driver | ||
4 | controls the philips tda8290+75 tuner chip combo. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | |||
20 | This "tda8290" module was split apart from the original "tuner" module. | ||
21 | */ | ||
22 | |||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/videodev.h> | ||
26 | #include "tuner-i2c.h" | ||
27 | #include "tda8290.h" | ||
28 | #include "tda827x.h" | ||
29 | #include "tda18271.h" | ||
30 | |||
31 | static int debug; | ||
32 | module_param(debug, int, 0644); | ||
33 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
34 | |||
35 | /* ---------------------------------------------------------------------- */ | ||
36 | |||
37 | struct tda8290_priv { | ||
38 | struct tuner_i2c_props i2c_props; | ||
39 | |||
40 | unsigned char tda8290_easy_mode; | ||
41 | |||
42 | unsigned char tda827x_addr; | ||
43 | |||
44 | unsigned char ver; | ||
45 | #define TDA8290 1 | ||
46 | #define TDA8295 2 | ||
47 | #define TDA8275 4 | ||
48 | #define TDA8275A 8 | ||
49 | #define TDA18271 16 | ||
50 | |||
51 | struct tda827x_config cfg; | ||
52 | }; | ||
53 | |||
54 | /*---------------------------------------------------------------------*/ | ||
55 | |||
56 | static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close) | ||
57 | { | ||
58 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
59 | |||
60 | unsigned char enable[2] = { 0x21, 0xC0 }; | ||
61 | unsigned char disable[2] = { 0x21, 0x00 }; | ||
62 | unsigned char *msg; | ||
63 | |||
64 | if (close) { | ||
65 | msg = enable; | ||
66 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
67 | /* let the bridge stabilize */ | ||
68 | msleep(20); | ||
69 | } else { | ||
70 | msg = disable; | ||
71 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close) | ||
78 | { | ||
79 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
80 | |||
81 | unsigned char enable[2] = { 0x45, 0xc1 }; | ||
82 | unsigned char disable[2] = { 0x46, 0x00 }; | ||
83 | unsigned char buf[3] = { 0x45, 0x01, 0x00 }; | ||
84 | unsigned char *msg; | ||
85 | |||
86 | if (close) { | ||
87 | msg = enable; | ||
88 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
89 | /* let the bridge stabilize */ | ||
90 | msleep(20); | ||
91 | } else { | ||
92 | msg = disable; | ||
93 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 1); | ||
94 | tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1); | ||
95 | |||
96 | buf[2] = msg[1]; | ||
97 | buf[2] &= ~0x04; | ||
98 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 3); | ||
99 | msleep(5); | ||
100 | |||
101 | msg[1] |= 0x04; | ||
102 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
103 | } | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | /*---------------------------------------------------------------------*/ | ||
109 | |||
110 | static void set_audio(struct dvb_frontend *fe, | ||
111 | struct analog_parameters *params) | ||
112 | { | ||
113 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
114 | char* mode; | ||
115 | |||
116 | if (params->std & V4L2_STD_MN) { | ||
117 | priv->tda8290_easy_mode = 0x01; | ||
118 | mode = "MN"; | ||
119 | } else if (params->std & V4L2_STD_B) { | ||
120 | priv->tda8290_easy_mode = 0x02; | ||
121 | mode = "B"; | ||
122 | } else if (params->std & V4L2_STD_GH) { | ||
123 | priv->tda8290_easy_mode = 0x04; | ||
124 | mode = "GH"; | ||
125 | } else if (params->std & V4L2_STD_PAL_I) { | ||
126 | priv->tda8290_easy_mode = 0x08; | ||
127 | mode = "I"; | ||
128 | } else if (params->std & V4L2_STD_DK) { | ||
129 | priv->tda8290_easy_mode = 0x10; | ||
130 | mode = "DK"; | ||
131 | } else if (params->std & V4L2_STD_SECAM_L) { | ||
132 | priv->tda8290_easy_mode = 0x20; | ||
133 | mode = "L"; | ||
134 | } else if (params->std & V4L2_STD_SECAM_LC) { | ||
135 | priv->tda8290_easy_mode = 0x40; | ||
136 | mode = "LC"; | ||
137 | } else { | ||
138 | priv->tda8290_easy_mode = 0x10; | ||
139 | mode = "xx"; | ||
140 | } | ||
141 | |||
142 | tuner_dbg("setting tda829x to system %s\n", mode); | ||
143 | } | ||
144 | |||
145 | static void tda8290_set_params(struct dvb_frontend *fe, | ||
146 | struct analog_parameters *params) | ||
147 | { | ||
148 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
149 | |||
150 | unsigned char soft_reset[] = { 0x00, 0x00 }; | ||
151 | unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; | ||
152 | unsigned char expert_mode[] = { 0x01, 0x80 }; | ||
153 | unsigned char agc_out_on[] = { 0x02, 0x00 }; | ||
154 | unsigned char gainset_off[] = { 0x28, 0x14 }; | ||
155 | unsigned char if_agc_spd[] = { 0x0f, 0x88 }; | ||
156 | unsigned char adc_head_6[] = { 0x05, 0x04 }; | ||
157 | unsigned char adc_head_9[] = { 0x05, 0x02 }; | ||
158 | unsigned char adc_head_12[] = { 0x05, 0x01 }; | ||
159 | unsigned char pll_bw_nom[] = { 0x0d, 0x47 }; | ||
160 | unsigned char pll_bw_low[] = { 0x0d, 0x27 }; | ||
161 | unsigned char gainset_2[] = { 0x28, 0x64 }; | ||
162 | unsigned char agc_rst_on[] = { 0x0e, 0x0b }; | ||
163 | unsigned char agc_rst_off[] = { 0x0e, 0x09 }; | ||
164 | unsigned char if_agc_set[] = { 0x0f, 0x81 }; | ||
165 | unsigned char addr_adc_sat = 0x1a; | ||
166 | unsigned char addr_agc_stat = 0x1d; | ||
167 | unsigned char addr_pll_stat = 0x1b; | ||
168 | unsigned char adc_sat, agc_stat, | ||
169 | pll_stat; | ||
170 | int i; | ||
171 | |||
172 | set_audio(fe, params); | ||
173 | |||
174 | if (priv->cfg.config) | ||
175 | tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config); | ||
176 | tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); | ||
177 | tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); | ||
178 | tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); | ||
179 | msleep(1); | ||
180 | |||
181 | expert_mode[1] = priv->tda8290_easy_mode + 0x80; | ||
182 | tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2); | ||
183 | tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2); | ||
184 | tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2); | ||
185 | if (priv->tda8290_easy_mode & 0x60) | ||
186 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2); | ||
187 | else | ||
188 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); | ||
189 | tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); | ||
190 | |||
191 | tda8290_i2c_bridge(fe, 1); | ||
192 | |||
193 | if (fe->ops.tuner_ops.set_analog_params) | ||
194 | fe->ops.tuner_ops.set_analog_params(fe, params); | ||
195 | |||
196 | for (i = 0; i < 3; i++) { | ||
197 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
198 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
199 | if (pll_stat & 0x80) { | ||
200 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); | ||
201 | tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); | ||
202 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | ||
203 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | ||
204 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); | ||
205 | break; | ||
206 | } else { | ||
207 | tuner_dbg("tda8290 not locked, no signal?\n"); | ||
208 | msleep(100); | ||
209 | } | ||
210 | } | ||
211 | /* adjust headroom resp. gain */ | ||
212 | if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { | ||
213 | tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", | ||
214 | agc_stat, adc_sat, pll_stat & 0x80); | ||
215 | tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); | ||
216 | msleep(100); | ||
217 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | ||
218 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | ||
219 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
220 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
221 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { | ||
222 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", | ||
223 | agc_stat, pll_stat & 0x80); | ||
224 | if (priv->cfg.agcf) | ||
225 | priv->cfg.agcf(fe); | ||
226 | msleep(100); | ||
227 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | ||
228 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | ||
229 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
230 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
231 | if((agc_stat > 115) || !(pll_stat & 0x80)) { | ||
232 | tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); | ||
233 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); | ||
234 | tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2); | ||
235 | msleep(100); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | /* l/ l' deadlock? */ | ||
241 | if(priv->tda8290_easy_mode & 0x60) { | ||
242 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); | ||
243 | tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); | ||
244 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
245 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
246 | if ((adc_sat > 20) || !(pll_stat & 0x80)) { | ||
247 | tuner_dbg("trying to resolve SECAM L deadlock\n"); | ||
248 | tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2); | ||
249 | msleep(40); | ||
250 | tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | tda8290_i2c_bridge(fe, 0); | ||
255 | tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); | ||
256 | } | ||
257 | |||
258 | /*---------------------------------------------------------------------*/ | ||
259 | |||
260 | static void tda8295_power(struct dvb_frontend *fe, int enable) | ||
261 | { | ||
262 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
263 | unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ | ||
264 | |||
265 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | ||
266 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
267 | |||
268 | if (enable) | ||
269 | buf[1] = 0x01; | ||
270 | else | ||
271 | buf[1] = 0x03; | ||
272 | |||
273 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
274 | } | ||
275 | |||
276 | static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable) | ||
277 | { | ||
278 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
279 | unsigned char buf[] = { 0x01, 0x00 }; | ||
280 | |||
281 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | ||
282 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
283 | |||
284 | if (enable) | ||
285 | buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ | ||
286 | else | ||
287 | buf[1] = 0x00; /* reset active bit */ | ||
288 | |||
289 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
290 | } | ||
291 | |||
292 | static void tda8295_set_video_std(struct dvb_frontend *fe) | ||
293 | { | ||
294 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
295 | unsigned char buf[] = { 0x00, priv->tda8290_easy_mode }; | ||
296 | |||
297 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
298 | |||
299 | tda8295_set_easy_mode(fe, 1); | ||
300 | msleep(20); | ||
301 | tda8295_set_easy_mode(fe, 0); | ||
302 | } | ||
303 | |||
304 | /*---------------------------------------------------------------------*/ | ||
305 | |||
306 | static void tda8295_agc1_out(struct dvb_frontend *fe, int enable) | ||
307 | { | ||
308 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
309 | unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ | ||
310 | |||
311 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | ||
312 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
313 | |||
314 | if (enable) | ||
315 | buf[1] &= ~0x40; | ||
316 | else | ||
317 | buf[1] |= 0x40; | ||
318 | |||
319 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
320 | } | ||
321 | |||
322 | static void tda8295_agc2_out(struct dvb_frontend *fe, int enable) | ||
323 | { | ||
324 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
325 | unsigned char set_gpio_cf[] = { 0x44, 0x00 }; | ||
326 | unsigned char set_gpio_val[] = { 0x46, 0x00 }; | ||
327 | |||
328 | tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1); | ||
329 | tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1); | ||
330 | tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1); | ||
331 | tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1); | ||
332 | |||
333 | set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ | ||
334 | |||
335 | if (enable) { | ||
336 | set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */ | ||
337 | set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */ | ||
338 | } | ||
339 | tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2); | ||
340 | tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2); | ||
341 | } | ||
342 | |||
343 | static int tda8295_has_signal(struct dvb_frontend *fe) | ||
344 | { | ||
345 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
346 | |||
347 | unsigned char hvpll_stat = 0x26; | ||
348 | unsigned char ret; | ||
349 | |||
350 | tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1); | ||
351 | tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1); | ||
352 | return (ret & 0x01) ? 65535 : 0; | ||
353 | } | ||
354 | |||
355 | /*---------------------------------------------------------------------*/ | ||
356 | |||
357 | static void tda8295_set_params(struct dvb_frontend *fe, | ||
358 | struct analog_parameters *params) | ||
359 | { | ||
360 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
361 | |||
362 | unsigned char blanking_mode[] = { 0x1d, 0x00 }; | ||
363 | |||
364 | set_audio(fe, params); | ||
365 | |||
366 | tuner_dbg("%s: freq = %d\n", __func__, params->frequency); | ||
367 | |||
368 | tda8295_power(fe, 1); | ||
369 | tda8295_agc1_out(fe, 1); | ||
370 | |||
371 | tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1); | ||
372 | tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1); | ||
373 | |||
374 | tda8295_set_video_std(fe); | ||
375 | |||
376 | blanking_mode[1] = 0x03; | ||
377 | tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); | ||
378 | msleep(20); | ||
379 | |||
380 | tda8295_i2c_bridge(fe, 1); | ||
381 | |||
382 | if (fe->ops.tuner_ops.set_analog_params) | ||
383 | fe->ops.tuner_ops.set_analog_params(fe, params); | ||
384 | |||
385 | if (priv->cfg.agcf) | ||
386 | priv->cfg.agcf(fe); | ||
387 | |||
388 | if (tda8295_has_signal(fe)) | ||
389 | tuner_dbg("tda8295 is locked\n"); | ||
390 | else | ||
391 | tuner_dbg("tda8295 not locked, no signal?\n"); | ||
392 | |||
393 | tda8295_i2c_bridge(fe, 0); | ||
394 | } | ||
395 | |||
396 | /*---------------------------------------------------------------------*/ | ||
397 | |||
398 | static int tda8290_has_signal(struct dvb_frontend *fe) | ||
399 | { | ||
400 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
401 | |||
402 | unsigned char i2c_get_afc[1] = { 0x1B }; | ||
403 | unsigned char afc = 0; | ||
404 | |||
405 | tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc)); | ||
406 | tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1); | ||
407 | return (afc & 0x80)? 65535:0; | ||
408 | } | ||
409 | |||
410 | /*---------------------------------------------------------------------*/ | ||
411 | |||
412 | static void tda8290_standby(struct dvb_frontend *fe) | ||
413 | { | ||
414 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
415 | |||
416 | unsigned char cb1[] = { 0x30, 0xD0 }; | ||
417 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; | ||
418 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; | ||
419 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; | ||
420 | |||
421 | tda8290_i2c_bridge(fe, 1); | ||
422 | if (priv->ver & TDA8275A) | ||
423 | cb1[1] = 0x90; | ||
424 | i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
425 | tda8290_i2c_bridge(fe, 0); | ||
426 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); | ||
427 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); | ||
428 | } | ||
429 | |||
430 | static void tda8295_standby(struct dvb_frontend *fe) | ||
431 | { | ||
432 | tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */ | ||
433 | |||
434 | tda8295_power(fe, 0); | ||
435 | } | ||
436 | |||
437 | static void tda8290_init_if(struct dvb_frontend *fe) | ||
438 | { | ||
439 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
440 | |||
441 | unsigned char set_VS[] = { 0x30, 0x6F }; | ||
442 | unsigned char set_GP00_CF[] = { 0x20, 0x01 }; | ||
443 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; | ||
444 | |||
445 | if ((priv->cfg.config == 1) || (priv->cfg.config == 2)) | ||
446 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); | ||
447 | else | ||
448 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); | ||
449 | tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2); | ||
450 | } | ||
451 | |||
452 | static void tda8295_init_if(struct dvb_frontend *fe) | ||
453 | { | ||
454 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
455 | |||
456 | static unsigned char set_adc_ctl[] = { 0x33, 0x14 }; | ||
457 | static unsigned char set_adc_ctl2[] = { 0x34, 0x00 }; | ||
458 | static unsigned char set_pll_reg6[] = { 0x3e, 0x63 }; | ||
459 | static unsigned char set_pll_reg0[] = { 0x38, 0x23 }; | ||
460 | static unsigned char set_pll_reg7[] = { 0x3f, 0x01 }; | ||
461 | static unsigned char set_pll_reg10[] = { 0x42, 0x61 }; | ||
462 | static unsigned char set_gpio_reg0[] = { 0x44, 0x0b }; | ||
463 | |||
464 | tda8295_power(fe, 1); | ||
465 | |||
466 | tda8295_set_easy_mode(fe, 0); | ||
467 | tda8295_set_video_std(fe); | ||
468 | |||
469 | tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2); | ||
470 | tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2); | ||
471 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2); | ||
472 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2); | ||
473 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2); | ||
474 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2); | ||
475 | tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2); | ||
476 | |||
477 | tda8295_agc1_out(fe, 0); | ||
478 | tda8295_agc2_out(fe, 0); | ||
479 | } | ||
480 | |||
481 | static void tda8290_init_tuner(struct dvb_frontend *fe) | ||
482 | { | ||
483 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
484 | unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, | ||
485 | 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; | ||
486 | unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, | ||
487 | 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; | ||
488 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, | ||
489 | .buf=tda8275_init, .len = 14}; | ||
490 | if (priv->ver & TDA8275A) | ||
491 | msg.buf = tda8275a_init; | ||
492 | |||
493 | tda8290_i2c_bridge(fe, 1); | ||
494 | i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
495 | tda8290_i2c_bridge(fe, 0); | ||
496 | } | ||
497 | |||
498 | /*---------------------------------------------------------------------*/ | ||
499 | |||
500 | static void tda829x_release(struct dvb_frontend *fe) | ||
501 | { | ||
502 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
503 | |||
504 | /* only try to release the tuner if we've | ||
505 | * attached it from within this module */ | ||
506 | if (priv->ver & (TDA18271 | TDA8275 | TDA8275A)) | ||
507 | if (fe->ops.tuner_ops.release) | ||
508 | fe->ops.tuner_ops.release(fe); | ||
509 | |||
510 | kfree(fe->analog_demod_priv); | ||
511 | fe->analog_demod_priv = NULL; | ||
512 | } | ||
513 | |||
514 | static struct tda18271_config tda829x_tda18271_config = { | ||
515 | .gate = TDA18271_GATE_ANALOG, | ||
516 | }; | ||
517 | |||
518 | static int tda829x_find_tuner(struct dvb_frontend *fe) | ||
519 | { | ||
520 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
521 | struct analog_demod_ops *analog_ops = &fe->ops.analog_ops; | ||
522 | int i, ret, tuners_found; | ||
523 | u32 tuner_addrs; | ||
524 | u8 data; | ||
525 | struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; | ||
526 | |||
527 | if (NULL == analog_ops->i2c_gate_ctrl) | ||
528 | return -EINVAL; | ||
529 | |||
530 | analog_ops->i2c_gate_ctrl(fe, 1); | ||
531 | |||
532 | /* probe for tuner chip */ | ||
533 | tuners_found = 0; | ||
534 | tuner_addrs = 0; | ||
535 | for (i = 0x60; i <= 0x63; i++) { | ||
536 | msg.addr = i; | ||
537 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
538 | if (ret == 1) { | ||
539 | tuners_found++; | ||
540 | tuner_addrs = (tuner_addrs << 8) + i; | ||
541 | } | ||
542 | } | ||
543 | /* if there is more than one tuner, we expect the right one is | ||
544 | behind the bridge and we choose the highest address that doesn't | ||
545 | give a response now | ||
546 | */ | ||
547 | |||
548 | analog_ops->i2c_gate_ctrl(fe, 0); | ||
549 | |||
550 | if (tuners_found > 1) | ||
551 | for (i = 0; i < tuners_found; i++) { | ||
552 | msg.addr = tuner_addrs & 0xff; | ||
553 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
554 | if (ret == 1) | ||
555 | tuner_addrs = tuner_addrs >> 8; | ||
556 | else | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (tuner_addrs == 0) { | ||
561 | tuner_addrs = 0x60; | ||
562 | tuner_info("could not clearly identify tuner address, " | ||
563 | "defaulting to %x\n", tuner_addrs); | ||
564 | } else { | ||
565 | tuner_addrs = tuner_addrs & 0xff; | ||
566 | tuner_info("setting tuner address to %x\n", tuner_addrs); | ||
567 | } | ||
568 | priv->tda827x_addr = tuner_addrs; | ||
569 | msg.addr = tuner_addrs; | ||
570 | |||
571 | analog_ops->i2c_gate_ctrl(fe, 1); | ||
572 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
573 | |||
574 | if (ret != 1) { | ||
575 | tuner_warn("tuner access failed!\n"); | ||
576 | return -EREMOTEIO; | ||
577 | } | ||
578 | |||
579 | if ((data == 0x83) || (data == 0x84)) { | ||
580 | priv->ver |= TDA18271; | ||
581 | tda18271_attach(fe, priv->tda827x_addr, | ||
582 | priv->i2c_props.adap, | ||
583 | &tda829x_tda18271_config); | ||
584 | } else { | ||
585 | if ((data & 0x3c) == 0) | ||
586 | priv->ver |= TDA8275; | ||
587 | else | ||
588 | priv->ver |= TDA8275A; | ||
589 | |||
590 | tda827x_attach(fe, priv->tda827x_addr, priv->i2c_props.adap, &priv->cfg); | ||
591 | priv->cfg.switch_addr = priv->i2c_props.addr; | ||
592 | } | ||
593 | if (fe->ops.tuner_ops.init) | ||
594 | fe->ops.tuner_ops.init(fe); | ||
595 | |||
596 | if (fe->ops.tuner_ops.sleep) | ||
597 | fe->ops.tuner_ops.sleep(fe); | ||
598 | |||
599 | analog_ops->i2c_gate_ctrl(fe, 0); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int tda8290_probe(struct tuner_i2c_props *i2c_props) | ||
605 | { | ||
606 | #define TDA8290_ID 0x89 | ||
607 | unsigned char tda8290_id[] = { 0x1f, 0x00 }; | ||
608 | |||
609 | /* detect tda8290 */ | ||
610 | tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1); | ||
611 | tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); | ||
612 | |||
613 | if (tda8290_id[1] == TDA8290_ID) { | ||
614 | if (debug) | ||
615 | printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", | ||
616 | __func__, i2c_adapter_id(i2c_props->adap), | ||
617 | i2c_props->addr); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | return -ENODEV; | ||
622 | } | ||
623 | |||
624 | static int tda8295_probe(struct tuner_i2c_props *i2c_props) | ||
625 | { | ||
626 | #define TDA8295_ID 0x8a | ||
627 | unsigned char tda8295_id[] = { 0x2f, 0x00 }; | ||
628 | |||
629 | /* detect tda8295 */ | ||
630 | tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); | ||
631 | tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); | ||
632 | |||
633 | if (tda8295_id[1] == TDA8295_ID) { | ||
634 | if (debug) | ||
635 | printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", | ||
636 | __func__, i2c_adapter_id(i2c_props->adap), | ||
637 | i2c_props->addr); | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | return -ENODEV; | ||
642 | } | ||
643 | |||
644 | static struct analog_demod_ops tda8290_ops = { | ||
645 | .set_params = tda8290_set_params, | ||
646 | .has_signal = tda8290_has_signal, | ||
647 | .standby = tda8290_standby, | ||
648 | .release = tda829x_release, | ||
649 | .i2c_gate_ctrl = tda8290_i2c_bridge, | ||
650 | }; | ||
651 | |||
652 | static struct analog_demod_ops tda8295_ops = { | ||
653 | .set_params = tda8295_set_params, | ||
654 | .has_signal = tda8295_has_signal, | ||
655 | .standby = tda8295_standby, | ||
656 | .release = tda829x_release, | ||
657 | .i2c_gate_ctrl = tda8295_i2c_bridge, | ||
658 | }; | ||
659 | |||
660 | struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | ||
661 | struct i2c_adapter *i2c_adap, u8 i2c_addr, | ||
662 | struct tda829x_config *cfg) | ||
663 | { | ||
664 | struct tda8290_priv *priv = NULL; | ||
665 | char *name; | ||
666 | |||
667 | priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); | ||
668 | if (priv == NULL) | ||
669 | return NULL; | ||
670 | fe->analog_demod_priv = priv; | ||
671 | |||
672 | priv->i2c_props.addr = i2c_addr; | ||
673 | priv->i2c_props.adap = i2c_adap; | ||
674 | priv->i2c_props.name = "tda829x"; | ||
675 | if (cfg) { | ||
676 | priv->cfg.config = cfg->lna_cfg; | ||
677 | priv->cfg.tuner_callback = cfg->tuner_callback; | ||
678 | } | ||
679 | |||
680 | if (tda8290_probe(&priv->i2c_props) == 0) { | ||
681 | priv->ver = TDA8290; | ||
682 | memcpy(&fe->ops.analog_ops, &tda8290_ops, | ||
683 | sizeof(struct analog_demod_ops)); | ||
684 | } | ||
685 | |||
686 | if (tda8295_probe(&priv->i2c_props) == 0) { | ||
687 | priv->ver = TDA8295; | ||
688 | memcpy(&fe->ops.analog_ops, &tda8295_ops, | ||
689 | sizeof(struct analog_demod_ops)); | ||
690 | } | ||
691 | |||
692 | if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) && | ||
693 | (tda829x_find_tuner(fe) < 0)) | ||
694 | goto fail; | ||
695 | |||
696 | switch (priv->ver) { | ||
697 | case TDA8290: | ||
698 | name = "tda8290"; | ||
699 | break; | ||
700 | case TDA8295: | ||
701 | name = "tda8295"; | ||
702 | break; | ||
703 | case TDA8290 | TDA8275: | ||
704 | name = "tda8290+75"; | ||
705 | break; | ||
706 | case TDA8295 | TDA8275: | ||
707 | name = "tda8295+75"; | ||
708 | break; | ||
709 | case TDA8290 | TDA8275A: | ||
710 | name = "tda8290+75a"; | ||
711 | break; | ||
712 | case TDA8295 | TDA8275A: | ||
713 | name = "tda8295+75a"; | ||
714 | break; | ||
715 | case TDA8290 | TDA18271: | ||
716 | name = "tda8290+18271"; | ||
717 | break; | ||
718 | case TDA8295 | TDA18271: | ||
719 | name = "tda8295+18271"; | ||
720 | break; | ||
721 | default: | ||
722 | goto fail; | ||
723 | } | ||
724 | tuner_info("type set to %s\n", name); | ||
725 | |||
726 | fe->ops.analog_ops.info.name = name; | ||
727 | |||
728 | if (priv->ver & TDA8290) { | ||
729 | tda8290_init_tuner(fe); | ||
730 | tda8290_init_if(fe); | ||
731 | } else if (priv->ver & TDA8295) | ||
732 | tda8295_init_if(fe); | ||
733 | |||
734 | return fe; | ||
735 | |||
736 | fail: | ||
737 | tda829x_release(fe); | ||
738 | return NULL; | ||
739 | } | ||
740 | EXPORT_SYMBOL_GPL(tda829x_attach); | ||
741 | |||
742 | int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) | ||
743 | { | ||
744 | struct tuner_i2c_props i2c_props = { | ||
745 | .adap = i2c_adap, | ||
746 | .addr = i2c_addr, | ||
747 | }; | ||
748 | |||
749 | unsigned char soft_reset[] = { 0x00, 0x00 }; | ||
750 | unsigned char easy_mode_b[] = { 0x01, 0x02 }; | ||
751 | unsigned char easy_mode_g[] = { 0x01, 0x04 }; | ||
752 | unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; | ||
753 | unsigned char addr_dto_lsb = 0x07; | ||
754 | unsigned char data; | ||
755 | #define PROBE_BUFFER_SIZE 8 | ||
756 | unsigned char buf[PROBE_BUFFER_SIZE]; | ||
757 | int i; | ||
758 | |||
759 | /* rule out tda9887, which would return the same byte repeatedly */ | ||
760 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 1); | ||
761 | tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE); | ||
762 | for (i = 1; i < PROBE_BUFFER_SIZE; i++) { | ||
763 | if (buf[i] != buf[0]) | ||
764 | break; | ||
765 | } | ||
766 | |||
767 | /* all bytes are equal, not a tda829x - probably a tda9887 */ | ||
768 | if (i == PROBE_BUFFER_SIZE) | ||
769 | return -ENODEV; | ||
770 | |||
771 | if ((tda8290_probe(&i2c_props) == 0) || | ||
772 | (tda8295_probe(&i2c_props) == 0)) | ||
773 | return 0; | ||
774 | |||
775 | /* fall back to old probing method */ | ||
776 | tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); | ||
777 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); | ||
778 | tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); | ||
779 | tuner_i2c_xfer_recv(&i2c_props, &data, 1); | ||
780 | if (data == 0) { | ||
781 | tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); | ||
782 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); | ||
783 | tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); | ||
784 | tuner_i2c_xfer_recv(&i2c_props, &data, 1); | ||
785 | if (data == 0x7b) { | ||
786 | return 0; | ||
787 | } | ||
788 | } | ||
789 | tuner_i2c_xfer_send(&i2c_props, restore_9886, 3); | ||
790 | return -ENODEV; | ||
791 | } | ||
792 | EXPORT_SYMBOL_GPL(tda829x_probe); | ||
793 | |||
794 | MODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver"); | ||
795 | MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky"); | ||
796 | MODULE_LICENSE("GPL"); | ||
797 | |||
798 | /* | ||
799 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
800 | * --------------------------------------------------------------------------- | ||
801 | * Local variables: | ||
802 | * c-basic-offset: 8 | ||
803 | * End: | ||
804 | */ | ||
diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h deleted file mode 100644 index d3bbf276a469..000000000000 --- a/drivers/media/video/tda8290.h +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or modify | ||
3 | it under the terms of the GNU General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or | ||
5 | (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU General Public License | ||
13 | along with this program; if not, write to the Free Software | ||
14 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TDA8290_H__ | ||
18 | #define __TDA8290_H__ | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | struct tda829x_config { | ||
24 | unsigned int lna_cfg; | ||
25 | int (*tuner_callback) (void *dev, int command, int arg); | ||
26 | |||
27 | unsigned int probe_tuner:1; | ||
28 | #define TDA829X_PROBE_TUNER 0 | ||
29 | #define TDA829X_DONT_PROBE 1 | ||
30 | }; | ||
31 | |||
32 | #if defined(CONFIG_TUNER_TDA8290) || (defined(CONFIG_TUNER_TDA8290_MODULE) && defined(MODULE)) | ||
33 | extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr); | ||
34 | |||
35 | extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | ||
36 | struct i2c_adapter *i2c_adap, | ||
37 | u8 i2c_addr, | ||
38 | struct tda829x_config *cfg); | ||
39 | #else | ||
40 | static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) | ||
41 | { | ||
42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
43 | return -EINVAL; | ||
44 | } | ||
45 | |||
46 | static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | ||
47 | struct i2c_adapter *i2c_adap, | ||
48 | u8 i2c_addr, | ||
49 | struct tda829x_config *cfg) | ||
50 | { | ||
51 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | ||
52 | __func__); | ||
53 | return NULL; | ||
54 | } | ||
55 | #endif | ||
56 | |||
57 | #endif /* __TDA8290_H__ */ | ||
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c deleted file mode 100644 index a0545ba957b0..000000000000 --- a/drivers/media/video/tda9887.c +++ /dev/null | |||
@@ -1,717 +0,0 @@ | |||
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/slab.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/videodev.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 | |||
42 | /* ---------------------------------------------------------------------- */ | ||
43 | |||
44 | #define UNSET (-1U) | ||
45 | |||
46 | struct tvnorm { | ||
47 | v4l2_std_id std; | ||
48 | char *name; | ||
49 | unsigned char b; | ||
50 | unsigned char c; | ||
51 | unsigned char e; | ||
52 | }; | ||
53 | |||
54 | /* ---------------------------------------------------------------------- */ | ||
55 | |||
56 | // | ||
57 | // TDA defines | ||
58 | // | ||
59 | |||
60 | //// first reg (b) | ||
61 | #define cVideoTrapBypassOFF 0x00 // bit b0 | ||
62 | #define cVideoTrapBypassON 0x01 // bit b0 | ||
63 | |||
64 | #define cAutoMuteFmInactive 0x00 // bit b1 | ||
65 | #define cAutoMuteFmActive 0x02 // bit b1 | ||
66 | |||
67 | #define cIntercarrier 0x00 // bit b2 | ||
68 | #define cQSS 0x04 // bit b2 | ||
69 | |||
70 | #define cPositiveAmTV 0x00 // bit b3:4 | ||
71 | #define cFmRadio 0x08 // bit b3:4 | ||
72 | #define cNegativeFmTV 0x10 // bit b3:4 | ||
73 | |||
74 | |||
75 | #define cForcedMuteAudioON 0x20 // bit b5 | ||
76 | #define cForcedMuteAudioOFF 0x00 // bit b5 | ||
77 | |||
78 | #define cOutputPort1Active 0x00 // bit b6 | ||
79 | #define cOutputPort1Inactive 0x40 // bit b6 | ||
80 | |||
81 | #define cOutputPort2Active 0x00 // bit b7 | ||
82 | #define cOutputPort2Inactive 0x80 // bit b7 | ||
83 | |||
84 | |||
85 | //// second reg (c) | ||
86 | #define cDeemphasisOFF 0x00 // bit c5 | ||
87 | #define cDeemphasisON 0x20 // bit c5 | ||
88 | |||
89 | #define cDeemphasis75 0x00 // bit c6 | ||
90 | #define cDeemphasis50 0x40 // bit c6 | ||
91 | |||
92 | #define cAudioGain0 0x00 // bit c7 | ||
93 | #define cAudioGain6 0x80 // bit c7 | ||
94 | |||
95 | #define cTopMask 0x1f // bit c0:4 | ||
96 | #define cTopDefault 0x10 // bit c0:4 | ||
97 | |||
98 | //// third reg (e) | ||
99 | #define cAudioIF_4_5 0x00 // bit e0:1 | ||
100 | #define cAudioIF_5_5 0x01 // bit e0:1 | ||
101 | #define cAudioIF_6_0 0x02 // bit e0:1 | ||
102 | #define cAudioIF_6_5 0x03 // bit e0:1 | ||
103 | |||
104 | |||
105 | #define cVideoIFMask 0x1c // bit e2:4 | ||
106 | /* Video IF selection in TV Mode (bit B3=0) */ | ||
107 | #define cVideoIF_58_75 0x00 // bit e2:4 | ||
108 | #define cVideoIF_45_75 0x04 // bit e2:4 | ||
109 | #define cVideoIF_38_90 0x08 // bit e2:4 | ||
110 | #define cVideoIF_38_00 0x0C // bit e2:4 | ||
111 | #define cVideoIF_33_90 0x10 // bit e2:4 | ||
112 | #define cVideoIF_33_40 0x14 // bit e2:4 | ||
113 | #define cRadioIF_45_75 0x18 // bit e2:4 | ||
114 | #define cRadioIF_38_90 0x1C // bit e2:4 | ||
115 | |||
116 | /* IF1 selection in Radio Mode (bit B3=1) */ | ||
117 | #define cRadioIF_33_30 0x00 // bit e2,4 (also 0x10,0x14) | ||
118 | #define cRadioIF_41_30 0x04 // bit e2,4 | ||
119 | |||
120 | /* Output of AFC pin in radio mode when bit E7=1 */ | ||
121 | #define cRadioAGC_SIF 0x00 // bit e3 | ||
122 | #define cRadioAGC_FM 0x08 // bit e3 | ||
123 | |||
124 | #define cTunerGainNormal 0x00 // bit e5 | ||
125 | #define cTunerGainLow 0x20 // bit e5 | ||
126 | |||
127 | #define cGating_18 0x00 // bit e6 | ||
128 | #define cGating_36 0x40 // bit e6 | ||
129 | |||
130 | #define cAgcOutON 0x80 // bit e7 | ||
131 | #define cAgcOutOFF 0x00 // bit e7 | ||
132 | |||
133 | /* ---------------------------------------------------------------------- */ | ||
134 | |||
135 | static struct tvnorm tvnorms[] = { | ||
136 | { | ||
137 | .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N, | ||
138 | .name = "PAL-BGHN", | ||
139 | .b = ( cNegativeFmTV | | ||
140 | cQSS ), | ||
141 | .c = ( cDeemphasisON | | ||
142 | cDeemphasis50 | | ||
143 | cTopDefault), | ||
144 | .e = ( cGating_36 | | ||
145 | cAudioIF_5_5 | | ||
146 | cVideoIF_38_90 ), | ||
147 | },{ | ||
148 | .std = V4L2_STD_PAL_I, | ||
149 | .name = "PAL-I", | ||
150 | .b = ( cNegativeFmTV | | ||
151 | cQSS ), | ||
152 | .c = ( cDeemphasisON | | ||
153 | cDeemphasis50 | | ||
154 | cTopDefault), | ||
155 | .e = ( cGating_36 | | ||
156 | cAudioIF_6_0 | | ||
157 | cVideoIF_38_90 ), | ||
158 | },{ | ||
159 | .std = V4L2_STD_PAL_DK, | ||
160 | .name = "PAL-DK", | ||
161 | .b = ( cNegativeFmTV | | ||
162 | cQSS ), | ||
163 | .c = ( cDeemphasisON | | ||
164 | cDeemphasis50 | | ||
165 | cTopDefault), | ||
166 | .e = ( cGating_36 | | ||
167 | cAudioIF_6_5 | | ||
168 | cVideoIF_38_90 ), | ||
169 | },{ | ||
170 | .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc, | ||
171 | .name = "PAL-M/Nc", | ||
172 | .b = ( cNegativeFmTV | | ||
173 | cQSS ), | ||
174 | .c = ( cDeemphasisON | | ||
175 | cDeemphasis75 | | ||
176 | cTopDefault), | ||
177 | .e = ( cGating_36 | | ||
178 | cAudioIF_4_5 | | ||
179 | cVideoIF_45_75 ), | ||
180 | },{ | ||
181 | .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, | ||
182 | .name = "SECAM-BGH", | ||
183 | .b = ( cPositiveAmTV | | ||
184 | cQSS ), | ||
185 | .c = ( cTopDefault), | ||
186 | .e = ( cGating_36 | | ||
187 | 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 | |||
244 | static 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 | |||
256 | static 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 | |||
270 | static 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 | |||
300 | static 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 | |||
400 | static 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 | |||
432 | static unsigned int port1 = UNSET; | ||
433 | static unsigned int port2 = UNSET; | ||
434 | static unsigned int qss = UNSET; | ||
435 | static unsigned int adjust = UNSET; | ||
436 | |||
437 | module_param(port1, int, 0644); | ||
438 | module_param(port2, int, 0644); | ||
439 | module_param(qss, int, 0644); | ||
440 | module_param(adjust, int, 0644); | ||
441 | |||
442 | static 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 >= 0x00 && adjust < 0x20) { | ||
468 | buf[2] &= ~cTopMask; | ||
469 | buf[2] |= adjust; | ||
470 | } | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static 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 | |||
533 | static 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 | memset(buf,0,sizeof(buf)); | ||
540 | if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,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 | |||
546 | static 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->mode == T_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 | |||
592 | static 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 | |||
599 | static int tda9887_get_afc(struct dvb_frontend *fe) | ||
600 | { | ||
601 | struct tda9887_priv *priv = fe->analog_demod_priv; | ||
602 | static 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 | int afc=0; | ||
609 | __u8 reg = 0; | ||
610 | |||
611 | if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,®,1)) | ||
612 | afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; | ||
613 | |||
614 | return afc; | ||
615 | } | ||
616 | |||
617 | static void tda9887_standby(struct dvb_frontend *fe) | ||
618 | { | ||
619 | struct tda9887_priv *priv = fe->analog_demod_priv; | ||
620 | |||
621 | priv->mode = T_STANDBY; | ||
622 | |||
623 | tda9887_configure(fe); | ||
624 | } | ||
625 | |||
626 | static 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->mode = params->mode; | ||
632 | priv->audmode = params->audmode; | ||
633 | priv->std = params->std; | ||
634 | tda9887_configure(fe); | ||
635 | } | ||
636 | |||
637 | static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg) | ||
638 | { | ||
639 | struct tda9887_priv *priv = fe->analog_demod_priv; | ||
640 | |||
641 | priv->config = *(unsigned int *)priv_cfg; | ||
642 | tda9887_configure(fe); | ||
643 | |||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static void tda9887_release(struct dvb_frontend *fe) | ||
648 | { | ||
649 | struct tda9887_priv *priv = fe->analog_demod_priv; | ||
650 | |||
651 | mutex_lock(&tda9887_list_mutex); | ||
652 | |||
653 | if (priv) | ||
654 | hybrid_tuner_release_state(priv); | ||
655 | |||
656 | mutex_unlock(&tda9887_list_mutex); | ||
657 | |||
658 | fe->analog_demod_priv = NULL; | ||
659 | } | ||
660 | |||
661 | static struct analog_demod_ops tda9887_ops = { | ||
662 | .info = { | ||
663 | .name = "tda9887", | ||
664 | }, | ||
665 | .set_params = tda9887_set_params, | ||
666 | .standby = tda9887_standby, | ||
667 | .tuner_status = tda9887_tuner_status, | ||
668 | .get_afc = tda9887_get_afc, | ||
669 | .release = tda9887_release, | ||
670 | .set_config = tda9887_set_config, | ||
671 | }; | ||
672 | |||
673 | struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | ||
674 | struct i2c_adapter *i2c_adap, | ||
675 | u8 i2c_addr) | ||
676 | { | ||
677 | struct tda9887_priv *priv = NULL; | ||
678 | int instance; | ||
679 | |||
680 | mutex_lock(&tda9887_list_mutex); | ||
681 | |||
682 | instance = hybrid_tuner_request_state(struct tda9887_priv, priv, | ||
683 | hybrid_tuner_instance_list, | ||
684 | i2c_adap, i2c_addr, "tda9887"); | ||
685 | switch (instance) { | ||
686 | case 0: | ||
687 | mutex_unlock(&tda9887_list_mutex); | ||
688 | return NULL; | ||
689 | break; | ||
690 | case 1: | ||
691 | fe->analog_demod_priv = priv; | ||
692 | priv->mode = T_STANDBY; | ||
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 | } | ||
707 | EXPORT_SYMBOL_GPL(tda9887_attach); | ||
708 | |||
709 | MODULE_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 | */ | ||
diff --git a/drivers/media/video/tda9887.h b/drivers/media/video/tda9887.h deleted file mode 100644 index be49dcbfc70e..000000000000 --- a/drivers/media/video/tda9887.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or modify | ||
3 | it under the terms of the GNU General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or | ||
5 | (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU General Public License | ||
13 | along with this program; if not, write to the Free Software | ||
14 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TDA9887_H__ | ||
18 | #define __TDA9887_H__ | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | /* ------------------------------------------------------------------------ */ | ||
24 | #if defined(CONFIG_TUNER_TDA9887) || (defined(CONFIG_TUNER_TDA9887_MODULE) && defined(MODULE)) | ||
25 | extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | ||
26 | struct i2c_adapter *i2c_adap, | ||
27 | u8 i2c_addr); | ||
28 | #else | ||
29 | static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | ||
30 | struct i2c_adapter *i2c_adap, | ||
31 | u8 i2c_addr) | ||
32 | { | ||
33 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
34 | return NULL; | ||
35 | } | ||
36 | #endif | ||
37 | |||
38 | #endif /* __TDA9887_H__ */ | ||
diff --git a/drivers/media/video/tea5761.c b/drivers/media/video/tea5761.c deleted file mode 100644 index b93cdef9ac73..000000000000 --- a/drivers/media/video/tea5761.c +++ /dev/null | |||
@@ -1,324 +0,0 @@ | |||
1 | /* | ||
2 | * For Philips TEA5761 FM Chip | ||
3 | * I2C address is allways 0x20 (0x10 at 7-bit mode). | ||
4 | * | ||
5 | * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
6 | * This code is placed under the terms of the GNUv2 General Public License | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/videodev.h> | ||
13 | #include <media/tuner.h> | ||
14 | #include "tuner-i2c.h" | ||
15 | #include "tea5761.h" | ||
16 | |||
17 | static int debug; | ||
18 | module_param(debug, int, 0644); | ||
19 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
20 | |||
21 | struct tea5761_priv { | ||
22 | struct tuner_i2c_props i2c_props; | ||
23 | |||
24 | u32 frequency; | ||
25 | }; | ||
26 | |||
27 | /*****************************************************************************/ | ||
28 | |||
29 | /*************************** | ||
30 | * TEA5761HN I2C registers * | ||
31 | ***************************/ | ||
32 | |||
33 | /* INTREG - Read: bytes 0 and 1 / Write: byte 0 */ | ||
34 | |||
35 | /* first byte for reading */ | ||
36 | #define TEA5761_INTREG_IFFLAG 0x10 | ||
37 | #define TEA5761_INTREG_LEVFLAG 0x8 | ||
38 | #define TEA5761_INTREG_FRRFLAG 0x2 | ||
39 | #define TEA5761_INTREG_BLFLAG 0x1 | ||
40 | |||
41 | /* second byte for reading / byte for writing */ | ||
42 | #define TEA5761_INTREG_IFMSK 0x10 | ||
43 | #define TEA5761_INTREG_LEVMSK 0x8 | ||
44 | #define TEA5761_INTREG_FRMSK 0x2 | ||
45 | #define TEA5761_INTREG_BLMSK 0x1 | ||
46 | |||
47 | /* FRQSET - Read: bytes 2 and 3 / Write: byte 1 and 2 */ | ||
48 | |||
49 | /* First byte */ | ||
50 | #define TEA5761_FRQSET_SEARCH_UP 0x80 /* 1=Station search from botton to up */ | ||
51 | #define TEA5761_FRQSET_SEARCH_MODE 0x40 /* 1=Search mode */ | ||
52 | |||
53 | /* Bits 0-5 for divider MSB */ | ||
54 | |||
55 | /* Second byte */ | ||
56 | /* Bits 0-7 for divider LSB */ | ||
57 | |||
58 | /* TNCTRL - Read: bytes 4 and 5 / Write: Bytes 3 and 4 */ | ||
59 | |||
60 | /* first byte */ | ||
61 | |||
62 | #define TEA5761_TNCTRL_PUPD_0 0x40 /* Power UP/Power Down MSB */ | ||
63 | #define TEA5761_TNCTRL_BLIM 0X20 /* 1= Japan Frequencies, 0= European frequencies */ | ||
64 | #define TEA5761_TNCTRL_SWPM 0x10 /* 1= software port is FRRFLAG */ | ||
65 | #define TEA5761_TNCTRL_IFCTC 0x08 /* 1= IF count time 15.02 ms, 0= IF count time 2.02 ms */ | ||
66 | #define TEA5761_TNCTRL_AFM 0x04 | ||
67 | #define TEA5761_TNCTRL_SMUTE 0x02 /* 1= Soft mute */ | ||
68 | #define TEA5761_TNCTRL_SNC 0x01 | ||
69 | |||
70 | /* second byte */ | ||
71 | |||
72 | #define TEA5761_TNCTRL_MU 0x80 /* 1=Hard mute */ | ||
73 | #define TEA5761_TNCTRL_SSL_1 0x40 | ||
74 | #define TEA5761_TNCTRL_SSL_0 0x20 | ||
75 | #define TEA5761_TNCTRL_HLSI 0x10 | ||
76 | #define TEA5761_TNCTRL_MST 0x08 /* 1 = mono */ | ||
77 | #define TEA5761_TNCTRL_SWP 0x04 | ||
78 | #define TEA5761_TNCTRL_DTC 0x02 /* 1 = deemphasis 50 us, 0 = deemphasis 75 us */ | ||
79 | #define TEA5761_TNCTRL_AHLSI 0x01 | ||
80 | |||
81 | /* FRQCHECK - Read: bytes 6 and 7 */ | ||
82 | /* First byte */ | ||
83 | |||
84 | /* Bits 0-5 for divider MSB */ | ||
85 | |||
86 | /* Second byte */ | ||
87 | /* Bits 0-7 for divider LSB */ | ||
88 | |||
89 | /* TUNCHECK - Read: bytes 8 and 9 */ | ||
90 | |||
91 | /* First byte */ | ||
92 | #define TEA5761_TUNCHECK_IF_MASK 0x7e /* IF count */ | ||
93 | #define TEA5761_TUNCHECK_TUNTO 0x01 | ||
94 | |||
95 | /* Second byte */ | ||
96 | #define TEA5761_TUNCHECK_LEV_MASK 0xf0 /* Level Count */ | ||
97 | #define TEA5761_TUNCHECK_LD 0x08 | ||
98 | #define TEA5761_TUNCHECK_STEREO 0x04 | ||
99 | |||
100 | /* TESTREG - Read: bytes 10 and 11 / Write: bytes 5 and 6 */ | ||
101 | |||
102 | /* All zero = no test mode */ | ||
103 | |||
104 | /* MANID - Read: bytes 12 and 13 */ | ||
105 | |||
106 | /* First byte - should be 0x10 */ | ||
107 | #define TEA5767_MANID_VERSION_MASK 0xf0 /* Version = 1 */ | ||
108 | #define TEA5767_MANID_ID_MSB_MASK 0x0f /* Manufacurer ID - should be 0 */ | ||
109 | |||
110 | /* Second byte - Should be 0x2b */ | ||
111 | |||
112 | #define TEA5767_MANID_ID_LSB_MASK 0xfe /* Manufacturer ID - should be 0x15 */ | ||
113 | #define TEA5767_MANID_IDAV 0x01 /* 1 = Chip has ID, 0 = Chip has no ID */ | ||
114 | |||
115 | /* Chip ID - Read: bytes 14 and 15 */ | ||
116 | |||
117 | /* First byte - should be 0x57 */ | ||
118 | |||
119 | /* Second byte - should be 0x61 */ | ||
120 | |||
121 | /*****************************************************************************/ | ||
122 | |||
123 | #define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */ | ||
124 | static void tea5761_status_dump(unsigned char *buffer) | ||
125 | { | ||
126 | unsigned int div, frq; | ||
127 | |||
128 | div = ((buffer[2] & 0x3f) << 8) | buffer[3]; | ||
129 | |||
130 | frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */ | ||
131 | |||
132 | printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n", | ||
133 | frq / 1000, frq % 1000, div); | ||
134 | } | ||
135 | |||
136 | /* Freq should be specifyed at 62.5 Hz */ | ||
137 | static int set_radio_freq(struct dvb_frontend *fe, | ||
138 | struct analog_parameters *params) | ||
139 | { | ||
140 | struct tea5761_priv *priv = fe->tuner_priv; | ||
141 | unsigned int frq = params->frequency; | ||
142 | unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 }; | ||
143 | unsigned div; | ||
144 | int rc; | ||
145 | |||
146 | tuner_dbg("radio freq counter %d\n", frq); | ||
147 | |||
148 | if (params->mode == T_STANDBY) { | ||
149 | tuner_dbg("TEA5761 set to standby mode\n"); | ||
150 | buffer[5] |= TEA5761_TNCTRL_MU; | ||
151 | } else { | ||
152 | buffer[4] |= TEA5761_TNCTRL_PUPD_0; | ||
153 | } | ||
154 | |||
155 | |||
156 | if (params->audmode == V4L2_TUNER_MODE_MONO) { | ||
157 | tuner_dbg("TEA5761 set to mono\n"); | ||
158 | buffer[5] |= TEA5761_TNCTRL_MST; | ||
159 | } else { | ||
160 | tuner_dbg("TEA5761 set to stereo\n"); | ||
161 | } | ||
162 | |||
163 | div = (1000 * (frq * 4 / 16 + 700 + 225) ) >> 15; | ||
164 | buffer[1] = (div >> 8) & 0x3f; | ||
165 | buffer[2] = div & 0xff; | ||
166 | |||
167 | if (debug) | ||
168 | tea5761_status_dump(buffer); | ||
169 | |||
170 | if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7))) | ||
171 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
172 | |||
173 | priv->frequency = frq * 125 / 2; | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int tea5761_read_status(struct dvb_frontend *fe, char *buffer) | ||
179 | { | ||
180 | struct tea5761_priv *priv = fe->tuner_priv; | ||
181 | int rc; | ||
182 | |||
183 | memset(buffer, 0, 16); | ||
184 | if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) { | ||
185 | tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc); | ||
186 | return -EREMOTEIO; | ||
187 | } | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer) | ||
193 | { | ||
194 | struct tea5761_priv *priv = fe->tuner_priv; | ||
195 | |||
196 | int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4)); | ||
197 | |||
198 | tuner_dbg("Signal strength: %d\n", signal); | ||
199 | |||
200 | return signal; | ||
201 | } | ||
202 | |||
203 | static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer) | ||
204 | { | ||
205 | struct tea5761_priv *priv = fe->tuner_priv; | ||
206 | |||
207 | int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO; | ||
208 | |||
209 | tuner_dbg("Radio ST GET = %02x\n", stereo); | ||
210 | |||
211 | return (stereo ? V4L2_TUNER_SUB_STEREO : 0); | ||
212 | } | ||
213 | |||
214 | static int tea5761_get_status(struct dvb_frontend *fe, u32 *status) | ||
215 | { | ||
216 | unsigned char buffer[16]; | ||
217 | |||
218 | *status = 0; | ||
219 | |||
220 | if (0 == tea5761_read_status(fe, buffer)) { | ||
221 | if (tea5761_signal(fe, buffer)) | ||
222 | *status = TUNER_STATUS_LOCKED; | ||
223 | if (tea5761_stereo(fe, buffer)) | ||
224 | *status |= TUNER_STATUS_STEREO; | ||
225 | } | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | ||
231 | { | ||
232 | unsigned char buffer[16]; | ||
233 | |||
234 | *strength = 0; | ||
235 | |||
236 | if (0 == tea5761_read_status(fe, buffer)) | ||
237 | *strength = tea5761_signal(fe, buffer); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) | ||
243 | { | ||
244 | unsigned char buffer[16]; | ||
245 | int rc; | ||
246 | struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr }; | ||
247 | |||
248 | if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) { | ||
249 | printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) { | ||
254 | printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x." | ||
255 | " It is not a TEA5761\n", | ||
256 | buffer[13], buffer[14], buffer[15]); | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | printk(KERN_WARNING "tea5761: TEA%02x%02x detected. " | ||
260 | "Manufacturer ID= 0x%02x\n", | ||
261 | buffer[14], buffer[15], buffer[13]); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int tea5761_release(struct dvb_frontend *fe) | ||
267 | { | ||
268 | kfree(fe->tuner_priv); | ||
269 | fe->tuner_priv = NULL; | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
275 | { | ||
276 | struct tea5761_priv *priv = fe->tuner_priv; | ||
277 | *frequency = priv->frequency; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static struct dvb_tuner_ops tea5761_tuner_ops = { | ||
282 | .info = { | ||
283 | .name = "tea5761", // Philips TEA5761HN FM Radio | ||
284 | }, | ||
285 | .set_analog_params = set_radio_freq, | ||
286 | .release = tea5761_release, | ||
287 | .get_frequency = tea5761_get_frequency, | ||
288 | .get_status = tea5761_get_status, | ||
289 | .get_rf_strength = tea5761_get_rf_strength, | ||
290 | }; | ||
291 | |||
292 | struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | ||
293 | struct i2c_adapter* i2c_adap, | ||
294 | u8 i2c_addr) | ||
295 | { | ||
296 | struct tea5761_priv *priv = NULL; | ||
297 | |||
298 | if (tea5761_autodetection(i2c_adap, i2c_addr) == EINVAL) | ||
299 | return NULL; | ||
300 | |||
301 | priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); | ||
302 | if (priv == NULL) | ||
303 | return NULL; | ||
304 | fe->tuner_priv = priv; | ||
305 | |||
306 | priv->i2c_props.addr = i2c_addr; | ||
307 | priv->i2c_props.adap = i2c_adap; | ||
308 | priv->i2c_props.name = "tea5761"; | ||
309 | |||
310 | memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops, | ||
311 | sizeof(struct dvb_tuner_ops)); | ||
312 | |||
313 | tuner_info("type set to %s\n", "Philips TEA5761HN FM Radio"); | ||
314 | |||
315 | return fe; | ||
316 | } | ||
317 | |||
318 | |||
319 | EXPORT_SYMBOL_GPL(tea5761_attach); | ||
320 | EXPORT_SYMBOL_GPL(tea5761_autodetection); | ||
321 | |||
322 | MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver"); | ||
323 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | ||
324 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tea5761.h b/drivers/media/video/tea5761.h deleted file mode 100644 index 8eb62722b988..000000000000 --- a/drivers/media/video/tea5761.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or modify | ||
3 | it under the terms of the GNU General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or | ||
5 | (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU General Public License | ||
13 | along with this program; if not, write to the Free Software | ||
14 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TEA5761_H__ | ||
18 | #define __TEA5761_H__ | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | #if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE)) | ||
24 | extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); | ||
25 | |||
26 | extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | ||
27 | struct i2c_adapter* i2c_adap, | ||
28 | u8 i2c_addr); | ||
29 | #else | ||
30 | static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap, | ||
31 | u8 i2c_addr) | ||
32 | { | ||
33 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | ||
34 | __func__); | ||
35 | return -EINVAL; | ||
36 | } | ||
37 | |||
38 | static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | ||
39 | struct i2c_adapter* i2c_adap, | ||
40 | u8 i2c_addr) | ||
41 | { | ||
42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
43 | return NULL; | ||
44 | } | ||
45 | #endif | ||
46 | |||
47 | #endif /* __TEA5761_H__ */ | ||
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c deleted file mode 100644 index f6e7d7ad8424..000000000000 --- a/drivers/media/video/tea5767.c +++ /dev/null | |||
@@ -1,474 +0,0 @@ | |||
1 | /* | ||
2 | * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview | ||
3 | * I2C address is allways 0xC0. | ||
4 | * | ||
5 | * | ||
6 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
7 | * This code is placed under the terms of the GNU General Public License | ||
8 | * | ||
9 | * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa | ||
10 | * from their contributions on DScaler. | ||
11 | */ | ||
12 | |||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/videodev.h> | ||
16 | #include "tuner-i2c.h" | ||
17 | #include "tea5767.h" | ||
18 | |||
19 | static int debug; | ||
20 | module_param(debug, int, 0644); | ||
21 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
22 | |||
23 | /*****************************************************************************/ | ||
24 | |||
25 | struct tea5767_priv { | ||
26 | struct tuner_i2c_props i2c_props; | ||
27 | u32 frequency; | ||
28 | struct tea5767_ctrl ctrl; | ||
29 | }; | ||
30 | |||
31 | /*****************************************************************************/ | ||
32 | |||
33 | /****************************** | ||
34 | * Write mode register values * | ||
35 | ******************************/ | ||
36 | |||
37 | /* First register */ | ||
38 | #define TEA5767_MUTE 0x80 /* Mutes output */ | ||
39 | #define TEA5767_SEARCH 0x40 /* Activates station search */ | ||
40 | /* Bits 0-5 for divider MSB */ | ||
41 | |||
42 | /* Second register */ | ||
43 | /* Bits 0-7 for divider LSB */ | ||
44 | |||
45 | /* Third register */ | ||
46 | |||
47 | /* Station search from botton to up */ | ||
48 | #define TEA5767_SEARCH_UP 0x80 | ||
49 | |||
50 | /* Searches with ADC output = 10 */ | ||
51 | #define TEA5767_SRCH_HIGH_LVL 0x60 | ||
52 | |||
53 | /* Searches with ADC output = 10 */ | ||
54 | #define TEA5767_SRCH_MID_LVL 0x40 | ||
55 | |||
56 | /* Searches with ADC output = 5 */ | ||
57 | #define TEA5767_SRCH_LOW_LVL 0x20 | ||
58 | |||
59 | /* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */ | ||
60 | #define TEA5767_HIGH_LO_INJECT 0x10 | ||
61 | |||
62 | /* Disable stereo */ | ||
63 | #define TEA5767_MONO 0x08 | ||
64 | |||
65 | /* Disable right channel and turns to mono */ | ||
66 | #define TEA5767_MUTE_RIGHT 0x04 | ||
67 | |||
68 | /* Disable left channel and turns to mono */ | ||
69 | #define TEA5767_MUTE_LEFT 0x02 | ||
70 | |||
71 | #define TEA5767_PORT1_HIGH 0x01 | ||
72 | |||
73 | /* Fourth register */ | ||
74 | #define TEA5767_PORT2_HIGH 0x80 | ||
75 | /* Chips stops working. Only I2C bus remains on */ | ||
76 | #define TEA5767_STDBY 0x40 | ||
77 | |||
78 | /* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */ | ||
79 | #define TEA5767_JAPAN_BAND 0x20 | ||
80 | |||
81 | /* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */ | ||
82 | #define TEA5767_XTAL_32768 0x10 | ||
83 | |||
84 | /* Cuts weak signals */ | ||
85 | #define TEA5767_SOFT_MUTE 0x08 | ||
86 | |||
87 | /* Activates high cut control */ | ||
88 | #define TEA5767_HIGH_CUT_CTRL 0x04 | ||
89 | |||
90 | /* Activates stereo noise control */ | ||
91 | #define TEA5767_ST_NOISE_CTL 0x02 | ||
92 | |||
93 | /* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ | ||
94 | #define TEA5767_SRCH_IND 0x01 | ||
95 | |||
96 | /* Fifth register */ | ||
97 | |||
98 | /* By activating, it will use Xtal at 13 MHz as reference for divider */ | ||
99 | #define TEA5767_PLLREF_ENABLE 0x80 | ||
100 | |||
101 | /* By activating, deemphasis=50, or else, deemphasis of 50us */ | ||
102 | #define TEA5767_DEEMPH_75 0X40 | ||
103 | |||
104 | /***************************** | ||
105 | * Read mode register values * | ||
106 | *****************************/ | ||
107 | |||
108 | /* First register */ | ||
109 | #define TEA5767_READY_FLAG_MASK 0x80 | ||
110 | #define TEA5767_BAND_LIMIT_MASK 0X40 | ||
111 | /* Bits 0-5 for divider MSB after search or preset */ | ||
112 | |||
113 | /* Second register */ | ||
114 | /* Bits 0-7 for divider LSB after search or preset */ | ||
115 | |||
116 | /* Third register */ | ||
117 | #define TEA5767_STEREO_MASK 0x80 | ||
118 | #define TEA5767_IF_CNTR_MASK 0x7f | ||
119 | |||
120 | /* Fourth register */ | ||
121 | #define TEA5767_ADC_LEVEL_MASK 0xf0 | ||
122 | |||
123 | /* should be 0 */ | ||
124 | #define TEA5767_CHIP_ID_MASK 0x0f | ||
125 | |||
126 | /* Fifth register */ | ||
127 | /* Reserved for future extensions */ | ||
128 | #define TEA5767_RESERVED_MASK 0xff | ||
129 | |||
130 | /*****************************************************************************/ | ||
131 | |||
132 | static void tea5767_status_dump(struct tea5767_priv *priv, | ||
133 | unsigned char *buffer) | ||
134 | { | ||
135 | unsigned int div, frq; | ||
136 | |||
137 | if (TEA5767_READY_FLAG_MASK & buffer[0]) | ||
138 | tuner_info("Ready Flag ON\n"); | ||
139 | else | ||
140 | tuner_info("Ready Flag OFF\n"); | ||
141 | |||
142 | if (TEA5767_BAND_LIMIT_MASK & buffer[0]) | ||
143 | tuner_info("Tuner at band limit\n"); | ||
144 | else | ||
145 | tuner_info("Tuner not at band limit\n"); | ||
146 | |||
147 | div = ((buffer[0] & 0x3f) << 8) | buffer[1]; | ||
148 | |||
149 | switch (priv->ctrl.xtal_freq) { | ||
150 | case TEA5767_HIGH_LO_13MHz: | ||
151 | frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */ | ||
152 | break; | ||
153 | case TEA5767_LOW_LO_13MHz: | ||
154 | frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */ | ||
155 | break; | ||
156 | case TEA5767_LOW_LO_32768: | ||
157 | frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */ | ||
158 | break; | ||
159 | case TEA5767_HIGH_LO_32768: | ||
160 | default: | ||
161 | frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */ | ||
162 | break; | ||
163 | } | ||
164 | buffer[0] = (div >> 8) & 0x3f; | ||
165 | buffer[1] = div & 0xff; | ||
166 | |||
167 | tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n", | ||
168 | frq / 1000, frq % 1000, div); | ||
169 | |||
170 | if (TEA5767_STEREO_MASK & buffer[2]) | ||
171 | tuner_info("Stereo\n"); | ||
172 | else | ||
173 | tuner_info("Mono\n"); | ||
174 | |||
175 | tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); | ||
176 | |||
177 | tuner_info("ADC Level = %d\n", | ||
178 | (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); | ||
179 | |||
180 | tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); | ||
181 | |||
182 | tuner_info("Reserved = 0x%02x\n", | ||
183 | (buffer[4] & TEA5767_RESERVED_MASK)); | ||
184 | } | ||
185 | |||
186 | /* Freq should be specifyed at 62.5 Hz */ | ||
187 | static int set_radio_freq(struct dvb_frontend *fe, | ||
188 | struct analog_parameters *params) | ||
189 | { | ||
190 | struct tea5767_priv *priv = fe->tuner_priv; | ||
191 | unsigned int frq = params->frequency; | ||
192 | unsigned char buffer[5]; | ||
193 | unsigned div; | ||
194 | int rc; | ||
195 | |||
196 | tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000); | ||
197 | |||
198 | buffer[2] = 0; | ||
199 | |||
200 | if (priv->ctrl.port1) | ||
201 | buffer[2] |= TEA5767_PORT1_HIGH; | ||
202 | |||
203 | if (params->audmode == V4L2_TUNER_MODE_MONO) { | ||
204 | tuner_dbg("TEA5767 set to mono\n"); | ||
205 | buffer[2] |= TEA5767_MONO; | ||
206 | } else { | ||
207 | tuner_dbg("TEA5767 set to stereo\n"); | ||
208 | } | ||
209 | |||
210 | |||
211 | buffer[3] = 0; | ||
212 | |||
213 | if (priv->ctrl.port2) | ||
214 | buffer[3] |= TEA5767_PORT2_HIGH; | ||
215 | |||
216 | if (priv->ctrl.high_cut) | ||
217 | buffer[3] |= TEA5767_HIGH_CUT_CTRL; | ||
218 | |||
219 | if (priv->ctrl.st_noise) | ||
220 | buffer[3] |= TEA5767_ST_NOISE_CTL; | ||
221 | |||
222 | if (priv->ctrl.soft_mute) | ||
223 | buffer[3] |= TEA5767_SOFT_MUTE; | ||
224 | |||
225 | if (priv->ctrl.japan_band) | ||
226 | buffer[3] |= TEA5767_JAPAN_BAND; | ||
227 | |||
228 | buffer[4] = 0; | ||
229 | |||
230 | if (priv->ctrl.deemph_75) | ||
231 | buffer[4] |= TEA5767_DEEMPH_75; | ||
232 | |||
233 | if (priv->ctrl.pllref) | ||
234 | buffer[4] |= TEA5767_PLLREF_ENABLE; | ||
235 | |||
236 | |||
237 | /* Rounds freq to next decimal value - for 62.5 KHz step */ | ||
238 | /* frq = 20*(frq/16)+radio_frq[frq%16]; */ | ||
239 | |||
240 | switch (priv->ctrl.xtal_freq) { | ||
241 | case TEA5767_HIGH_LO_13MHz: | ||
242 | tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n"); | ||
243 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | ||
244 | div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000; | ||
245 | break; | ||
246 | case TEA5767_LOW_LO_13MHz: | ||
247 | tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n"); | ||
248 | |||
249 | div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000; | ||
250 | break; | ||
251 | case TEA5767_LOW_LO_32768: | ||
252 | tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n"); | ||
253 | buffer[3] |= TEA5767_XTAL_32768; | ||
254 | /* const 700=4000*175 Khz - to adjust freq to right value */ | ||
255 | div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15; | ||
256 | break; | ||
257 | case TEA5767_HIGH_LO_32768: | ||
258 | default: | ||
259 | tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n"); | ||
260 | |||
261 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | ||
262 | buffer[3] |= TEA5767_XTAL_32768; | ||
263 | div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15; | ||
264 | break; | ||
265 | } | ||
266 | buffer[0] = (div >> 8) & 0x3f; | ||
267 | buffer[1] = div & 0xff; | ||
268 | |||
269 | if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5))) | ||
270 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
271 | |||
272 | if (debug) { | ||
273 | if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) | ||
274 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
275 | else | ||
276 | tea5767_status_dump(priv, buffer); | ||
277 | } | ||
278 | |||
279 | priv->frequency = frq * 125 / 2; | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int tea5767_read_status(struct dvb_frontend *fe, char *buffer) | ||
285 | { | ||
286 | struct tea5767_priv *priv = fe->tuner_priv; | ||
287 | int rc; | ||
288 | |||
289 | memset(buffer, 0, 5); | ||
290 | if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) { | ||
291 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
292 | return -EREMOTEIO; | ||
293 | } | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer) | ||
299 | { | ||
300 | struct tea5767_priv *priv = fe->tuner_priv; | ||
301 | |||
302 | int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8); | ||
303 | |||
304 | tuner_dbg("Signal strength: %d\n", signal); | ||
305 | |||
306 | return signal; | ||
307 | } | ||
308 | |||
309 | static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer) | ||
310 | { | ||
311 | struct tea5767_priv *priv = fe->tuner_priv; | ||
312 | |||
313 | int stereo = buffer[2] & TEA5767_STEREO_MASK; | ||
314 | |||
315 | tuner_dbg("Radio ST GET = %02x\n", stereo); | ||
316 | |||
317 | return (stereo ? V4L2_TUNER_SUB_STEREO : 0); | ||
318 | } | ||
319 | |||
320 | static int tea5767_get_status(struct dvb_frontend *fe, u32 *status) | ||
321 | { | ||
322 | unsigned char buffer[5]; | ||
323 | |||
324 | *status = 0; | ||
325 | |||
326 | if (0 == tea5767_read_status(fe, buffer)) { | ||
327 | if (tea5767_signal(fe, buffer)) | ||
328 | *status = TUNER_STATUS_LOCKED; | ||
329 | if (tea5767_stereo(fe, buffer)) | ||
330 | *status |= TUNER_STATUS_STEREO; | ||
331 | } | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | ||
337 | { | ||
338 | unsigned char buffer[5]; | ||
339 | |||
340 | *strength = 0; | ||
341 | |||
342 | if (0 == tea5767_read_status(fe, buffer)) | ||
343 | *strength = tea5767_signal(fe, buffer); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int tea5767_standby(struct dvb_frontend *fe) | ||
349 | { | ||
350 | unsigned char buffer[5]; | ||
351 | struct tea5767_priv *priv = fe->tuner_priv; | ||
352 | unsigned div, rc; | ||
353 | |||
354 | div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */ | ||
355 | buffer[0] = (div >> 8) & 0x3f; | ||
356 | buffer[1] = div & 0xff; | ||
357 | buffer[2] = TEA5767_PORT1_HIGH; | ||
358 | buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | | ||
359 | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY; | ||
360 | buffer[4] = 0; | ||
361 | |||
362 | if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5))) | ||
363 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) | ||
369 | { | ||
370 | struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr }; | ||
371 | unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
372 | int rc; | ||
373 | |||
374 | if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) { | ||
375 | printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc); | ||
376 | return EINVAL; | ||
377 | } | ||
378 | |||
379 | /* If all bytes are the same then it's a TV tuner and not a tea5767 */ | ||
380 | if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && | ||
381 | buffer[0] == buffer[3] && buffer[0] == buffer[4]) { | ||
382 | printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n"); | ||
383 | return EINVAL; | ||
384 | } | ||
385 | |||
386 | /* Status bytes: | ||
387 | * Byte 4: bit 3:1 : CI (Chip Identification) == 0 | ||
388 | * bit 0 : internally set to 0 | ||
389 | * Byte 5: bit 7:0 : == 0 | ||
390 | */ | ||
391 | if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) { | ||
392 | printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n"); | ||
393 | return EINVAL; | ||
394 | } | ||
395 | |||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int tea5767_release(struct dvb_frontend *fe) | ||
401 | { | ||
402 | kfree(fe->tuner_priv); | ||
403 | fe->tuner_priv = NULL; | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
409 | { | ||
410 | struct tea5767_priv *priv = fe->tuner_priv; | ||
411 | *frequency = priv->frequency; | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg) | ||
417 | { | ||
418 | struct tea5767_priv *priv = fe->tuner_priv; | ||
419 | |||
420 | memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl)); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static struct dvb_tuner_ops tea5767_tuner_ops = { | ||
426 | .info = { | ||
427 | .name = "tea5767", // Philips TEA5767HN FM Radio | ||
428 | }, | ||
429 | |||
430 | .set_analog_params = set_radio_freq, | ||
431 | .set_config = tea5767_set_config, | ||
432 | .sleep = tea5767_standby, | ||
433 | .release = tea5767_release, | ||
434 | .get_frequency = tea5767_get_frequency, | ||
435 | .get_status = tea5767_get_status, | ||
436 | .get_rf_strength = tea5767_get_rf_strength, | ||
437 | }; | ||
438 | |||
439 | struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, | ||
440 | struct i2c_adapter* i2c_adap, | ||
441 | u8 i2c_addr) | ||
442 | { | ||
443 | struct tea5767_priv *priv = NULL; | ||
444 | |||
445 | priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL); | ||
446 | if (priv == NULL) | ||
447 | return NULL; | ||
448 | fe->tuner_priv = priv; | ||
449 | |||
450 | priv->i2c_props.addr = i2c_addr; | ||
451 | priv->i2c_props.adap = i2c_adap; | ||
452 | priv->i2c_props.name = "tea5767"; | ||
453 | |||
454 | priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768; | ||
455 | priv->ctrl.port1 = 1; | ||
456 | priv->ctrl.port2 = 1; | ||
457 | priv->ctrl.high_cut = 1; | ||
458 | priv->ctrl.st_noise = 1; | ||
459 | priv->ctrl.japan_band = 1; | ||
460 | |||
461 | memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops, | ||
462 | sizeof(struct dvb_tuner_ops)); | ||
463 | |||
464 | tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio"); | ||
465 | |||
466 | return fe; | ||
467 | } | ||
468 | |||
469 | EXPORT_SYMBOL_GPL(tea5767_attach); | ||
470 | EXPORT_SYMBOL_GPL(tea5767_autodetection); | ||
471 | |||
472 | MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver"); | ||
473 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | ||
474 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tea5767.h b/drivers/media/video/tea5767.h deleted file mode 100644 index 7b547c092e25..000000000000 --- a/drivers/media/video/tea5767.h +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or modify | ||
3 | it under the terms of the GNU General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or | ||
5 | (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU General Public License | ||
13 | along with this program; if not, write to the Free Software | ||
14 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TEA5767_H__ | ||
18 | #define __TEA5767_H__ | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | enum tea5767_xtal { | ||
24 | TEA5767_LOW_LO_32768 = 0, | ||
25 | TEA5767_HIGH_LO_32768 = 1, | ||
26 | TEA5767_LOW_LO_13MHz = 2, | ||
27 | TEA5767_HIGH_LO_13MHz = 3, | ||
28 | }; | ||
29 | |||
30 | struct tea5767_ctrl { | ||
31 | unsigned int port1:1; | ||
32 | unsigned int port2:1; | ||
33 | unsigned int high_cut:1; | ||
34 | unsigned int st_noise:1; | ||
35 | unsigned int soft_mute:1; | ||
36 | unsigned int japan_band:1; | ||
37 | unsigned int deemph_75:1; | ||
38 | unsigned int pllref:1; | ||
39 | enum tea5767_xtal xtal_freq; | ||
40 | }; | ||
41 | |||
42 | #if defined(CONFIG_TUNER_TEA5767) || (defined(CONFIG_TUNER_TEA5767_MODULE) && defined(MODULE)) | ||
43 | extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); | ||
44 | |||
45 | extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, | ||
46 | struct i2c_adapter* i2c_adap, | ||
47 | u8 i2c_addr); | ||
48 | #else | ||
49 | static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap, | ||
50 | u8 i2c_addr) | ||
51 | { | ||
52 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | ||
53 | __func__); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | |||
57 | static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, | ||
58 | struct i2c_adapter* i2c_adap, | ||
59 | u8 i2c_addr) | ||
60 | { | ||
61 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
62 | return NULL; | ||
63 | } | ||
64 | #endif | ||
65 | |||
66 | #endif /* __TEA5767_H__ */ | ||
diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/video/tuner-i2c.h deleted file mode 100644 index 3ad6c8e0b04c..000000000000 --- a/drivers/media/video/tuner-i2c.h +++ /dev/null | |||
@@ -1,173 +0,0 @@ | |||
1 | /* | ||
2 | tuner-i2c.h - i2c interface for different tuners | ||
3 | |||
4 | Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __TUNER_I2C_H__ | ||
22 | #define __TUNER_I2C_H__ | ||
23 | |||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | struct tuner_i2c_props { | ||
27 | u8 addr; | ||
28 | struct i2c_adapter *adap; | ||
29 | |||
30 | /* used for tuner instance management */ | ||
31 | int count; | ||
32 | char *name; | ||
33 | }; | ||
34 | |||
35 | static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len) | ||
36 | { | ||
37 | struct i2c_msg msg = { .addr = props->addr, .flags = 0, | ||
38 | .buf = buf, .len = len }; | ||
39 | int ret = i2c_transfer(props->adap, &msg, 1); | ||
40 | |||
41 | return (ret == 1) ? len : ret; | ||
42 | } | ||
43 | |||
44 | static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len) | ||
45 | { | ||
46 | struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD, | ||
47 | .buf = buf, .len = len }; | ||
48 | int ret = i2c_transfer(props->adap, &msg, 1); | ||
49 | |||
50 | return (ret == 1) ? len : ret; | ||
51 | } | ||
52 | |||
53 | static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, | ||
54 | char *obuf, int olen, | ||
55 | char *ibuf, int ilen) | ||
56 | { | ||
57 | struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0, | ||
58 | .buf = obuf, .len = olen }, | ||
59 | { .addr = props->addr, .flags = I2C_M_RD, | ||
60 | .buf = ibuf, .len = ilen } }; | ||
61 | int ret = i2c_transfer(props->adap, msg, 2); | ||
62 | |||
63 | return (ret == 2) ? ilen : ret; | ||
64 | } | ||
65 | |||
66 | /* Callers must declare as a global for the module: | ||
67 | * | ||
68 | * static LIST_HEAD(hybrid_tuner_instance_list); | ||
69 | * | ||
70 | * hybrid_tuner_instance_list should be the third argument | ||
71 | * passed into hybrid_tuner_request_state(). | ||
72 | * | ||
73 | * state structure must contain the following: | ||
74 | * | ||
75 | * struct list_head hybrid_tuner_instance_list; | ||
76 | * struct tuner_i2c_props i2c_props; | ||
77 | * | ||
78 | * hybrid_tuner_instance_list (both within state structure and globally) | ||
79 | * is only required if the driver is using hybrid_tuner_request_state | ||
80 | * and hybrid_tuner_release_state to manage state sharing between | ||
81 | * multiple instances of hybrid tuners. | ||
82 | */ | ||
83 | |||
84 | #define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \ | ||
85 | printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \ | ||
86 | i2cprops.adap ? \ | ||
87 | i2c_adapter_id(i2cprops.adap) : -1, \ | ||
88 | i2cprops.addr, ##arg); \ | ||
89 | } while (0) | ||
90 | |||
91 | /* TO DO: convert all callers of these macros to pass in | ||
92 | * struct tuner_i2c_props, then remove the macro wrappers */ | ||
93 | |||
94 | #define __tuner_warn(i2cprops, fmt, arg...) do { \ | ||
95 | tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \ | ||
96 | } while (0) | ||
97 | |||
98 | #define __tuner_info(i2cprops, fmt, arg...) do { \ | ||
99 | tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \ | ||
100 | } while (0) | ||
101 | |||
102 | #define __tuner_err(i2cprops, fmt, arg...) do { \ | ||
103 | tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \ | ||
104 | } while (0) | ||
105 | |||
106 | #define __tuner_dbg(i2cprops, fmt, arg...) do { \ | ||
107 | if ((debug)) \ | ||
108 | tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \ | ||
109 | } while (0) | ||
110 | |||
111 | #define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg) | ||
112 | #define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg) | ||
113 | #define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg) | ||
114 | #define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg) | ||
115 | |||
116 | /****************************************************************************/ | ||
117 | |||
118 | /* The return value of hybrid_tuner_request_state indicates the number of | ||
119 | * instances using this tuner object. | ||
120 | * | ||
121 | * 0 - no instances, indicates an error - kzalloc must have failed | ||
122 | * | ||
123 | * 1 - one instance, indicates that the tuner object was created successfully | ||
124 | * | ||
125 | * 2 (or more) instances, indicates that an existing tuner object was found | ||
126 | */ | ||
127 | |||
128 | #define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\ | ||
129 | ({ \ | ||
130 | int __ret = 0; \ | ||
131 | list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \ | ||
132 | if (((i2cadap) && (state->i2c_props.adap)) && \ | ||
133 | ((i2c_adapter_id(state->i2c_props.adap) == \ | ||
134 | i2c_adapter_id(i2cadap)) && \ | ||
135 | (i2caddr == state->i2c_props.addr))) { \ | ||
136 | __tuner_info(state->i2c_props, \ | ||
137 | "attaching existing instance\n"); \ | ||
138 | state->i2c_props.count++; \ | ||
139 | __ret = state->i2c_props.count; \ | ||
140 | break; \ | ||
141 | } \ | ||
142 | } \ | ||
143 | if (0 == __ret) { \ | ||
144 | state = kzalloc(sizeof(type), GFP_KERNEL); \ | ||
145 | if (NULL == state) \ | ||
146 | goto __fail; \ | ||
147 | state->i2c_props.addr = i2caddr; \ | ||
148 | state->i2c_props.adap = i2cadap; \ | ||
149 | state->i2c_props.name = devname; \ | ||
150 | __tuner_info(state->i2c_props, \ | ||
151 | "creating new instance\n"); \ | ||
152 | list_add_tail(&state->hybrid_tuner_instance_list, &list);\ | ||
153 | state->i2c_props.count++; \ | ||
154 | __ret = state->i2c_props.count; \ | ||
155 | } \ | ||
156 | __fail: \ | ||
157 | __ret; \ | ||
158 | }) | ||
159 | |||
160 | #define hybrid_tuner_release_state(state) \ | ||
161 | ({ \ | ||
162 | int __ret; \ | ||
163 | state->i2c_props.count--; \ | ||
164 | __ret = state->i2c_props.count; \ | ||
165 | if (!state->i2c_props.count) { \ | ||
166 | __tuner_info(state->i2c_props, "destroying instance\n");\ | ||
167 | list_del(&state->hybrid_tuner_instance_list); \ | ||
168 | kfree(state); \ | ||
169 | } \ | ||
170 | __ret; \ | ||
171 | }) | ||
172 | |||
173 | #endif /* __TUNER_I2C_H__ */ | ||
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c deleted file mode 100644 index be8d903171b7..000000000000 --- a/drivers/media/video/tuner-simple.c +++ /dev/null | |||
@@ -1,1093 +0,0 @@ | |||
1 | /* | ||
2 | * i2c tv tuner chip device driver | ||
3 | * controls all those simple 4-control-bytes style tuners. | ||
4 | * | ||
5 | * This "tuner-simple" module was split apart from the original "tuner" module. | ||
6 | */ | ||
7 | #include <linux/delay.h> | ||
8 | #include <linux/i2c.h> | ||
9 | #include <linux/videodev.h> | ||
10 | #include <media/tuner.h> | ||
11 | #include <media/v4l2-common.h> | ||
12 | #include <media/tuner-types.h> | ||
13 | #include "tuner-i2c.h" | ||
14 | #include "tuner-simple.h" | ||
15 | |||
16 | static int debug; | ||
17 | module_param(debug, int, 0644); | ||
18 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
19 | |||
20 | #define TUNER_SIMPLE_MAX 64 | ||
21 | static unsigned int simple_devcount; | ||
22 | |||
23 | static int offset; | ||
24 | module_param(offset, int, 0664); | ||
25 | MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner"); | ||
26 | |||
27 | static unsigned int atv_input[TUNER_SIMPLE_MAX] = \ | ||
28 | { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 }; | ||
29 | static unsigned int dtv_input[TUNER_SIMPLE_MAX] = \ | ||
30 | { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 }; | ||
31 | module_param_array(atv_input, int, NULL, 0644); | ||
32 | module_param_array(dtv_input, int, NULL, 0644); | ||
33 | MODULE_PARM_DESC(atv_input, "specify atv rf input, 0 for autoselect"); | ||
34 | MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect"); | ||
35 | |||
36 | /* ---------------------------------------------------------------------- */ | ||
37 | |||
38 | /* tv standard selection for Temic 4046 FM5 | ||
39 | this value takes the low bits of control byte 2 | ||
40 | from datasheet Rev.01, Feb.00 | ||
41 | standard BG I L L2 D | ||
42 | picture IF 38.9 38.9 38.9 33.95 38.9 | ||
43 | sound 1 33.4 32.9 32.4 40.45 32.4 | ||
44 | sound 2 33.16 | ||
45 | NICAM 33.05 32.348 33.05 33.05 | ||
46 | */ | ||
47 | #define TEMIC_SET_PAL_I 0x05 | ||
48 | #define TEMIC_SET_PAL_DK 0x09 | ||
49 | #define TEMIC_SET_PAL_L 0x0a /* SECAM ? */ | ||
50 | #define TEMIC_SET_PAL_L2 0x0b /* change IF ! */ | ||
51 | #define TEMIC_SET_PAL_BG 0x0c | ||
52 | |||
53 | /* tv tuner system standard selection for Philips FQ1216ME | ||
54 | this value takes the low bits of control byte 2 | ||
55 | from datasheet "1999 Nov 16" (supersedes "1999 Mar 23") | ||
56 | standard BG DK I L L` | ||
57 | picture carrier 38.90 38.90 38.90 38.90 33.95 | ||
58 | colour 34.47 34.47 34.47 34.47 38.38 | ||
59 | sound 1 33.40 32.40 32.90 32.40 40.45 | ||
60 | sound 2 33.16 - - - - | ||
61 | NICAM 33.05 33.05 32.35 33.05 39.80 | ||
62 | */ | ||
63 | #define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/ | ||
64 | #define PHILIPS_SET_PAL_BGDK 0x09 | ||
65 | #define PHILIPS_SET_PAL_L2 0x0a | ||
66 | #define PHILIPS_SET_PAL_L 0x0b | ||
67 | |||
68 | /* system switching for Philips FI1216MF MK2 | ||
69 | from datasheet "1996 Jul 09", | ||
70 | standard BG L L' | ||
71 | picture carrier 38.90 38.90 33.95 | ||
72 | colour 34.47 34.37 38.38 | ||
73 | sound 1 33.40 32.40 40.45 | ||
74 | sound 2 33.16 - - | ||
75 | NICAM 33.05 33.05 39.80 | ||
76 | */ | ||
77 | #define PHILIPS_MF_SET_STD_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */ | ||
78 | #define PHILIPS_MF_SET_STD_L 0x03 /* Used on Secam France */ | ||
79 | #define PHILIPS_MF_SET_STD_LC 0x02 /* Used on SECAM L' */ | ||
80 | |||
81 | /* Control byte */ | ||
82 | |||
83 | #define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */ | ||
84 | #define TUNER_RATIO_SELECT_50 0x00 | ||
85 | #define TUNER_RATIO_SELECT_32 0x02 | ||
86 | #define TUNER_RATIO_SELECT_166 0x04 | ||
87 | #define TUNER_RATIO_SELECT_62 0x06 | ||
88 | |||
89 | #define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */ | ||
90 | |||
91 | /* Status byte */ | ||
92 | |||
93 | #define TUNER_POR 0x80 | ||
94 | #define TUNER_FL 0x40 | ||
95 | #define TUNER_MODE 0x38 | ||
96 | #define TUNER_AFC 0x07 | ||
97 | #define TUNER_SIGNAL 0x07 | ||
98 | #define TUNER_STEREO 0x10 | ||
99 | |||
100 | #define TUNER_PLL_LOCKED 0x40 | ||
101 | #define TUNER_STEREO_MK3 0x04 | ||
102 | |||
103 | static DEFINE_MUTEX(tuner_simple_list_mutex); | ||
104 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
105 | |||
106 | struct tuner_simple_priv { | ||
107 | unsigned int nr; | ||
108 | u16 last_div; | ||
109 | |||
110 | struct tuner_i2c_props i2c_props; | ||
111 | struct list_head hybrid_tuner_instance_list; | ||
112 | |||
113 | unsigned int type; | ||
114 | struct tunertype *tun; | ||
115 | |||
116 | u32 frequency; | ||
117 | u32 bandwidth; | ||
118 | }; | ||
119 | |||
120 | /* ---------------------------------------------------------------------- */ | ||
121 | |||
122 | static int tuner_read_status(struct dvb_frontend *fe) | ||
123 | { | ||
124 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
125 | unsigned char byte; | ||
126 | |||
127 | if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1)) | ||
128 | return 0; | ||
129 | |||
130 | return byte; | ||
131 | } | ||
132 | |||
133 | static inline int tuner_signal(const int status) | ||
134 | { | ||
135 | return (status & TUNER_SIGNAL) << 13; | ||
136 | } | ||
137 | |||
138 | static inline int tuner_stereo(const int type, const int status) | ||
139 | { | ||
140 | switch (type) { | ||
141 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
142 | case TUNER_PHILIPS_FM1236_MK3: | ||
143 | case TUNER_PHILIPS_FM1256_IH3: | ||
144 | case TUNER_LG_NTSC_TAPE: | ||
145 | return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); | ||
146 | default: | ||
147 | return status & TUNER_STEREO; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static inline int tuner_islocked(const int status) | ||
152 | { | ||
153 | return (status & TUNER_FL); | ||
154 | } | ||
155 | |||
156 | static inline int tuner_afcstatus(const int status) | ||
157 | { | ||
158 | return (status & TUNER_AFC) - 2; | ||
159 | } | ||
160 | |||
161 | |||
162 | static int simple_get_status(struct dvb_frontend *fe, u32 *status) | ||
163 | { | ||
164 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
165 | int tuner_status; | ||
166 | |||
167 | if (priv->i2c_props.adap == NULL) | ||
168 | return -EINVAL; | ||
169 | |||
170 | tuner_status = tuner_read_status(fe); | ||
171 | |||
172 | *status = 0; | ||
173 | |||
174 | if (tuner_islocked(tuner_status)) | ||
175 | *status = TUNER_STATUS_LOCKED; | ||
176 | if (tuner_stereo(priv->type, tuner_status)) | ||
177 | *status |= TUNER_STATUS_STEREO; | ||
178 | |||
179 | tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status)); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | ||
185 | { | ||
186 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
187 | int signal; | ||
188 | |||
189 | if (priv->i2c_props.adap == NULL) | ||
190 | return -EINVAL; | ||
191 | |||
192 | signal = tuner_signal(tuner_read_status(fe)); | ||
193 | |||
194 | *strength = signal; | ||
195 | |||
196 | tuner_dbg("Signal strength: %d\n", signal); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* ---------------------------------------------------------------------- */ | ||
202 | |||
203 | static inline char *tuner_param_name(enum param_type type) | ||
204 | { | ||
205 | char *name; | ||
206 | |||
207 | switch (type) { | ||
208 | case TUNER_PARAM_TYPE_RADIO: | ||
209 | name = "radio"; | ||
210 | break; | ||
211 | case TUNER_PARAM_TYPE_PAL: | ||
212 | name = "pal"; | ||
213 | break; | ||
214 | case TUNER_PARAM_TYPE_SECAM: | ||
215 | name = "secam"; | ||
216 | break; | ||
217 | case TUNER_PARAM_TYPE_NTSC: | ||
218 | name = "ntsc"; | ||
219 | break; | ||
220 | case TUNER_PARAM_TYPE_DIGITAL: | ||
221 | name = "digital"; | ||
222 | break; | ||
223 | default: | ||
224 | name = "unknown"; | ||
225 | break; | ||
226 | } | ||
227 | return name; | ||
228 | } | ||
229 | |||
230 | static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe, | ||
231 | enum param_type desired_type) | ||
232 | { | ||
233 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
234 | struct tunertype *tun = priv->tun; | ||
235 | int i; | ||
236 | |||
237 | for (i = 0; i < tun->count; i++) | ||
238 | if (desired_type == tun->params[i].type) | ||
239 | break; | ||
240 | |||
241 | /* use default tuner params if desired_type not available */ | ||
242 | if (i == tun->count) { | ||
243 | tuner_dbg("desired params (%s) undefined for tuner %d\n", | ||
244 | tuner_param_name(desired_type), priv->type); | ||
245 | i = 0; | ||
246 | } | ||
247 | |||
248 | tuner_dbg("using tuner params #%d (%s)\n", i, | ||
249 | tuner_param_name(tun->params[i].type)); | ||
250 | |||
251 | return &tun->params[i]; | ||
252 | } | ||
253 | |||
254 | static int simple_config_lookup(struct dvb_frontend *fe, | ||
255 | struct tuner_params *t_params, | ||
256 | int *frequency, u8 *config, u8 *cb) | ||
257 | { | ||
258 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
259 | int i; | ||
260 | |||
261 | for (i = 0; i < t_params->count; i++) { | ||
262 | if (*frequency > t_params->ranges[i].limit) | ||
263 | continue; | ||
264 | break; | ||
265 | } | ||
266 | if (i == t_params->count) { | ||
267 | tuner_dbg("frequency out of range (%d > %d)\n", | ||
268 | *frequency, t_params->ranges[i - 1].limit); | ||
269 | *frequency = t_params->ranges[--i].limit; | ||
270 | } | ||
271 | *config = t_params->ranges[i].config; | ||
272 | *cb = t_params->ranges[i].cb; | ||
273 | |||
274 | tuner_dbg("freq = %d.%02d (%d), range = %d, " | ||
275 | "config = 0x%02x, cb = 0x%02x\n", | ||
276 | *frequency / 16, *frequency % 16 * 100 / 16, *frequency, | ||
277 | i, *config, *cb); | ||
278 | |||
279 | return i; | ||
280 | } | ||
281 | |||
282 | /* ---------------------------------------------------------------------- */ | ||
283 | |||
284 | static void simple_set_rf_input(struct dvb_frontend *fe, | ||
285 | u8 *config, u8 *cb, unsigned int rf) | ||
286 | { | ||
287 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
288 | |||
289 | switch (priv->type) { | ||
290 | case TUNER_PHILIPS_TUV1236D: | ||
291 | switch (rf) { | ||
292 | case 1: | ||
293 | *cb |= 0x08; | ||
294 | break; | ||
295 | default: | ||
296 | *cb &= ~0x08; | ||
297 | break; | ||
298 | } | ||
299 | break; | ||
300 | case TUNER_PHILIPS_FCV1236D: | ||
301 | switch (rf) { | ||
302 | case 1: | ||
303 | *cb |= 0x01; | ||
304 | break; | ||
305 | default: | ||
306 | *cb &= ~0x01; | ||
307 | break; | ||
308 | } | ||
309 | break; | ||
310 | default: | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | static int simple_std_setup(struct dvb_frontend *fe, | ||
316 | struct analog_parameters *params, | ||
317 | u8 *config, u8 *cb) | ||
318 | { | ||
319 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
320 | u8 tuneraddr; | ||
321 | int rc; | ||
322 | |||
323 | /* tv norm specific stuff for multi-norm tuners */ | ||
324 | switch (priv->type) { | ||
325 | case TUNER_PHILIPS_SECAM: /* FI1216MF */ | ||
326 | /* 0x01 -> ??? no change ??? */ | ||
327 | /* 0x02 -> PAL BDGHI / SECAM L */ | ||
328 | /* 0x04 -> ??? PAL others / SECAM others ??? */ | ||
329 | *cb &= ~0x03; | ||
330 | if (params->std & V4L2_STD_SECAM_L) | ||
331 | /* also valid for V4L2_STD_SECAM */ | ||
332 | *cb |= PHILIPS_MF_SET_STD_L; | ||
333 | else if (params->std & V4L2_STD_SECAM_LC) | ||
334 | *cb |= PHILIPS_MF_SET_STD_LC; | ||
335 | else /* V4L2_STD_B|V4L2_STD_GH */ | ||
336 | *cb |= PHILIPS_MF_SET_STD_BG; | ||
337 | break; | ||
338 | |||
339 | case TUNER_TEMIC_4046FM5: | ||
340 | *cb &= ~0x0f; | ||
341 | |||
342 | if (params->std & V4L2_STD_PAL_BG) { | ||
343 | *cb |= TEMIC_SET_PAL_BG; | ||
344 | |||
345 | } else if (params->std & V4L2_STD_PAL_I) { | ||
346 | *cb |= TEMIC_SET_PAL_I; | ||
347 | |||
348 | } else if (params->std & V4L2_STD_PAL_DK) { | ||
349 | *cb |= TEMIC_SET_PAL_DK; | ||
350 | |||
351 | } else if (params->std & V4L2_STD_SECAM_L) { | ||
352 | *cb |= TEMIC_SET_PAL_L; | ||
353 | |||
354 | } | ||
355 | break; | ||
356 | |||
357 | case TUNER_PHILIPS_FQ1216ME: | ||
358 | *cb &= ~0x0f; | ||
359 | |||
360 | if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { | ||
361 | *cb |= PHILIPS_SET_PAL_BGDK; | ||
362 | |||
363 | } else if (params->std & V4L2_STD_PAL_I) { | ||
364 | *cb |= PHILIPS_SET_PAL_I; | ||
365 | |||
366 | } else if (params->std & V4L2_STD_SECAM_L) { | ||
367 | *cb |= PHILIPS_SET_PAL_L; | ||
368 | |||
369 | } | ||
370 | break; | ||
371 | |||
372 | case TUNER_PHILIPS_FCV1236D: | ||
373 | /* 0x00 -> ATSC antenna input 1 */ | ||
374 | /* 0x01 -> ATSC antenna input 2 */ | ||
375 | /* 0x02 -> NTSC antenna input 1 */ | ||
376 | /* 0x03 -> NTSC antenna input 2 */ | ||
377 | *cb &= ~0x03; | ||
378 | if (!(params->std & V4L2_STD_ATSC)) | ||
379 | *cb |= 2; | ||
380 | break; | ||
381 | |||
382 | case TUNER_MICROTUNE_4042FI5: | ||
383 | /* Set the charge pump for fast tuning */ | ||
384 | *config |= TUNER_CHARGE_PUMP; | ||
385 | break; | ||
386 | |||
387 | case TUNER_PHILIPS_TUV1236D: | ||
388 | { | ||
389 | /* 0x40 -> ATSC antenna input 1 */ | ||
390 | /* 0x48 -> ATSC antenna input 2 */ | ||
391 | /* 0x00 -> NTSC antenna input 1 */ | ||
392 | /* 0x08 -> NTSC antenna input 2 */ | ||
393 | u8 buffer[4] = { 0x14, 0x00, 0x17, 0x00}; | ||
394 | *cb &= ~0x40; | ||
395 | if (params->std & V4L2_STD_ATSC) { | ||
396 | *cb |= 0x40; | ||
397 | buffer[1] = 0x04; | ||
398 | } | ||
399 | /* set to the correct mode (analog or digital) */ | ||
400 | tuneraddr = priv->i2c_props.addr; | ||
401 | priv->i2c_props.addr = 0x0a; | ||
402 | rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2); | ||
403 | if (2 != rc) | ||
404 | tuner_warn("i2c i/o error: rc == %d " | ||
405 | "(should be 2)\n", rc); | ||
406 | rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2); | ||
407 | if (2 != rc) | ||
408 | tuner_warn("i2c i/o error: rc == %d " | ||
409 | "(should be 2)\n", rc); | ||
410 | priv->i2c_props.addr = tuneraddr; | ||
411 | break; | ||
412 | } | ||
413 | } | ||
414 | if (atv_input[priv->nr]) | ||
415 | simple_set_rf_input(fe, config, cb, atv_input[priv->nr]); | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, | ||
421 | u16 div, u8 config, u8 cb) | ||
422 | { | ||
423 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
424 | int rc; | ||
425 | |||
426 | switch (priv->type) { | ||
427 | case TUNER_LG_TDVS_H06XF: | ||
428 | /* Set the Auxiliary Byte. */ | ||
429 | buffer[0] = buffer[2]; | ||
430 | buffer[0] &= ~0x20; | ||
431 | buffer[0] |= 0x18; | ||
432 | buffer[1] = 0x20; | ||
433 | tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
434 | |||
435 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); | ||
436 | if (2 != rc) | ||
437 | tuner_warn("i2c i/o error: rc == %d " | ||
438 | "(should be 2)\n", rc); | ||
439 | break; | ||
440 | case TUNER_MICROTUNE_4042FI5: | ||
441 | { | ||
442 | /* FIXME - this may also work for other tuners */ | ||
443 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
444 | u8 status_byte = 0; | ||
445 | |||
446 | /* Wait until the PLL locks */ | ||
447 | for (;;) { | ||
448 | if (time_after(jiffies, timeout)) | ||
449 | return 0; | ||
450 | rc = tuner_i2c_xfer_recv(&priv->i2c_props, | ||
451 | &status_byte, 1); | ||
452 | if (1 != rc) { | ||
453 | tuner_warn("i2c i/o read error: rc == %d " | ||
454 | "(should be 1)\n", rc); | ||
455 | break; | ||
456 | } | ||
457 | if (status_byte & TUNER_PLL_LOCKED) | ||
458 | break; | ||
459 | udelay(10); | ||
460 | } | ||
461 | |||
462 | /* Set the charge pump for optimized phase noise figure */ | ||
463 | config &= ~TUNER_CHARGE_PUMP; | ||
464 | buffer[0] = (div>>8) & 0x7f; | ||
465 | buffer[1] = div & 0xff; | ||
466 | buffer[2] = config; | ||
467 | buffer[3] = cb; | ||
468 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
469 | buffer[0], buffer[1], buffer[2], buffer[3]); | ||
470 | |||
471 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); | ||
472 | if (4 != rc) | ||
473 | tuner_warn("i2c i/o error: rc == %d " | ||
474 | "(should be 4)\n", rc); | ||
475 | break; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) | ||
483 | { | ||
484 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
485 | |||
486 | switch (priv->type) { | ||
487 | case TUNER_TENA_9533_DI: | ||
488 | case TUNER_YMEC_TVF_5533MF: | ||
489 | tuner_dbg("This tuner doesn't have FM. " | ||
490 | "Most cards have a TEA5767 for FM\n"); | ||
491 | return 0; | ||
492 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
493 | case TUNER_PHILIPS_FM1236_MK3: | ||
494 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
495 | case TUNER_LG_NTSC_TAPE: | ||
496 | case TUNER_PHILIPS_FM1256_IH3: | ||
497 | buffer[3] = 0x19; | ||
498 | break; | ||
499 | case TUNER_TNF_5335MF: | ||
500 | buffer[3] = 0x11; | ||
501 | break; | ||
502 | case TUNER_LG_PAL_FM: | ||
503 | buffer[3] = 0xa5; | ||
504 | break; | ||
505 | case TUNER_THOMSON_DTT761X: | ||
506 | buffer[3] = 0x39; | ||
507 | break; | ||
508 | case TUNER_MICROTUNE_4049FM5: | ||
509 | default: | ||
510 | buffer[3] = 0xa4; | ||
511 | break; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | /* ---------------------------------------------------------------------- */ | ||
518 | |||
519 | static int simple_set_tv_freq(struct dvb_frontend *fe, | ||
520 | struct analog_parameters *params) | ||
521 | { | ||
522 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
523 | u8 config, cb; | ||
524 | u16 div; | ||
525 | struct tunertype *tun; | ||
526 | u8 buffer[4]; | ||
527 | int rc, IFPCoff, i; | ||
528 | enum param_type desired_type; | ||
529 | struct tuner_params *t_params; | ||
530 | |||
531 | tun = priv->tun; | ||
532 | |||
533 | /* IFPCoff = Video Intermediate Frequency - Vif: | ||
534 | 940 =16*58.75 NTSC/J (Japan) | ||
535 | 732 =16*45.75 M/N STD | ||
536 | 704 =16*44 ATSC (at DVB code) | ||
537 | 632 =16*39.50 I U.K. | ||
538 | 622.4=16*38.90 B/G D/K I, L STD | ||
539 | 592 =16*37.00 D China | ||
540 | 590 =16.36.875 B Australia | ||
541 | 543.2=16*33.95 L' STD | ||
542 | 171.2=16*10.70 FM Radio (at set_radio_freq) | ||
543 | */ | ||
544 | |||
545 | if (params->std == V4L2_STD_NTSC_M_JP) { | ||
546 | IFPCoff = 940; | ||
547 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
548 | } else if ((params->std & V4L2_STD_MN) && | ||
549 | !(params->std & ~V4L2_STD_MN)) { | ||
550 | IFPCoff = 732; | ||
551 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
552 | } else if (params->std == V4L2_STD_SECAM_LC) { | ||
553 | IFPCoff = 543; | ||
554 | desired_type = TUNER_PARAM_TYPE_SECAM; | ||
555 | } else { | ||
556 | IFPCoff = 623; | ||
557 | desired_type = TUNER_PARAM_TYPE_PAL; | ||
558 | } | ||
559 | |||
560 | t_params = simple_tuner_params(fe, desired_type); | ||
561 | |||
562 | i = simple_config_lookup(fe, t_params, ¶ms->frequency, | ||
563 | &config, &cb); | ||
564 | |||
565 | div = params->frequency + IFPCoff + offset; | ||
566 | |||
567 | tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, " | ||
568 | "Offset=%d.%02d MHz, div=%0d\n", | ||
569 | params->frequency / 16, params->frequency % 16 * 100 / 16, | ||
570 | IFPCoff / 16, IFPCoff % 16 * 100 / 16, | ||
571 | offset / 16, offset % 16 * 100 / 16, div); | ||
572 | |||
573 | /* tv norm specific stuff for multi-norm tuners */ | ||
574 | simple_std_setup(fe, params, &config, &cb); | ||
575 | |||
576 | if (t_params->cb_first_if_lower_freq && div < priv->last_div) { | ||
577 | buffer[0] = config; | ||
578 | buffer[1] = cb; | ||
579 | buffer[2] = (div>>8) & 0x7f; | ||
580 | buffer[3] = div & 0xff; | ||
581 | } else { | ||
582 | buffer[0] = (div>>8) & 0x7f; | ||
583 | buffer[1] = div & 0xff; | ||
584 | buffer[2] = config; | ||
585 | buffer[3] = cb; | ||
586 | } | ||
587 | priv->last_div = div; | ||
588 | if (t_params->has_tda9887) { | ||
589 | struct v4l2_priv_tun_config tda9887_cfg; | ||
590 | int config = 0; | ||
591 | int is_secam_l = (params->std & (V4L2_STD_SECAM_L | | ||
592 | V4L2_STD_SECAM_LC)) && | ||
593 | !(params->std & ~(V4L2_STD_SECAM_L | | ||
594 | V4L2_STD_SECAM_LC)); | ||
595 | |||
596 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
597 | tda9887_cfg.priv = &config; | ||
598 | |||
599 | if (params->std == V4L2_STD_SECAM_LC) { | ||
600 | if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc) | ||
601 | config |= TDA9887_PORT1_ACTIVE; | ||
602 | if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) | ||
603 | config |= TDA9887_PORT2_ACTIVE; | ||
604 | } else { | ||
605 | if (t_params->port1_active) | ||
606 | config |= TDA9887_PORT1_ACTIVE; | ||
607 | if (t_params->port2_active) | ||
608 | config |= TDA9887_PORT2_ACTIVE; | ||
609 | } | ||
610 | if (t_params->intercarrier_mode) | ||
611 | config |= TDA9887_INTERCARRIER; | ||
612 | if (is_secam_l) { | ||
613 | if (i == 0 && t_params->default_top_secam_low) | ||
614 | config |= TDA9887_TOP(t_params->default_top_secam_low); | ||
615 | else if (i == 1 && t_params->default_top_secam_mid) | ||
616 | config |= TDA9887_TOP(t_params->default_top_secam_mid); | ||
617 | else if (t_params->default_top_secam_high) | ||
618 | config |= TDA9887_TOP(t_params->default_top_secam_high); | ||
619 | } else { | ||
620 | if (i == 0 && t_params->default_top_low) | ||
621 | config |= TDA9887_TOP(t_params->default_top_low); | ||
622 | else if (i == 1 && t_params->default_top_mid) | ||
623 | config |= TDA9887_TOP(t_params->default_top_mid); | ||
624 | else if (t_params->default_top_high) | ||
625 | config |= TDA9887_TOP(t_params->default_top_high); | ||
626 | } | ||
627 | if (t_params->default_pll_gating_18) | ||
628 | config |= TDA9887_GATING_18; | ||
629 | i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, | ||
630 | &tda9887_cfg); | ||
631 | } | ||
632 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
633 | buffer[0], buffer[1], buffer[2], buffer[3]); | ||
634 | |||
635 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); | ||
636 | if (4 != rc) | ||
637 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); | ||
638 | |||
639 | simple_post_tune(fe, &buffer[0], div, config, cb); | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static int simple_set_radio_freq(struct dvb_frontend *fe, | ||
645 | struct analog_parameters *params) | ||
646 | { | ||
647 | struct tunertype *tun; | ||
648 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
649 | u8 buffer[4]; | ||
650 | u16 div; | ||
651 | int rc, j; | ||
652 | struct tuner_params *t_params; | ||
653 | unsigned int freq = params->frequency; | ||
654 | |||
655 | tun = priv->tun; | ||
656 | |||
657 | for (j = tun->count-1; j > 0; j--) | ||
658 | if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO) | ||
659 | break; | ||
660 | /* default t_params (j=0) will be used if desired type wasn't found */ | ||
661 | t_params = &tun->params[j]; | ||
662 | |||
663 | /* Select Radio 1st IF used */ | ||
664 | switch (t_params->radio_if) { | ||
665 | case 0: /* 10.7 MHz */ | ||
666 | freq += (unsigned int)(10.7*16000); | ||
667 | break; | ||
668 | case 1: /* 33.3 MHz */ | ||
669 | freq += (unsigned int)(33.3*16000); | ||
670 | break; | ||
671 | case 2: /* 41.3 MHz */ | ||
672 | freq += (unsigned int)(41.3*16000); | ||
673 | break; | ||
674 | default: | ||
675 | tuner_warn("Unsupported radio_if value %d\n", | ||
676 | t_params->radio_if); | ||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | /* Bandswitch byte */ | ||
681 | simple_radio_bandswitch(fe, &buffer[0]); | ||
682 | |||
683 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | | ||
684 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ | ||
685 | |||
686 | /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps | ||
687 | freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = | ||
688 | freq * (1/800) */ | ||
689 | div = (freq + 400) / 800; | ||
690 | |||
691 | if (t_params->cb_first_if_lower_freq && div < priv->last_div) { | ||
692 | buffer[0] = buffer[2]; | ||
693 | buffer[1] = buffer[3]; | ||
694 | buffer[2] = (div>>8) & 0x7f; | ||
695 | buffer[3] = div & 0xff; | ||
696 | } else { | ||
697 | buffer[0] = (div>>8) & 0x7f; | ||
698 | buffer[1] = div & 0xff; | ||
699 | } | ||
700 | |||
701 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
702 | buffer[0], buffer[1], buffer[2], buffer[3]); | ||
703 | priv->last_div = div; | ||
704 | |||
705 | if (t_params->has_tda9887) { | ||
706 | int config = 0; | ||
707 | struct v4l2_priv_tun_config tda9887_cfg; | ||
708 | |||
709 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
710 | tda9887_cfg.priv = &config; | ||
711 | |||
712 | if (t_params->port1_active && | ||
713 | !t_params->port1_fm_high_sensitivity) | ||
714 | config |= TDA9887_PORT1_ACTIVE; | ||
715 | if (t_params->port2_active && | ||
716 | !t_params->port2_fm_high_sensitivity) | ||
717 | config |= TDA9887_PORT2_ACTIVE; | ||
718 | if (t_params->intercarrier_mode) | ||
719 | config |= TDA9887_INTERCARRIER; | ||
720 | /* if (t_params->port1_set_for_fm_mono) | ||
721 | config &= ~TDA9887_PORT1_ACTIVE;*/ | ||
722 | if (t_params->fm_gain_normal) | ||
723 | config |= TDA9887_GAIN_NORMAL; | ||
724 | if (t_params->radio_if == 2) | ||
725 | config |= TDA9887_RIF_41_3; | ||
726 | i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, | ||
727 | &tda9887_cfg); | ||
728 | } | ||
729 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); | ||
730 | if (4 != rc) | ||
731 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int simple_set_params(struct dvb_frontend *fe, | ||
737 | struct analog_parameters *params) | ||
738 | { | ||
739 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
740 | int ret = -EINVAL; | ||
741 | |||
742 | if (priv->i2c_props.adap == NULL) | ||
743 | return -EINVAL; | ||
744 | |||
745 | switch (params->mode) { | ||
746 | case V4L2_TUNER_RADIO: | ||
747 | ret = simple_set_radio_freq(fe, params); | ||
748 | priv->frequency = params->frequency * 125 / 2; | ||
749 | break; | ||
750 | case V4L2_TUNER_ANALOG_TV: | ||
751 | case V4L2_TUNER_DIGITAL_TV: | ||
752 | ret = simple_set_tv_freq(fe, params); | ||
753 | priv->frequency = params->frequency * 62500; | ||
754 | break; | ||
755 | } | ||
756 | priv->bandwidth = 0; | ||
757 | |||
758 | return ret; | ||
759 | } | ||
760 | |||
761 | static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf, | ||
762 | const struct dvb_frontend_parameters *params) | ||
763 | { | ||
764 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
765 | |||
766 | switch (priv->type) { | ||
767 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
768 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && | ||
769 | params->frequency >= 158870000) | ||
770 | buf[3] |= 0x08; | ||
771 | break; | ||
772 | case TUNER_PHILIPS_TD1316: | ||
773 | /* determine band */ | ||
774 | buf[3] |= (params->frequency < 161000000) ? 1 : | ||
775 | (params->frequency < 444000000) ? 2 : 4; | ||
776 | |||
777 | /* setup PLL filter */ | ||
778 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) | ||
779 | buf[3] |= 1 << 3; | ||
780 | break; | ||
781 | case TUNER_PHILIPS_TUV1236D: | ||
782 | case TUNER_PHILIPS_FCV1236D: | ||
783 | { | ||
784 | unsigned int new_rf; | ||
785 | |||
786 | if (dtv_input[priv->nr]) | ||
787 | new_rf = dtv_input[priv->nr]; | ||
788 | else | ||
789 | switch (params->u.vsb.modulation) { | ||
790 | case QAM_64: | ||
791 | case QAM_256: | ||
792 | new_rf = 1; | ||
793 | break; | ||
794 | case VSB_8: | ||
795 | default: | ||
796 | new_rf = 0; | ||
797 | break; | ||
798 | } | ||
799 | simple_set_rf_input(fe, &buf[2], &buf[3], new_rf); | ||
800 | break; | ||
801 | } | ||
802 | default: | ||
803 | break; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, | ||
808 | const struct dvb_frontend_parameters *params) | ||
809 | { | ||
810 | /* This function returns the tuned frequency on success, 0 on error */ | ||
811 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
812 | struct tunertype *tun = priv->tun; | ||
813 | static struct tuner_params *t_params; | ||
814 | u8 config, cb; | ||
815 | u32 div; | ||
816 | int ret, frequency = params->frequency / 62500; | ||
817 | |||
818 | t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); | ||
819 | ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); | ||
820 | if (ret < 0) | ||
821 | return 0; /* failure */ | ||
822 | |||
823 | div = ((frequency + t_params->iffreq) * 62500 + offset + | ||
824 | tun->stepsize/2) / tun->stepsize; | ||
825 | |||
826 | buf[0] = div >> 8; | ||
827 | buf[1] = div & 0xff; | ||
828 | buf[2] = config; | ||
829 | buf[3] = cb; | ||
830 | |||
831 | simple_set_dvb(fe, buf, params); | ||
832 | |||
833 | tuner_dbg("%s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", | ||
834 | tun->name, div, buf[0], buf[1], buf[2], buf[3]); | ||
835 | |||
836 | /* calculate the frequency we set it to */ | ||
837 | return (div * tun->stepsize) - t_params->iffreq; | ||
838 | } | ||
839 | |||
840 | static int simple_dvb_calc_regs(struct dvb_frontend *fe, | ||
841 | struct dvb_frontend_parameters *params, | ||
842 | u8 *buf, int buf_len) | ||
843 | { | ||
844 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
845 | u32 frequency; | ||
846 | |||
847 | if (buf_len < 5) | ||
848 | return -EINVAL; | ||
849 | |||
850 | frequency = simple_dvb_configure(fe, buf+1, params); | ||
851 | if (frequency == 0) | ||
852 | return -EINVAL; | ||
853 | |||
854 | buf[0] = priv->i2c_props.addr; | ||
855 | |||
856 | priv->frequency = frequency; | ||
857 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? | ||
858 | params->u.ofdm.bandwidth : 0; | ||
859 | |||
860 | return 5; | ||
861 | } | ||
862 | |||
863 | static int simple_dvb_set_params(struct dvb_frontend *fe, | ||
864 | struct dvb_frontend_parameters *params) | ||
865 | { | ||
866 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
867 | u32 prev_freq, prev_bw; | ||
868 | int ret; | ||
869 | u8 buf[5]; | ||
870 | |||
871 | if (priv->i2c_props.adap == NULL) | ||
872 | return -EINVAL; | ||
873 | |||
874 | prev_freq = priv->frequency; | ||
875 | prev_bw = priv->bandwidth; | ||
876 | |||
877 | ret = simple_dvb_calc_regs(fe, params, buf, 5); | ||
878 | if (ret != 5) | ||
879 | goto fail; | ||
880 | |||
881 | /* put analog demod in standby when tuning digital */ | ||
882 | if (fe->ops.analog_ops.standby) | ||
883 | fe->ops.analog_ops.standby(fe); | ||
884 | |||
885 | if (fe->ops.i2c_gate_ctrl) | ||
886 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
887 | |||
888 | /* buf[0] contains the i2c address, but * | ||
889 | * we already have it in i2c_props.addr */ | ||
890 | ret = tuner_i2c_xfer_send(&priv->i2c_props, buf+1, 4); | ||
891 | if (ret != 4) | ||
892 | goto fail; | ||
893 | |||
894 | return 0; | ||
895 | fail: | ||
896 | /* calc_regs sets frequency and bandwidth. if we failed, unset them */ | ||
897 | priv->frequency = prev_freq; | ||
898 | priv->bandwidth = prev_bw; | ||
899 | |||
900 | return ret; | ||
901 | } | ||
902 | |||
903 | static int simple_init(struct dvb_frontend *fe) | ||
904 | { | ||
905 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
906 | |||
907 | if (priv->i2c_props.adap == NULL) | ||
908 | return -EINVAL; | ||
909 | |||
910 | if (priv->tun->initdata) { | ||
911 | int ret; | ||
912 | |||
913 | if (fe->ops.i2c_gate_ctrl) | ||
914 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
915 | |||
916 | ret = tuner_i2c_xfer_send(&priv->i2c_props, | ||
917 | priv->tun->initdata + 1, | ||
918 | priv->tun->initdata[0]); | ||
919 | if (ret != priv->tun->initdata[0]) | ||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | static int simple_sleep(struct dvb_frontend *fe) | ||
927 | { | ||
928 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
929 | |||
930 | if (priv->i2c_props.adap == NULL) | ||
931 | return -EINVAL; | ||
932 | |||
933 | if (priv->tun->sleepdata) { | ||
934 | int ret; | ||
935 | |||
936 | if (fe->ops.i2c_gate_ctrl) | ||
937 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
938 | |||
939 | ret = tuner_i2c_xfer_send(&priv->i2c_props, | ||
940 | priv->tun->sleepdata + 1, | ||
941 | priv->tun->sleepdata[0]); | ||
942 | if (ret != priv->tun->sleepdata[0]) | ||
943 | return ret; | ||
944 | } | ||
945 | |||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | static int simple_release(struct dvb_frontend *fe) | ||
950 | { | ||
951 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
952 | |||
953 | mutex_lock(&tuner_simple_list_mutex); | ||
954 | |||
955 | if (priv) | ||
956 | hybrid_tuner_release_state(priv); | ||
957 | |||
958 | mutex_unlock(&tuner_simple_list_mutex); | ||
959 | |||
960 | fe->tuner_priv = NULL; | ||
961 | |||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
966 | { | ||
967 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
968 | *frequency = priv->frequency; | ||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
973 | { | ||
974 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
975 | *bandwidth = priv->bandwidth; | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | static struct dvb_tuner_ops simple_tuner_ops = { | ||
980 | .init = simple_init, | ||
981 | .sleep = simple_sleep, | ||
982 | .set_analog_params = simple_set_params, | ||
983 | .set_params = simple_dvb_set_params, | ||
984 | .calc_regs = simple_dvb_calc_regs, | ||
985 | .release = simple_release, | ||
986 | .get_frequency = simple_get_frequency, | ||
987 | .get_bandwidth = simple_get_bandwidth, | ||
988 | .get_status = simple_get_status, | ||
989 | .get_rf_strength = simple_get_rf_strength, | ||
990 | }; | ||
991 | |||
992 | struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | ||
993 | struct i2c_adapter *i2c_adap, | ||
994 | u8 i2c_addr, | ||
995 | unsigned int type) | ||
996 | { | ||
997 | struct tuner_simple_priv *priv = NULL; | ||
998 | int instance; | ||
999 | |||
1000 | if (type >= tuner_count) { | ||
1001 | printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n", | ||
1002 | __func__, type, tuner_count-1); | ||
1003 | return NULL; | ||
1004 | } | ||
1005 | |||
1006 | /* If i2c_adap is set, check that the tuner is at the correct address. | ||
1007 | * Otherwise, if i2c_adap is NULL, the tuner will be programmed directly | ||
1008 | * by the digital demod via calc_regs. | ||
1009 | */ | ||
1010 | if (i2c_adap != NULL) { | ||
1011 | u8 b[1]; | ||
1012 | struct i2c_msg msg = { | ||
1013 | .addr = i2c_addr, .flags = I2C_M_RD, | ||
1014 | .buf = b, .len = 1, | ||
1015 | }; | ||
1016 | |||
1017 | if (fe->ops.i2c_gate_ctrl) | ||
1018 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1019 | |||
1020 | if (1 != i2c_transfer(i2c_adap, &msg, 1)) | ||
1021 | tuner_warn("unable to probe %s, proceeding anyway.", | ||
1022 | tuners[type].name); | ||
1023 | |||
1024 | if (fe->ops.i2c_gate_ctrl) | ||
1025 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1026 | } | ||
1027 | |||
1028 | mutex_lock(&tuner_simple_list_mutex); | ||
1029 | |||
1030 | instance = hybrid_tuner_request_state(struct tuner_simple_priv, priv, | ||
1031 | hybrid_tuner_instance_list, | ||
1032 | i2c_adap, i2c_addr, | ||
1033 | "tuner-simple"); | ||
1034 | switch (instance) { | ||
1035 | case 0: | ||
1036 | mutex_unlock(&tuner_simple_list_mutex); | ||
1037 | return NULL; | ||
1038 | break; | ||
1039 | case 1: | ||
1040 | fe->tuner_priv = priv; | ||
1041 | |||
1042 | priv->type = type; | ||
1043 | priv->tun = &tuners[type]; | ||
1044 | priv->nr = simple_devcount++; | ||
1045 | break; | ||
1046 | default: | ||
1047 | fe->tuner_priv = priv; | ||
1048 | break; | ||
1049 | } | ||
1050 | |||
1051 | mutex_unlock(&tuner_simple_list_mutex); | ||
1052 | |||
1053 | memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, | ||
1054 | sizeof(struct dvb_tuner_ops)); | ||
1055 | |||
1056 | tuner_info("type set to %d (%s)\n", type, priv->tun->name); | ||
1057 | |||
1058 | if ((debug) || ((atv_input[priv->nr] > 0) || | ||
1059 | (dtv_input[priv->nr] > 0))) { | ||
1060 | if (0 == atv_input[priv->nr]) | ||
1061 | tuner_info("tuner %d atv rf input will be " | ||
1062 | "autoselected\n", priv->nr); | ||
1063 | else | ||
1064 | tuner_info("tuner %d atv rf input will be " | ||
1065 | "set to input %d (insmod option)\n", | ||
1066 | priv->nr, atv_input[priv->nr]); | ||
1067 | if (0 == dtv_input[priv->nr]) | ||
1068 | tuner_info("tuner %d dtv rf input will be " | ||
1069 | "autoselected\n", priv->nr); | ||
1070 | else | ||
1071 | tuner_info("tuner %d dtv rf input will be " | ||
1072 | "set to input %d (insmod option)\n", | ||
1073 | priv->nr, dtv_input[priv->nr]); | ||
1074 | } | ||
1075 | |||
1076 | strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name, | ||
1077 | sizeof(fe->ops.tuner_ops.info.name)); | ||
1078 | |||
1079 | return fe; | ||
1080 | } | ||
1081 | EXPORT_SYMBOL_GPL(simple_tuner_attach); | ||
1082 | |||
1083 | MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver"); | ||
1084 | MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | ||
1085 | MODULE_LICENSE("GPL"); | ||
1086 | |||
1087 | /* | ||
1088 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1089 | * --------------------------------------------------------------------------- | ||
1090 | * Local variables: | ||
1091 | * c-basic-offset: 8 | ||
1092 | * End: | ||
1093 | */ | ||
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/video/tuner-simple.h deleted file mode 100644 index e46cf0121e03..000000000000 --- a/drivers/media/video/tuner-simple.h +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or modify | ||
3 | it under the terms of the GNU General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or | ||
5 | (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU General Public License | ||
13 | along with this program; if not, write to the Free Software | ||
14 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TUNER_SIMPLE_H__ | ||
18 | #define __TUNER_SIMPLE_H__ | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | #if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE)) | ||
24 | extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | ||
25 | struct i2c_adapter *i2c_adap, | ||
26 | u8 i2c_addr, | ||
27 | unsigned int type); | ||
28 | #else | ||
29 | static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | ||
30 | struct i2c_adapter *i2c_adap, | ||
31 | u8 i2c_addr, | ||
32 | unsigned int type) | ||
33 | { | ||
34 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
35 | return NULL; | ||
36 | } | ||
37 | #endif | ||
38 | |||
39 | #endif /* __TUNER_SIMPLE_H__ */ | ||
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c deleted file mode 100644 index 10dddca8b5d1..000000000000 --- a/drivers/media/video/tuner-types.c +++ /dev/null | |||
@@ -1,1652 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * i2c tv tuner chip device type database. | ||
4 | * | ||
5 | */ | ||
6 | |||
7 | #include <linux/i2c.h> | ||
8 | #include <media/tuner.h> | ||
9 | #include <media/tuner-types.h> | ||
10 | |||
11 | /* ---------------------------------------------------------------------- */ | ||
12 | |||
13 | /* | ||
14 | * The floats in the tuner struct are computed at compile time | ||
15 | * by gcc and cast back to integers. Thus we don't violate the | ||
16 | * "no float in kernel" rule. | ||
17 | * | ||
18 | * A tuner_range may be referenced by multiple tuner_params structs. | ||
19 | * There are many duplicates in here. Reusing tuner_range structs, | ||
20 | * rather than defining new ones for each tuner, will cut down on | ||
21 | * memory usage, and is preferred when possible. | ||
22 | * | ||
23 | * Each tuner_params array may contain one or more elements, one | ||
24 | * for each video standard. | ||
25 | * | ||
26 | * FIXME: tuner_params struct contains an element, tda988x. We must | ||
27 | * set this for all tuners that contain a tda988x chip, and then we | ||
28 | * can remove this setting from the various card structs. | ||
29 | * | ||
30 | * FIXME: Right now, all tuners are using the first tuner_params[] | ||
31 | * array element for analog mode. In the future, we will be merging | ||
32 | * similar tuner definitions together, such that each tuner definition | ||
33 | * will have a tuner_params struct for each available video standard. | ||
34 | * At that point, the tuner_params[] array element will be chosen | ||
35 | * based on the video standard in use. | ||
36 | */ | ||
37 | |||
38 | /* The following was taken from dvb-pll.c: */ | ||
39 | |||
40 | /* Set AGC TOP value to 103 dBuV: | ||
41 | * 0x80 = Control Byte | ||
42 | * 0x40 = 250 uA charge pump (irrelevant) | ||
43 | * 0x18 = Aux Byte to follow | ||
44 | * 0x06 = 64.5 kHz divider (irrelevant) | ||
45 | * 0x01 = Disable Vt (aka sleep) | ||
46 | * | ||
47 | * 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA) | ||
48 | * 0x50 = AGC Take over point = 103 dBuV | ||
49 | */ | ||
50 | static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; | ||
51 | |||
52 | /* 0x04 = 166.67 kHz divider | ||
53 | * | ||
54 | * 0x80 = AGC Time constant 50ms Iagc = 9 uA | ||
55 | * 0x20 = AGC Take over point = 112 dBuV | ||
56 | */ | ||
57 | static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 }; | ||
58 | |||
59 | /* 0-9 */ | ||
60 | /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ | ||
61 | |||
62 | static struct tuner_range tuner_temic_pal_ranges[] = { | ||
63 | { 16 * 140.25 /*MHz*/, 0x8e, 0x02, }, | ||
64 | { 16 * 463.25 /*MHz*/, 0x8e, 0x04, }, | ||
65 | { 16 * 999.99 , 0x8e, 0x01, }, | ||
66 | }; | ||
67 | |||
68 | static struct tuner_params tuner_temic_pal_params[] = { | ||
69 | { | ||
70 | .type = TUNER_PARAM_TYPE_PAL, | ||
71 | .ranges = tuner_temic_pal_ranges, | ||
72 | .count = ARRAY_SIZE(tuner_temic_pal_ranges), | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | /* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */ | ||
77 | |||
78 | static struct tuner_range tuner_philips_pal_i_ranges[] = { | ||
79 | { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, }, | ||
80 | { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, | ||
81 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
82 | }; | ||
83 | |||
84 | static struct tuner_params tuner_philips_pal_i_params[] = { | ||
85 | { | ||
86 | .type = TUNER_PARAM_TYPE_PAL, | ||
87 | .ranges = tuner_philips_pal_i_ranges, | ||
88 | .count = ARRAY_SIZE(tuner_philips_pal_i_ranges), | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | /* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */ | ||
93 | |||
94 | static struct tuner_range tuner_philips_ntsc_ranges[] = { | ||
95 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, | ||
96 | { 16 * 451.25 /*MHz*/, 0x8e, 0x90, }, | ||
97 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
98 | }; | ||
99 | |||
100 | static struct tuner_params tuner_philips_ntsc_params[] = { | ||
101 | { | ||
102 | .type = TUNER_PARAM_TYPE_NTSC, | ||
103 | .ranges = tuner_philips_ntsc_ranges, | ||
104 | .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), | ||
105 | .cb_first_if_lower_freq = 1, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | /* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */ | ||
110 | |||
111 | static struct tuner_range tuner_philips_secam_ranges[] = { | ||
112 | { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, }, | ||
113 | { 16 * 447.25 /*MHz*/, 0x8e, 0x97, }, | ||
114 | { 16 * 999.99 , 0x8e, 0x37, }, | ||
115 | }; | ||
116 | |||
117 | static struct tuner_params tuner_philips_secam_params[] = { | ||
118 | { | ||
119 | .type = TUNER_PARAM_TYPE_SECAM, | ||
120 | .ranges = tuner_philips_secam_ranges, | ||
121 | .count = ARRAY_SIZE(tuner_philips_secam_ranges), | ||
122 | .cb_first_if_lower_freq = 1, | ||
123 | }, | ||
124 | }; | ||
125 | |||
126 | /* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */ | ||
127 | |||
128 | static struct tuner_range tuner_philips_pal_ranges[] = { | ||
129 | { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, }, | ||
130 | { 16 * 447.25 /*MHz*/, 0x8e, 0x90, }, | ||
131 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
132 | }; | ||
133 | |||
134 | static struct tuner_params tuner_philips_pal_params[] = { | ||
135 | { | ||
136 | .type = TUNER_PARAM_TYPE_PAL, | ||
137 | .ranges = tuner_philips_pal_ranges, | ||
138 | .count = ARRAY_SIZE(tuner_philips_pal_ranges), | ||
139 | .cb_first_if_lower_freq = 1, | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | /* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */ | ||
144 | |||
145 | static struct tuner_range tuner_temic_ntsc_ranges[] = { | ||
146 | { 16 * 157.25 /*MHz*/, 0x8e, 0x02, }, | ||
147 | { 16 * 463.25 /*MHz*/, 0x8e, 0x04, }, | ||
148 | { 16 * 999.99 , 0x8e, 0x01, }, | ||
149 | }; | ||
150 | |||
151 | static struct tuner_params tuner_temic_ntsc_params[] = { | ||
152 | { | ||
153 | .type = TUNER_PARAM_TYPE_NTSC, | ||
154 | .ranges = tuner_temic_ntsc_ranges, | ||
155 | .count = ARRAY_SIZE(tuner_temic_ntsc_ranges), | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | /* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */ | ||
160 | |||
161 | static struct tuner_range tuner_temic_pal_i_ranges[] = { | ||
162 | { 16 * 170.00 /*MHz*/, 0x8e, 0x02, }, | ||
163 | { 16 * 450.00 /*MHz*/, 0x8e, 0x04, }, | ||
164 | { 16 * 999.99 , 0x8e, 0x01, }, | ||
165 | }; | ||
166 | |||
167 | static struct tuner_params tuner_temic_pal_i_params[] = { | ||
168 | { | ||
169 | .type = TUNER_PARAM_TYPE_PAL, | ||
170 | .ranges = tuner_temic_pal_i_ranges, | ||
171 | .count = ARRAY_SIZE(tuner_temic_pal_i_ranges), | ||
172 | }, | ||
173 | }; | ||
174 | |||
175 | /* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */ | ||
176 | |||
177 | static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = { | ||
178 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, | ||
179 | { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, | ||
180 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
181 | }; | ||
182 | |||
183 | static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = { | ||
184 | { | ||
185 | .type = TUNER_PARAM_TYPE_NTSC, | ||
186 | .ranges = tuner_temic_4036fy5_ntsc_ranges, | ||
187 | .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges), | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | /* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */ | ||
192 | |||
193 | static struct tuner_range tuner_alps_tsb_1_ranges[] = { | ||
194 | { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, | ||
195 | { 16 * 385.25 /*MHz*/, 0x8e, 0x02, }, | ||
196 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
197 | }; | ||
198 | |||
199 | static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = { | ||
200 | { | ||
201 | .type = TUNER_PARAM_TYPE_NTSC, | ||
202 | .ranges = tuner_alps_tsb_1_ranges, | ||
203 | .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), | ||
204 | }, | ||
205 | }; | ||
206 | |||
207 | /* 10-19 */ | ||
208 | /* ------------ TUNER_ALPS_TSBE1_PAL - TEMIC PAL ------------ */ | ||
209 | |||
210 | static struct tuner_params tuner_alps_tsb_1_params[] = { | ||
211 | { | ||
212 | .type = TUNER_PARAM_TYPE_PAL, | ||
213 | .ranges = tuner_alps_tsb_1_ranges, | ||
214 | .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), | ||
215 | }, | ||
216 | }; | ||
217 | |||
218 | /* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */ | ||
219 | |||
220 | static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = { | ||
221 | { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, | ||
222 | { 16 * 351.25 /*MHz*/, 0x8e, 0x02, }, | ||
223 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
224 | }; | ||
225 | |||
226 | static struct tuner_params tuner_alps_tsbb5_params[] = { | ||
227 | { | ||
228 | .type = TUNER_PARAM_TYPE_PAL, | ||
229 | .ranges = tuner_alps_tsb_5_pal_ranges, | ||
230 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | /* ------------ TUNER_ALPS_TSBE5_PAL - Alps PAL ------------ */ | ||
235 | |||
236 | static struct tuner_params tuner_alps_tsbe5_params[] = { | ||
237 | { | ||
238 | .type = TUNER_PARAM_TYPE_PAL, | ||
239 | .ranges = tuner_alps_tsb_5_pal_ranges, | ||
240 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | /* ------------ TUNER_ALPS_TSBC5_PAL - Alps PAL ------------ */ | ||
245 | |||
246 | static struct tuner_params tuner_alps_tsbc5_params[] = { | ||
247 | { | ||
248 | .type = TUNER_PARAM_TYPE_PAL, | ||
249 | .ranges = tuner_alps_tsb_5_pal_ranges, | ||
250 | .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), | ||
251 | }, | ||
252 | }; | ||
253 | |||
254 | /* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */ | ||
255 | |||
256 | static struct tuner_range tuner_lg_pal_ranges[] = { | ||
257 | { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, }, | ||
258 | { 16 * 450.00 /*MHz*/, 0x8e, 0x90, }, | ||
259 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
260 | }; | ||
261 | |||
262 | static struct tuner_params tuner_temic_4006fh5_params[] = { | ||
263 | { | ||
264 | .type = TUNER_PARAM_TYPE_PAL, | ||
265 | .ranges = tuner_lg_pal_ranges, | ||
266 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
267 | }, | ||
268 | }; | ||
269 | |||
270 | /* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */ | ||
271 | |||
272 | static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = { | ||
273 | { 16 * 137.25 /*MHz*/, 0x8e, 0x14, }, | ||
274 | { 16 * 385.25 /*MHz*/, 0x8e, 0x12, }, | ||
275 | { 16 * 999.99 , 0x8e, 0x11, }, | ||
276 | }; | ||
277 | |||
278 | static struct tuner_params tuner_alps_tshc6_params[] = { | ||
279 | { | ||
280 | .type = TUNER_PARAM_TYPE_NTSC, | ||
281 | .ranges = tuner_alps_tshc6_ntsc_ranges, | ||
282 | .count = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges), | ||
283 | }, | ||
284 | }; | ||
285 | |||
286 | /* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */ | ||
287 | |||
288 | static struct tuner_range tuner_temic_pal_dk_ranges[] = { | ||
289 | { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, }, | ||
290 | { 16 * 456.25 /*MHz*/, 0x8e, 0x90, }, | ||
291 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
292 | }; | ||
293 | |||
294 | static struct tuner_params tuner_temic_pal_dk_params[] = { | ||
295 | { | ||
296 | .type = TUNER_PARAM_TYPE_PAL, | ||
297 | .ranges = tuner_temic_pal_dk_ranges, | ||
298 | .count = ARRAY_SIZE(tuner_temic_pal_dk_ranges), | ||
299 | }, | ||
300 | }; | ||
301 | |||
302 | /* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */ | ||
303 | |||
304 | static struct tuner_range tuner_philips_ntsc_m_ranges[] = { | ||
305 | { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, }, | ||
306 | { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, | ||
307 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
308 | }; | ||
309 | |||
310 | static struct tuner_params tuner_philips_ntsc_m_params[] = { | ||
311 | { | ||
312 | .type = TUNER_PARAM_TYPE_NTSC, | ||
313 | .ranges = tuner_philips_ntsc_m_ranges, | ||
314 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), | ||
315 | }, | ||
316 | }; | ||
317 | |||
318 | /* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */ | ||
319 | |||
320 | static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = { | ||
321 | { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, }, | ||
322 | { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, | ||
323 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
324 | }; | ||
325 | |||
326 | static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = { | ||
327 | { | ||
328 | .type = TUNER_PARAM_TYPE_PAL, | ||
329 | .ranges = tuner_temic_40x6f_5_pal_ranges, | ||
330 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), | ||
331 | }, | ||
332 | }; | ||
333 | |||
334 | /* ------------ TUNER_TEMIC_4006FN5_MULTI_PAL - TEMIC PAL ------------ */ | ||
335 | |||
336 | static struct tuner_params tuner_temic_4006fn5_multi_params[] = { | ||
337 | { | ||
338 | .type = TUNER_PARAM_TYPE_PAL, | ||
339 | .ranges = tuner_temic_40x6f_5_pal_ranges, | ||
340 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), | ||
341 | }, | ||
342 | }; | ||
343 | |||
344 | /* 20-29 */ | ||
345 | /* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */ | ||
346 | |||
347 | static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = { | ||
348 | { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, }, | ||
349 | { 16 * 464.00 /*MHz*/, 0x8e, 0x90, }, | ||
350 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
351 | }; | ||
352 | |||
353 | static struct tuner_params tuner_temic_4009f_5_params[] = { | ||
354 | { | ||
355 | .type = TUNER_PARAM_TYPE_PAL, | ||
356 | .ranges = tuner_temic_4009f_5_pal_ranges, | ||
357 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | ||
358 | }, | ||
359 | }; | ||
360 | |||
361 | /* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */ | ||
362 | |||
363 | static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = { | ||
364 | { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, }, | ||
365 | { 16 * 453.00 /*MHz*/, 0x8e, 0x90, }, | ||
366 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
367 | }; | ||
368 | |||
369 | static struct tuner_params tuner_temic_4039fr5_params[] = { | ||
370 | { | ||
371 | .type = TUNER_PARAM_TYPE_NTSC, | ||
372 | .ranges = tuner_temic_4x3x_f_5_ntsc_ranges, | ||
373 | .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges), | ||
374 | }, | ||
375 | }; | ||
376 | |||
377 | /* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */ | ||
378 | |||
379 | static struct tuner_params tuner_temic_4046fm5_params[] = { | ||
380 | { | ||
381 | .type = TUNER_PARAM_TYPE_PAL, | ||
382 | .ranges = tuner_temic_40x6f_5_pal_ranges, | ||
383 | .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), | ||
384 | }, | ||
385 | }; | ||
386 | |||
387 | /* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */ | ||
388 | |||
389 | static struct tuner_params tuner_philips_pal_dk_params[] = { | ||
390 | { | ||
391 | .type = TUNER_PARAM_TYPE_PAL, | ||
392 | .ranges = tuner_lg_pal_ranges, | ||
393 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
394 | }, | ||
395 | }; | ||
396 | |||
397 | /* ------------ TUNER_PHILIPS_FQ1216ME - Philips PAL ------------ */ | ||
398 | |||
399 | static struct tuner_params tuner_philips_fq1216me_params[] = { | ||
400 | { | ||
401 | .type = TUNER_PARAM_TYPE_PAL, | ||
402 | .ranges = tuner_lg_pal_ranges, | ||
403 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
404 | .has_tda9887 = 1, | ||
405 | .port1_active = 1, | ||
406 | .port2_active = 1, | ||
407 | .port2_invert_for_secam_lc = 1, | ||
408 | }, | ||
409 | }; | ||
410 | |||
411 | /* ------------ TUNER_LG_PAL_I_FM - LGINNOTEK PAL_I ------------ */ | ||
412 | |||
413 | static struct tuner_params tuner_lg_pal_i_fm_params[] = { | ||
414 | { | ||
415 | .type = TUNER_PARAM_TYPE_PAL, | ||
416 | .ranges = tuner_lg_pal_ranges, | ||
417 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
418 | }, | ||
419 | }; | ||
420 | |||
421 | /* ------------ TUNER_LG_PAL_I - LGINNOTEK PAL_I ------------ */ | ||
422 | |||
423 | static struct tuner_params tuner_lg_pal_i_params[] = { | ||
424 | { | ||
425 | .type = TUNER_PARAM_TYPE_PAL, | ||
426 | .ranges = tuner_lg_pal_ranges, | ||
427 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
428 | }, | ||
429 | }; | ||
430 | |||
431 | /* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */ | ||
432 | |||
433 | static struct tuner_range tuner_lg_ntsc_fm_ranges[] = { | ||
434 | { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, }, | ||
435 | { 16 * 497.00 /*MHz*/, 0x8e, 0x90, }, | ||
436 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
437 | }; | ||
438 | |||
439 | static struct tuner_params tuner_lg_ntsc_fm_params[] = { | ||
440 | { | ||
441 | .type = TUNER_PARAM_TYPE_NTSC, | ||
442 | .ranges = tuner_lg_ntsc_fm_ranges, | ||
443 | .count = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges), | ||
444 | }, | ||
445 | }; | ||
446 | |||
447 | /* ------------ TUNER_LG_PAL_FM - LGINNOTEK PAL ------------ */ | ||
448 | |||
449 | static struct tuner_params tuner_lg_pal_fm_params[] = { | ||
450 | { | ||
451 | .type = TUNER_PARAM_TYPE_PAL, | ||
452 | .ranges = tuner_lg_pal_ranges, | ||
453 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
454 | }, | ||
455 | }; | ||
456 | |||
457 | /* ------------ TUNER_LG_PAL - LGINNOTEK PAL ------------ */ | ||
458 | |||
459 | static struct tuner_params tuner_lg_pal_params[] = { | ||
460 | { | ||
461 | .type = TUNER_PARAM_TYPE_PAL, | ||
462 | .ranges = tuner_lg_pal_ranges, | ||
463 | .count = ARRAY_SIZE(tuner_lg_pal_ranges), | ||
464 | }, | ||
465 | }; | ||
466 | |||
467 | /* 30-39 */ | ||
468 | /* ------------ TUNER_TEMIC_4009FN5_MULTI_PAL_FM - TEMIC PAL ------------ */ | ||
469 | |||
470 | static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = { | ||
471 | { | ||
472 | .type = TUNER_PARAM_TYPE_PAL, | ||
473 | .ranges = tuner_temic_4009f_5_pal_ranges, | ||
474 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | ||
475 | }, | ||
476 | }; | ||
477 | |||
478 | /* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */ | ||
479 | |||
480 | static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = { | ||
481 | { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, | ||
482 | { 16 * 317.25 /*MHz*/, 0x8e, 0x02, }, | ||
483 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
484 | }; | ||
485 | |||
486 | static struct tuner_params tuner_sharp_2u5jf5540_params[] = { | ||
487 | { | ||
488 | .type = TUNER_PARAM_TYPE_NTSC, | ||
489 | .ranges = tuner_sharp_2u5jf5540_ntsc_ranges, | ||
490 | .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges), | ||
491 | }, | ||
492 | }; | ||
493 | |||
494 | /* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */ | ||
495 | |||
496 | static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = { | ||
497 | { 16 * 169 /*MHz*/, 0x8e, 0xa0, }, | ||
498 | { 16 * 464 /*MHz*/, 0x8e, 0x90, }, | ||
499 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
500 | }; | ||
501 | |||
502 | static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = { | ||
503 | { | ||
504 | .type = TUNER_PARAM_TYPE_PAL, | ||
505 | .ranges = tuner_samsung_pal_tcpm9091pd27_ranges, | ||
506 | .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges), | ||
507 | }, | ||
508 | }; | ||
509 | |||
510 | /* ------------ TUNER_TEMIC_4106FH5 - TEMIC PAL ------------ */ | ||
511 | |||
512 | static struct tuner_params tuner_temic_4106fh5_params[] = { | ||
513 | { | ||
514 | .type = TUNER_PARAM_TYPE_PAL, | ||
515 | .ranges = tuner_temic_4009f_5_pal_ranges, | ||
516 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | ||
517 | }, | ||
518 | }; | ||
519 | |||
520 | /* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */ | ||
521 | |||
522 | static struct tuner_params tuner_temic_4012fy5_params[] = { | ||
523 | { | ||
524 | .type = TUNER_PARAM_TYPE_PAL, | ||
525 | .ranges = tuner_temic_pal_ranges, | ||
526 | .count = ARRAY_SIZE(tuner_temic_pal_ranges), | ||
527 | }, | ||
528 | }; | ||
529 | |||
530 | /* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */ | ||
531 | |||
532 | static struct tuner_params tuner_temic_4136_fy5_params[] = { | ||
533 | { | ||
534 | .type = TUNER_PARAM_TYPE_NTSC, | ||
535 | .ranges = tuner_temic_4x3x_f_5_ntsc_ranges, | ||
536 | .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges), | ||
537 | }, | ||
538 | }; | ||
539 | |||
540 | /* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */ | ||
541 | |||
542 | static struct tuner_range tuner_lg_new_tapc_ranges[] = { | ||
543 | { 16 * 170.00 /*MHz*/, 0x8e, 0x01, }, | ||
544 | { 16 * 450.00 /*MHz*/, 0x8e, 0x02, }, | ||
545 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
546 | }; | ||
547 | |||
548 | static struct tuner_params tuner_lg_pal_new_tapc_params[] = { | ||
549 | { | ||
550 | .type = TUNER_PARAM_TYPE_PAL, | ||
551 | .ranges = tuner_lg_new_tapc_ranges, | ||
552 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), | ||
553 | }, | ||
554 | }; | ||
555 | |||
556 | /* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */ | ||
557 | |||
558 | static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = { | ||
559 | { 16 * 158.00 /*MHz*/, 0x8e, 0x01, }, | ||
560 | { 16 * 442.00 /*MHz*/, 0x8e, 0x02, }, | ||
561 | { 16 * 999.99 , 0x8e, 0x04, }, | ||
562 | }; | ||
563 | |||
564 | static struct tuner_params tuner_fm1216me_mk3_params[] = { | ||
565 | { | ||
566 | .type = TUNER_PARAM_TYPE_PAL, | ||
567 | .ranges = tuner_fm1216me_mk3_pal_ranges, | ||
568 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), | ||
569 | .cb_first_if_lower_freq = 1, | ||
570 | .has_tda9887 = 1, | ||
571 | .port1_active = 1, | ||
572 | .port2_active = 1, | ||
573 | .port2_invert_for_secam_lc = 1, | ||
574 | .port1_fm_high_sensitivity = 1, | ||
575 | .default_top_mid = -2, | ||
576 | .default_top_secam_mid = -2, | ||
577 | .default_top_secam_high = -2, | ||
578 | }, | ||
579 | }; | ||
580 | |||
581 | /* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */ | ||
582 | |||
583 | static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { | ||
584 | { | ||
585 | .type = TUNER_PARAM_TYPE_NTSC, | ||
586 | .ranges = tuner_lg_new_tapc_ranges, | ||
587 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), | ||
588 | }, | ||
589 | }; | ||
590 | |||
591 | /* 40-49 */ | ||
592 | /* ------------ TUNER_HITACHI_NTSC - HITACHI NTSC ------------ */ | ||
593 | |||
594 | static struct tuner_params tuner_hitachi_ntsc_params[] = { | ||
595 | { | ||
596 | .type = TUNER_PARAM_TYPE_NTSC, | ||
597 | .ranges = tuner_lg_new_tapc_ranges, | ||
598 | .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), | ||
599 | }, | ||
600 | }; | ||
601 | |||
602 | /* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */ | ||
603 | |||
604 | static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = { | ||
605 | { 16 * 140.25 /*MHz*/, 0x8e, 0x01, }, | ||
606 | { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, }, | ||
607 | { 16 * 999.99 , 0x8e, 0xcf, }, | ||
608 | }; | ||
609 | |||
610 | static struct tuner_params tuner_philips_pal_mk_params[] = { | ||
611 | { | ||
612 | .type = TUNER_PARAM_TYPE_PAL, | ||
613 | .ranges = tuner_philips_pal_mk_pal_ranges, | ||
614 | .count = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges), | ||
615 | }, | ||
616 | }; | ||
617 | |||
618 | /* ---- TUNER_PHILIPS_FCV1236D - Philips FCV1236D (ATSC/NTSC) ---- */ | ||
619 | |||
620 | static struct tuner_range tuner_philips_fcv1236d_ntsc_ranges[] = { | ||
621 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa2, }, | ||
622 | { 16 * 451.25 /*MHz*/, 0x8e, 0x92, }, | ||
623 | { 16 * 999.99 , 0x8e, 0x32, }, | ||
624 | }; | ||
625 | |||
626 | static struct tuner_range tuner_philips_fcv1236d_atsc_ranges[] = { | ||
627 | { 16 * 159.00 /*MHz*/, 0x8e, 0xa0, }, | ||
628 | { 16 * 453.00 /*MHz*/, 0x8e, 0x90, }, | ||
629 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
630 | }; | ||
631 | |||
632 | static struct tuner_params tuner_philips_fcv1236d_params[] = { | ||
633 | { | ||
634 | .type = TUNER_PARAM_TYPE_NTSC, | ||
635 | .ranges = tuner_philips_fcv1236d_ntsc_ranges, | ||
636 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_ntsc_ranges), | ||
637 | }, | ||
638 | { | ||
639 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
640 | .ranges = tuner_philips_fcv1236d_atsc_ranges, | ||
641 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_atsc_ranges), | ||
642 | .iffreq = 16 * 44.00, | ||
643 | }, | ||
644 | }; | ||
645 | |||
646 | /* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */ | ||
647 | |||
648 | static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = { | ||
649 | { 16 * 160.00 /*MHz*/, 0x8e, 0x01, }, | ||
650 | { 16 * 442.00 /*MHz*/, 0x8e, 0x02, }, | ||
651 | { 16 * 999.99 , 0x8e, 0x04, }, | ||
652 | }; | ||
653 | |||
654 | static struct tuner_params tuner_fm1236_mk3_params[] = { | ||
655 | { | ||
656 | .type = TUNER_PARAM_TYPE_NTSC, | ||
657 | .ranges = tuner_fm1236_mk3_ntsc_ranges, | ||
658 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), | ||
659 | .cb_first_if_lower_freq = 1, | ||
660 | .has_tda9887 = 1, | ||
661 | .port1_active = 1, | ||
662 | .port2_active = 1, | ||
663 | .port1_fm_high_sensitivity = 1, | ||
664 | }, | ||
665 | }; | ||
666 | |||
667 | /* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */ | ||
668 | |||
669 | static struct tuner_params tuner_philips_4in1_params[] = { | ||
670 | { | ||
671 | .type = TUNER_PARAM_TYPE_NTSC, | ||
672 | .ranges = tuner_fm1236_mk3_ntsc_ranges, | ||
673 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), | ||
674 | }, | ||
675 | }; | ||
676 | |||
677 | /* ------------ TUNER_MICROTUNE_4049FM5 - Microtune PAL ------------ */ | ||
678 | |||
679 | static struct tuner_params tuner_microtune_4049_fm5_params[] = { | ||
680 | { | ||
681 | .type = TUNER_PARAM_TYPE_PAL, | ||
682 | .ranges = tuner_temic_4009f_5_pal_ranges, | ||
683 | .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), | ||
684 | .has_tda9887 = 1, | ||
685 | .port1_invert_for_secam_lc = 1, | ||
686 | .default_pll_gating_18 = 1, | ||
687 | .fm_gain_normal=1, | ||
688 | .radio_if = 1, /* 33.3 MHz */ | ||
689 | }, | ||
690 | }; | ||
691 | |||
692 | /* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */ | ||
693 | |||
694 | static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = { | ||
695 | { 16 * 160.00 /*MHz*/, 0xce, 0x01, }, | ||
696 | { 16 * 454.00 /*MHz*/, 0xce, 0x02, }, | ||
697 | { 16 * 999.99 , 0xce, 0x08, }, | ||
698 | }; | ||
699 | |||
700 | static struct tuner_params tuner_panasonic_vp27_params[] = { | ||
701 | { | ||
702 | .type = TUNER_PARAM_TYPE_NTSC, | ||
703 | .ranges = tuner_panasonic_vp27_ntsc_ranges, | ||
704 | .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges), | ||
705 | .has_tda9887 = 1, | ||
706 | .intercarrier_mode = 1, | ||
707 | .default_top_low = -3, | ||
708 | .default_top_mid = -3, | ||
709 | .default_top_high = -3, | ||
710 | }, | ||
711 | }; | ||
712 | |||
713 | /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */ | ||
714 | |||
715 | static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = { | ||
716 | { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, }, | ||
717 | { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, | ||
718 | { 16 * 999.99 , 0x8e, 0x30, }, | ||
719 | }; | ||
720 | |||
721 | static struct tuner_params tuner_tnf_8831bgff_params[] = { | ||
722 | { | ||
723 | .type = TUNER_PARAM_TYPE_PAL, | ||
724 | .ranges = tuner_tnf_8831bgff_pal_ranges, | ||
725 | .count = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges), | ||
726 | }, | ||
727 | }; | ||
728 | |||
729 | /* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */ | ||
730 | |||
731 | static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = { | ||
732 | { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, }, | ||
733 | { 16 * 457.00 /*MHz*/, 0x8e, 0x94, }, | ||
734 | { 16 * 999.99 , 0x8e, 0x31, }, | ||
735 | }; | ||
736 | |||
737 | static struct tuner_range tuner_microtune_4042fi5_atsc_ranges[] = { | ||
738 | { 16 * 162.00 /*MHz*/, 0x8e, 0xa1, }, | ||
739 | { 16 * 457.00 /*MHz*/, 0x8e, 0x91, }, | ||
740 | { 16 * 999.99 , 0x8e, 0x31, }, | ||
741 | }; | ||
742 | |||
743 | static struct tuner_params tuner_microtune_4042fi5_params[] = { | ||
744 | { | ||
745 | .type = TUNER_PARAM_TYPE_NTSC, | ||
746 | .ranges = tuner_microtune_4042fi5_ntsc_ranges, | ||
747 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges), | ||
748 | }, | ||
749 | { | ||
750 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
751 | .ranges = tuner_microtune_4042fi5_atsc_ranges, | ||
752 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_atsc_ranges), | ||
753 | .iffreq = 16 * 44.00 /*MHz*/, | ||
754 | }, | ||
755 | }; | ||
756 | |||
757 | /* 50-59 */ | ||
758 | /* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */ | ||
759 | |||
760 | static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = { | ||
761 | { 16 * 172.00 /*MHz*/, 0x8e, 0x01, }, | ||
762 | { 16 * 448.00 /*MHz*/, 0x8e, 0x02, }, | ||
763 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
764 | }; | ||
765 | |||
766 | static struct tuner_params tuner_tcl_2002n_params[] = { | ||
767 | { | ||
768 | .type = TUNER_PARAM_TYPE_NTSC, | ||
769 | .ranges = tuner_tcl_2002n_ntsc_ranges, | ||
770 | .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), | ||
771 | .cb_first_if_lower_freq = 1, | ||
772 | }, | ||
773 | }; | ||
774 | |||
775 | /* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */ | ||
776 | |||
777 | static struct tuner_params tuner_philips_fm1256_ih3_params[] = { | ||
778 | { | ||
779 | .type = TUNER_PARAM_TYPE_PAL, | ||
780 | .ranges = tuner_fm1236_mk3_ntsc_ranges, | ||
781 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), | ||
782 | .radio_if = 1, /* 33.3 MHz */ | ||
783 | }, | ||
784 | }; | ||
785 | |||
786 | /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */ | ||
787 | |||
788 | /* single range used for both ntsc and atsc */ | ||
789 | static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = { | ||
790 | { 16 * 157.25 /*MHz*/, 0x8e, 0x39, }, | ||
791 | { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, }, | ||
792 | { 16 * 999.99 , 0x8e, 0x3c, }, | ||
793 | }; | ||
794 | |||
795 | static struct tuner_params tuner_thomson_dtt7610_params[] = { | ||
796 | { | ||
797 | .type = TUNER_PARAM_TYPE_NTSC, | ||
798 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, | ||
799 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), | ||
800 | }, | ||
801 | { | ||
802 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
803 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, | ||
804 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), | ||
805 | .iffreq = 16 * 44.00 /*MHz*/, | ||
806 | }, | ||
807 | }; | ||
808 | |||
809 | /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */ | ||
810 | |||
811 | static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = { | ||
812 | { 16 * 160.00 /*MHz*/, 0x8e, 0x41, }, | ||
813 | { 16 * 454.00 /*MHz*/, 0x8e, 0x42, }, | ||
814 | { 16 * 999.99 , 0x8e, 0x04, }, | ||
815 | }; | ||
816 | |||
817 | static struct tuner_params tuner_philips_fq1286_params[] = { | ||
818 | { | ||
819 | .type = TUNER_PARAM_TYPE_NTSC, | ||
820 | .ranges = tuner_philips_fq1286_ntsc_ranges, | ||
821 | .count = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges), | ||
822 | }, | ||
823 | }; | ||
824 | |||
825 | /* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */ | ||
826 | |||
827 | static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = { | ||
828 | { 16 * 170.00 /*MHz*/, 0xce, 0x01, }, | ||
829 | { 16 * 450.00 /*MHz*/, 0xce, 0x02, }, | ||
830 | { 16 * 999.99 , 0xce, 0x08, }, | ||
831 | }; | ||
832 | |||
833 | static struct tuner_params tuner_tcl_2002mb_params[] = { | ||
834 | { | ||
835 | .type = TUNER_PARAM_TYPE_PAL, | ||
836 | .ranges = tuner_tcl_2002mb_pal_ranges, | ||
837 | .count = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges), | ||
838 | }, | ||
839 | }; | ||
840 | |||
841 | /* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */ | ||
842 | |||
843 | static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = { | ||
844 | { 16 * 160.00 /*MHz*/, 0xce, 0x01, }, | ||
845 | { 16 * 442.00 /*MHz*/, 0xce, 0x02, }, | ||
846 | { 16 * 999.99 , 0xce, 0x04, }, | ||
847 | }; | ||
848 | |||
849 | static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = { | ||
850 | { | ||
851 | .type = TUNER_PARAM_TYPE_PAL, | ||
852 | .ranges = tuner_philips_fq12_6a___mk4_pal_ranges, | ||
853 | .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges), | ||
854 | .has_tda9887 = 1, | ||
855 | .port1_active = 1, | ||
856 | .port2_invert_for_secam_lc = 1, | ||
857 | .default_top_mid = -2, | ||
858 | .default_top_secam_low = -2, | ||
859 | .default_top_secam_mid = -2, | ||
860 | .default_top_secam_high = -2, | ||
861 | }, | ||
862 | }; | ||
863 | |||
864 | /* ------------ TUNER_PHILIPS_FQ1236A_MK4 - Philips NTSC ------------ */ | ||
865 | |||
866 | static struct tuner_params tuner_philips_fq1236a_mk4_params[] = { | ||
867 | { | ||
868 | .type = TUNER_PARAM_TYPE_NTSC, | ||
869 | .ranges = tuner_fm1236_mk3_ntsc_ranges, | ||
870 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), | ||
871 | }, | ||
872 | }; | ||
873 | |||
874 | /* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */ | ||
875 | |||
876 | static struct tuner_params tuner_ymec_tvf_8531mf_params[] = { | ||
877 | { | ||
878 | .type = TUNER_PARAM_TYPE_NTSC, | ||
879 | .ranges = tuner_philips_ntsc_m_ranges, | ||
880 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), | ||
881 | }, | ||
882 | }; | ||
883 | |||
884 | /* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */ | ||
885 | |||
886 | static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = { | ||
887 | { 16 * 160.00 /*MHz*/, 0x8e, 0x01, }, | ||
888 | { 16 * 454.00 /*MHz*/, 0x8e, 0x02, }, | ||
889 | { 16 * 999.99 , 0x8e, 0x04, }, | ||
890 | }; | ||
891 | |||
892 | static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { | ||
893 | { | ||
894 | .type = TUNER_PARAM_TYPE_NTSC, | ||
895 | .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges, | ||
896 | .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges), | ||
897 | }, | ||
898 | }; | ||
899 | |||
900 | /* 60-69 */ | ||
901 | /* ------------ TUNER_THOMSON_DTT761X - THOMSON ATSC ------------ */ | ||
902 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ | ||
903 | |||
904 | static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = { | ||
905 | { 16 * 145.25 /*MHz*/, 0x8e, 0x39, }, | ||
906 | { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, }, | ||
907 | { 16 * 999.99 , 0x8e, 0x3c, }, | ||
908 | }; | ||
909 | |||
910 | static struct tuner_range tuner_thomson_dtt761x_atsc_ranges[] = { | ||
911 | { 16 * 147.00 /*MHz*/, 0x8e, 0x39, }, | ||
912 | { 16 * 417.00 /*MHz*/, 0x8e, 0x3a, }, | ||
913 | { 16 * 999.99 , 0x8e, 0x3c, }, | ||
914 | }; | ||
915 | |||
916 | static struct tuner_params tuner_thomson_dtt761x_params[] = { | ||
917 | { | ||
918 | .type = TUNER_PARAM_TYPE_NTSC, | ||
919 | .ranges = tuner_thomson_dtt761x_ntsc_ranges, | ||
920 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges), | ||
921 | .has_tda9887 = 1, | ||
922 | .fm_gain_normal = 1, | ||
923 | .radio_if = 2, /* 41.3 MHz */ | ||
924 | }, | ||
925 | { | ||
926 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
927 | .ranges = tuner_thomson_dtt761x_atsc_ranges, | ||
928 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_atsc_ranges), | ||
929 | .iffreq = 16 * 44.00, /*MHz*/ | ||
930 | }, | ||
931 | }; | ||
932 | |||
933 | /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */ | ||
934 | |||
935 | static struct tuner_range tuner_tena_9533_di_pal_ranges[] = { | ||
936 | { 16 * 160.25 /*MHz*/, 0x8e, 0x01, }, | ||
937 | { 16 * 464.25 /*MHz*/, 0x8e, 0x02, }, | ||
938 | { 16 * 999.99 , 0x8e, 0x04, }, | ||
939 | }; | ||
940 | |||
941 | static struct tuner_params tuner_tena_9533_di_params[] = { | ||
942 | { | ||
943 | .type = TUNER_PARAM_TYPE_PAL, | ||
944 | .ranges = tuner_tena_9533_di_pal_ranges, | ||
945 | .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges), | ||
946 | }, | ||
947 | }; | ||
948 | |||
949 | /* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */ | ||
950 | |||
951 | static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { | ||
952 | { 16 * 160.00 /*MHz*/, 0x86, 0x51, }, | ||
953 | { 16 * 442.00 /*MHz*/, 0x86, 0x52, }, | ||
954 | { 16 * 999.99 , 0x86, 0x54, }, | ||
955 | }; | ||
956 | |||
957 | static struct tuner_range tuner_philips_fmd1216me_mk3_dvb_ranges[] = { | ||
958 | { 16 * 143.87 /*MHz*/, 0xbc, 0x41 }, | ||
959 | { 16 * 158.87 /*MHz*/, 0xf4, 0x41 }, | ||
960 | { 16 * 329.87 /*MHz*/, 0xbc, 0x42 }, | ||
961 | { 16 * 441.87 /*MHz*/, 0xf4, 0x42 }, | ||
962 | { 16 * 625.87 /*MHz*/, 0xbc, 0x44 }, | ||
963 | { 16 * 803.87 /*MHz*/, 0xf4, 0x44 }, | ||
964 | { 16 * 999.99 , 0xfc, 0x44 }, | ||
965 | }; | ||
966 | |||
967 | static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { | ||
968 | { | ||
969 | .type = TUNER_PARAM_TYPE_PAL, | ||
970 | .ranges = tuner_philips_fmd1216me_mk3_pal_ranges, | ||
971 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges), | ||
972 | .has_tda9887 = 1, | ||
973 | .port1_active = 1, | ||
974 | .port2_active = 1, | ||
975 | .port2_fm_high_sensitivity = 1, | ||
976 | .port2_invert_for_secam_lc = 1, | ||
977 | .port1_set_for_fm_mono = 1, | ||
978 | }, | ||
979 | { | ||
980 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
981 | .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges, | ||
982 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges), | ||
983 | .iffreq = 16 * 36.125, /*MHz*/ | ||
984 | }, | ||
985 | }; | ||
986 | |||
987 | |||
988 | /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */ | ||
989 | |||
990 | static struct tuner_range tuner_tua6034_ntsc_ranges[] = { | ||
991 | { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, | ||
992 | { 16 * 450.00 /*MHz*/, 0x8e, 0x02 }, | ||
993 | { 16 * 999.99 , 0x8e, 0x04 }, | ||
994 | }; | ||
995 | |||
996 | static struct tuner_range tuner_tua6034_atsc_ranges[] = { | ||
997 | { 16 * 165.00 /*MHz*/, 0xce, 0x01 }, | ||
998 | { 16 * 450.00 /*MHz*/, 0xce, 0x02 }, | ||
999 | { 16 * 999.99 , 0xce, 0x04 }, | ||
1000 | }; | ||
1001 | |||
1002 | static struct tuner_params tuner_lg_tdvs_h06xf_params[] = { | ||
1003 | { | ||
1004 | .type = TUNER_PARAM_TYPE_NTSC, | ||
1005 | .ranges = tuner_tua6034_ntsc_ranges, | ||
1006 | .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges), | ||
1007 | }, | ||
1008 | { | ||
1009 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1010 | .ranges = tuner_tua6034_atsc_ranges, | ||
1011 | .count = ARRAY_SIZE(tuner_tua6034_atsc_ranges), | ||
1012 | .iffreq = 16 * 44.00, | ||
1013 | }, | ||
1014 | }; | ||
1015 | |||
1016 | /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */ | ||
1017 | |||
1018 | static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = { | ||
1019 | { 16 * 160.25 /*MHz*/, 0x8e, 0x01, }, | ||
1020 | { 16 * 464.25 /*MHz*/, 0x8e, 0x02, }, | ||
1021 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
1022 | }; | ||
1023 | |||
1024 | static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = { | ||
1025 | { | ||
1026 | .type = TUNER_PARAM_TYPE_PAL, | ||
1027 | .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges, | ||
1028 | .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges), | ||
1029 | }, | ||
1030 | }; | ||
1031 | |||
1032 | /* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */ | ||
1033 | |||
1034 | static struct tuner_range tuner_lg_taln_ntsc_ranges[] = { | ||
1035 | { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, | ||
1036 | { 16 * 373.25 /*MHz*/, 0x8e, 0x02, }, | ||
1037 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
1038 | }; | ||
1039 | |||
1040 | static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = { | ||
1041 | { 16 * 150.00 /*MHz*/, 0x8e, 0x01, }, | ||
1042 | { 16 * 425.00 /*MHz*/, 0x8e, 0x02, }, | ||
1043 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
1044 | }; | ||
1045 | |||
1046 | static struct tuner_params tuner_lg_taln_params[] = { | ||
1047 | { | ||
1048 | .type = TUNER_PARAM_TYPE_NTSC, | ||
1049 | .ranges = tuner_lg_taln_ntsc_ranges, | ||
1050 | .count = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges), | ||
1051 | },{ | ||
1052 | .type = TUNER_PARAM_TYPE_PAL, | ||
1053 | .ranges = tuner_lg_taln_pal_secam_ranges, | ||
1054 | .count = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges), | ||
1055 | }, | ||
1056 | }; | ||
1057 | |||
1058 | /* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */ | ||
1059 | |||
1060 | static struct tuner_range tuner_philips_td1316_pal_ranges[] = { | ||
1061 | { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, }, | ||
1062 | { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, }, | ||
1063 | { 16 * 999.99 , 0xc8, 0xa4, }, | ||
1064 | }; | ||
1065 | |||
1066 | static struct tuner_range tuner_philips_td1316_dvb_ranges[] = { | ||
1067 | { 16 * 93.834 /*MHz*/, 0xca, 0x60, }, | ||
1068 | { 16 * 123.834 /*MHz*/, 0xca, 0xa0, }, | ||
1069 | { 16 * 163.834 /*MHz*/, 0xca, 0xc0, }, | ||
1070 | { 16 * 253.834 /*MHz*/, 0xca, 0x60, }, | ||
1071 | { 16 * 383.834 /*MHz*/, 0xca, 0xa0, }, | ||
1072 | { 16 * 443.834 /*MHz*/, 0xca, 0xc0, }, | ||
1073 | { 16 * 583.834 /*MHz*/, 0xca, 0x60, }, | ||
1074 | { 16 * 793.834 /*MHz*/, 0xca, 0xa0, }, | ||
1075 | { 16 * 999.999 , 0xca, 0xe0, }, | ||
1076 | }; | ||
1077 | |||
1078 | static struct tuner_params tuner_philips_td1316_params[] = { | ||
1079 | { | ||
1080 | .type = TUNER_PARAM_TYPE_PAL, | ||
1081 | .ranges = tuner_philips_td1316_pal_ranges, | ||
1082 | .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges), | ||
1083 | }, | ||
1084 | { | ||
1085 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1086 | .ranges = tuner_philips_td1316_dvb_ranges, | ||
1087 | .count = ARRAY_SIZE(tuner_philips_td1316_dvb_ranges), | ||
1088 | .iffreq = 16 * 36.166667 /*MHz*/, | ||
1089 | }, | ||
1090 | }; | ||
1091 | |||
1092 | /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */ | ||
1093 | |||
1094 | static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = { | ||
1095 | { 16 * 157.25 /*MHz*/, 0xce, 0x01, }, | ||
1096 | { 16 * 454.00 /*MHz*/, 0xce, 0x02, }, | ||
1097 | { 16 * 999.99 , 0xce, 0x04, }, | ||
1098 | }; | ||
1099 | |||
1100 | static struct tuner_range tuner_tuv1236d_atsc_ranges[] = { | ||
1101 | { 16 * 157.25 /*MHz*/, 0xc6, 0x41, }, | ||
1102 | { 16 * 454.00 /*MHz*/, 0xc6, 0x42, }, | ||
1103 | { 16 * 999.99 , 0xc6, 0x44, }, | ||
1104 | }; | ||
1105 | |||
1106 | static struct tuner_params tuner_tuv1236d_params[] = { | ||
1107 | { | ||
1108 | .type = TUNER_PARAM_TYPE_NTSC, | ||
1109 | .ranges = tuner_tuv1236d_ntsc_ranges, | ||
1110 | .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges), | ||
1111 | }, | ||
1112 | { | ||
1113 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1114 | .ranges = tuner_tuv1236d_atsc_ranges, | ||
1115 | .count = ARRAY_SIZE(tuner_tuv1236d_atsc_ranges), | ||
1116 | .iffreq = 16 * 44.00, | ||
1117 | }, | ||
1118 | }; | ||
1119 | |||
1120 | /* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */ | ||
1121 | /* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF | ||
1122 | * but it is expected to work also with other Tenna/Ymec | ||
1123 | * models based on TI SN 761677 chip on both PAL and NTSC | ||
1124 | */ | ||
1125 | |||
1126 | static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = { | ||
1127 | { 16 * 168.25 /*MHz*/, 0x8e, 0x01, }, | ||
1128 | { 16 * 471.25 /*MHz*/, 0x8e, 0x02, }, | ||
1129 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
1130 | }; | ||
1131 | |||
1132 | static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = { | ||
1133 | { 16 * 169.25 /*MHz*/, 0x8e, 0x01, }, | ||
1134 | { 16 * 469.25 /*MHz*/, 0x8e, 0x02, }, | ||
1135 | { 16 * 999.99 , 0x8e, 0x08, }, | ||
1136 | }; | ||
1137 | |||
1138 | static struct tuner_params tuner_tnf_5335mf_params[] = { | ||
1139 | { | ||
1140 | .type = TUNER_PARAM_TYPE_NTSC, | ||
1141 | .ranges = tuner_tnf_5335mf_ntsc_ranges, | ||
1142 | .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges), | ||
1143 | }, | ||
1144 | { | ||
1145 | .type = TUNER_PARAM_TYPE_PAL, | ||
1146 | .ranges = tuner_tnf_5335_d_if_pal_ranges, | ||
1147 | .count = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges), | ||
1148 | }, | ||
1149 | }; | ||
1150 | |||
1151 | /* 70-79 */ | ||
1152 | /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ | ||
1153 | |||
1154 | /* '+ 4' turns on the Low Noise Amplifier */ | ||
1155 | static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { | ||
1156 | { 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, }, | ||
1157 | { 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, }, | ||
1158 | { 16 * 999.99 , 0xce, 0x08 + 4, }, | ||
1159 | }; | ||
1160 | |||
1161 | static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { | ||
1162 | { | ||
1163 | .type = TUNER_PARAM_TYPE_NTSC, | ||
1164 | .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, | ||
1165 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), | ||
1166 | }, | ||
1167 | }; | ||
1168 | |||
1169 | /* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */ | ||
1170 | |||
1171 | static struct tuner_range tuner_thomson_fe6600_pal_ranges[] = { | ||
1172 | { 16 * 160.00 /*MHz*/, 0xfe, 0x11, }, | ||
1173 | { 16 * 442.00 /*MHz*/, 0xf6, 0x12, }, | ||
1174 | { 16 * 999.99 , 0xf6, 0x18, }, | ||
1175 | }; | ||
1176 | |||
1177 | static struct tuner_range tuner_thomson_fe6600_dvb_ranges[] = { | ||
1178 | { 16 * 250.00 /*MHz*/, 0xb4, 0x12, }, | ||
1179 | { 16 * 455.00 /*MHz*/, 0xfe, 0x11, }, | ||
1180 | { 16 * 775.50 /*MHz*/, 0xbc, 0x18, }, | ||
1181 | { 16 * 999.99 , 0xf4, 0x18, }, | ||
1182 | }; | ||
1183 | |||
1184 | static struct tuner_params tuner_thomson_fe6600_params[] = { | ||
1185 | { | ||
1186 | .type = TUNER_PARAM_TYPE_PAL, | ||
1187 | .ranges = tuner_thomson_fe6600_pal_ranges, | ||
1188 | .count = ARRAY_SIZE(tuner_thomson_fe6600_pal_ranges), | ||
1189 | }, | ||
1190 | { | ||
1191 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1192 | .ranges = tuner_thomson_fe6600_dvb_ranges, | ||
1193 | .count = ARRAY_SIZE(tuner_thomson_fe6600_dvb_ranges), | ||
1194 | .iffreq = 16 * 36.125 /*MHz*/, | ||
1195 | }, | ||
1196 | }; | ||
1197 | |||
1198 | /* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */ | ||
1199 | |||
1200 | /* '+ 4' turns on the Low Noise Amplifier */ | ||
1201 | static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = { | ||
1202 | { 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, }, | ||
1203 | { 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, }, | ||
1204 | { 16 * 999.99 , 0xce, 0x08 + 4, }, | ||
1205 | }; | ||
1206 | |||
1207 | static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = { | ||
1208 | { | ||
1209 | .type = TUNER_PARAM_TYPE_PAL, | ||
1210 | .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges, | ||
1211 | .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges), | ||
1212 | .has_tda9887 = 1, | ||
1213 | .port1_active = 1, | ||
1214 | .port2_active = 1, | ||
1215 | .port2_invert_for_secam_lc = 1, | ||
1216 | }, | ||
1217 | }; | ||
1218 | |||
1219 | /* --------------------------------------------------------------------- */ | ||
1220 | |||
1221 | struct tunertype tuners[] = { | ||
1222 | /* 0-9 */ | ||
1223 | [TUNER_TEMIC_PAL] = { /* TEMIC PAL */ | ||
1224 | .name = "Temic PAL (4002 FH5)", | ||
1225 | .params = tuner_temic_pal_params, | ||
1226 | .count = ARRAY_SIZE(tuner_temic_pal_params), | ||
1227 | }, | ||
1228 | [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */ | ||
1229 | .name = "Philips PAL_I (FI1246 and compatibles)", | ||
1230 | .params = tuner_philips_pal_i_params, | ||
1231 | .count = ARRAY_SIZE(tuner_philips_pal_i_params), | ||
1232 | }, | ||
1233 | [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */ | ||
1234 | .name = "Philips NTSC (FI1236,FM1236 and compatibles)", | ||
1235 | .params = tuner_philips_ntsc_params, | ||
1236 | .count = ARRAY_SIZE(tuner_philips_ntsc_params), | ||
1237 | }, | ||
1238 | [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */ | ||
1239 | .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", | ||
1240 | .params = tuner_philips_secam_params, | ||
1241 | .count = ARRAY_SIZE(tuner_philips_secam_params), | ||
1242 | }, | ||
1243 | [TUNER_ABSENT] = { /* Tuner Absent */ | ||
1244 | .name = "NoTuner", | ||
1245 | }, | ||
1246 | [TUNER_PHILIPS_PAL] = { /* Philips PAL */ | ||
1247 | .name = "Philips PAL_BG (FI1216 and compatibles)", | ||
1248 | .params = tuner_philips_pal_params, | ||
1249 | .count = ARRAY_SIZE(tuner_philips_pal_params), | ||
1250 | }, | ||
1251 | [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */ | ||
1252 | .name = "Temic NTSC (4032 FY5)", | ||
1253 | .params = tuner_temic_ntsc_params, | ||
1254 | .count = ARRAY_SIZE(tuner_temic_ntsc_params), | ||
1255 | }, | ||
1256 | [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */ | ||
1257 | .name = "Temic PAL_I (4062 FY5)", | ||
1258 | .params = tuner_temic_pal_i_params, | ||
1259 | .count = ARRAY_SIZE(tuner_temic_pal_i_params), | ||
1260 | }, | ||
1261 | [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */ | ||
1262 | .name = "Temic NTSC (4036 FY5)", | ||
1263 | .params = tuner_temic_4036fy5_ntsc_params, | ||
1264 | .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params), | ||
1265 | }, | ||
1266 | [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */ | ||
1267 | .name = "Alps HSBH1", | ||
1268 | .params = tuner_alps_tsbh1_ntsc_params, | ||
1269 | .count = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params), | ||
1270 | }, | ||
1271 | |||
1272 | /* 10-19 */ | ||
1273 | [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */ | ||
1274 | .name = "Alps TSBE1", | ||
1275 | .params = tuner_alps_tsb_1_params, | ||
1276 | .count = ARRAY_SIZE(tuner_alps_tsb_1_params), | ||
1277 | }, | ||
1278 | [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */ | ||
1279 | .name = "Alps TSBB5", | ||
1280 | .params = tuner_alps_tsbb5_params, | ||
1281 | .count = ARRAY_SIZE(tuner_alps_tsbb5_params), | ||
1282 | }, | ||
1283 | [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */ | ||
1284 | .name = "Alps TSBE5", | ||
1285 | .params = tuner_alps_tsbe5_params, | ||
1286 | .count = ARRAY_SIZE(tuner_alps_tsbe5_params), | ||
1287 | }, | ||
1288 | [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */ | ||
1289 | .name = "Alps TSBC5", | ||
1290 | .params = tuner_alps_tsbc5_params, | ||
1291 | .count = ARRAY_SIZE(tuner_alps_tsbc5_params), | ||
1292 | }, | ||
1293 | [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */ | ||
1294 | .name = "Temic PAL_BG (4006FH5)", | ||
1295 | .params = tuner_temic_4006fh5_params, | ||
1296 | .count = ARRAY_SIZE(tuner_temic_4006fh5_params), | ||
1297 | }, | ||
1298 | [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */ | ||
1299 | .name = "Alps TSCH6", | ||
1300 | .params = tuner_alps_tshc6_params, | ||
1301 | .count = ARRAY_SIZE(tuner_alps_tshc6_params), | ||
1302 | }, | ||
1303 | [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */ | ||
1304 | .name = "Temic PAL_DK (4016 FY5)", | ||
1305 | .params = tuner_temic_pal_dk_params, | ||
1306 | .count = ARRAY_SIZE(tuner_temic_pal_dk_params), | ||
1307 | }, | ||
1308 | [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */ | ||
1309 | .name = "Philips NTSC_M (MK2)", | ||
1310 | .params = tuner_philips_ntsc_m_params, | ||
1311 | .count = ARRAY_SIZE(tuner_philips_ntsc_m_params), | ||
1312 | }, | ||
1313 | [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */ | ||
1314 | .name = "Temic PAL_I (4066 FY5)", | ||
1315 | .params = tuner_temic_4066fy5_pal_i_params, | ||
1316 | .count = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params), | ||
1317 | }, | ||
1318 | [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */ | ||
1319 | .name = "Temic PAL* auto (4006 FN5)", | ||
1320 | .params = tuner_temic_4006fn5_multi_params, | ||
1321 | .count = ARRAY_SIZE(tuner_temic_4006fn5_multi_params), | ||
1322 | }, | ||
1323 | |||
1324 | /* 20-29 */ | ||
1325 | [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */ | ||
1326 | .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", | ||
1327 | .params = tuner_temic_4009f_5_params, | ||
1328 | .count = ARRAY_SIZE(tuner_temic_4009f_5_params), | ||
1329 | }, | ||
1330 | [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */ | ||
1331 | .name = "Temic NTSC (4039 FR5)", | ||
1332 | .params = tuner_temic_4039fr5_params, | ||
1333 | .count = ARRAY_SIZE(tuner_temic_4039fr5_params), | ||
1334 | }, | ||
1335 | [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */ | ||
1336 | .name = "Temic PAL/SECAM multi (4046 FM5)", | ||
1337 | .params = tuner_temic_4046fm5_params, | ||
1338 | .count = ARRAY_SIZE(tuner_temic_4046fm5_params), | ||
1339 | }, | ||
1340 | [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */ | ||
1341 | .name = "Philips PAL_DK (FI1256 and compatibles)", | ||
1342 | .params = tuner_philips_pal_dk_params, | ||
1343 | .count = ARRAY_SIZE(tuner_philips_pal_dk_params), | ||
1344 | }, | ||
1345 | [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */ | ||
1346 | .name = "Philips PAL/SECAM multi (FQ1216ME)", | ||
1347 | .params = tuner_philips_fq1216me_params, | ||
1348 | .count = ARRAY_SIZE(tuner_philips_fq1216me_params), | ||
1349 | }, | ||
1350 | [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */ | ||
1351 | .name = "LG PAL_I+FM (TAPC-I001D)", | ||
1352 | .params = tuner_lg_pal_i_fm_params, | ||
1353 | .count = ARRAY_SIZE(tuner_lg_pal_i_fm_params), | ||
1354 | }, | ||
1355 | [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */ | ||
1356 | .name = "LG PAL_I (TAPC-I701D)", | ||
1357 | .params = tuner_lg_pal_i_params, | ||
1358 | .count = ARRAY_SIZE(tuner_lg_pal_i_params), | ||
1359 | }, | ||
1360 | [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */ | ||
1361 | .name = "LG NTSC+FM (TPI8NSR01F)", | ||
1362 | .params = tuner_lg_ntsc_fm_params, | ||
1363 | .count = ARRAY_SIZE(tuner_lg_ntsc_fm_params), | ||
1364 | }, | ||
1365 | [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */ | ||
1366 | .name = "LG PAL_BG+FM (TPI8PSB01D)", | ||
1367 | .params = tuner_lg_pal_fm_params, | ||
1368 | .count = ARRAY_SIZE(tuner_lg_pal_fm_params), | ||
1369 | }, | ||
1370 | [TUNER_LG_PAL] = { /* LGINNOTEK PAL */ | ||
1371 | .name = "LG PAL_BG (TPI8PSB11D)", | ||
1372 | .params = tuner_lg_pal_params, | ||
1373 | .count = ARRAY_SIZE(tuner_lg_pal_params), | ||
1374 | }, | ||
1375 | |||
1376 | /* 30-39 */ | ||
1377 | [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */ | ||
1378 | .name = "Temic PAL* auto + FM (4009 FN5)", | ||
1379 | .params = tuner_temic_4009_fn5_multi_pal_fm_params, | ||
1380 | .count = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params), | ||
1381 | }, | ||
1382 | [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */ | ||
1383 | .name = "SHARP NTSC_JP (2U5JF5540)", | ||
1384 | .params = tuner_sharp_2u5jf5540_params, | ||
1385 | .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_params), | ||
1386 | }, | ||
1387 | [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */ | ||
1388 | .name = "Samsung PAL TCPM9091PD27", | ||
1389 | .params = tuner_samsung_pal_tcpm9091pd27_params, | ||
1390 | .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params), | ||
1391 | }, | ||
1392 | [TUNER_MT2032] = { /* Microtune PAL|NTSC */ | ||
1393 | .name = "MT20xx universal", | ||
1394 | /* see mt20xx.c for details */ }, | ||
1395 | [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */ | ||
1396 | .name = "Temic PAL_BG (4106 FH5)", | ||
1397 | .params = tuner_temic_4106fh5_params, | ||
1398 | .count = ARRAY_SIZE(tuner_temic_4106fh5_params), | ||
1399 | }, | ||
1400 | [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */ | ||
1401 | .name = "Temic PAL_DK/SECAM_L (4012 FY5)", | ||
1402 | .params = tuner_temic_4012fy5_params, | ||
1403 | .count = ARRAY_SIZE(tuner_temic_4012fy5_params), | ||
1404 | }, | ||
1405 | [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */ | ||
1406 | .name = "Temic NTSC (4136 FY5)", | ||
1407 | .params = tuner_temic_4136_fy5_params, | ||
1408 | .count = ARRAY_SIZE(tuner_temic_4136_fy5_params), | ||
1409 | }, | ||
1410 | [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */ | ||
1411 | .name = "LG PAL (newer TAPC series)", | ||
1412 | .params = tuner_lg_pal_new_tapc_params, | ||
1413 | .count = ARRAY_SIZE(tuner_lg_pal_new_tapc_params), | ||
1414 | }, | ||
1415 | [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */ | ||
1416 | .name = "Philips PAL/SECAM multi (FM1216ME MK3)", | ||
1417 | .params = tuner_fm1216me_mk3_params, | ||
1418 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_params), | ||
1419 | }, | ||
1420 | [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */ | ||
1421 | .name = "LG NTSC (newer TAPC series)", | ||
1422 | .params = tuner_lg_ntsc_new_tapc_params, | ||
1423 | .count = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params), | ||
1424 | }, | ||
1425 | |||
1426 | /* 40-49 */ | ||
1427 | [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */ | ||
1428 | .name = "HITACHI V7-J180AT", | ||
1429 | .params = tuner_hitachi_ntsc_params, | ||
1430 | .count = ARRAY_SIZE(tuner_hitachi_ntsc_params), | ||
1431 | }, | ||
1432 | [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */ | ||
1433 | .name = "Philips PAL_MK (FI1216 MK)", | ||
1434 | .params = tuner_philips_pal_mk_params, | ||
1435 | .count = ARRAY_SIZE(tuner_philips_pal_mk_params), | ||
1436 | }, | ||
1437 | [TUNER_PHILIPS_FCV1236D] = { /* Philips ATSC */ | ||
1438 | .name = "Philips FCV1236D ATSC/NTSC dual in", | ||
1439 | .params = tuner_philips_fcv1236d_params, | ||
1440 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_params), | ||
1441 | .min = 16 * 53.00, | ||
1442 | .max = 16 * 803.00, | ||
1443 | .stepsize = 62500, | ||
1444 | }, | ||
1445 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ | ||
1446 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", | ||
1447 | .params = tuner_fm1236_mk3_params, | ||
1448 | .count = ARRAY_SIZE(tuner_fm1236_mk3_params), | ||
1449 | }, | ||
1450 | [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */ | ||
1451 | .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", | ||
1452 | .params = tuner_philips_4in1_params, | ||
1453 | .count = ARRAY_SIZE(tuner_philips_4in1_params), | ||
1454 | }, | ||
1455 | [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */ | ||
1456 | .name = "Microtune 4049 FM5", | ||
1457 | .params = tuner_microtune_4049_fm5_params, | ||
1458 | .count = ARRAY_SIZE(tuner_microtune_4049_fm5_params), | ||
1459 | }, | ||
1460 | [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */ | ||
1461 | .name = "Panasonic VP27s/ENGE4324D", | ||
1462 | .params = tuner_panasonic_vp27_params, | ||
1463 | .count = ARRAY_SIZE(tuner_panasonic_vp27_params), | ||
1464 | }, | ||
1465 | [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ | ||
1466 | .name = "LG NTSC (TAPE series)", | ||
1467 | .params = tuner_fm1236_mk3_params, | ||
1468 | .count = ARRAY_SIZE(tuner_fm1236_mk3_params), | ||
1469 | }, | ||
1470 | [TUNER_TNF_8831BGFF] = { /* Philips PAL */ | ||
1471 | .name = "Tenna TNF 8831 BGFF)", | ||
1472 | .params = tuner_tnf_8831bgff_params, | ||
1473 | .count = ARRAY_SIZE(tuner_tnf_8831bgff_params), | ||
1474 | }, | ||
1475 | [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */ | ||
1476 | .name = "Microtune 4042 FI5 ATSC/NTSC dual in", | ||
1477 | .params = tuner_microtune_4042fi5_params, | ||
1478 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_params), | ||
1479 | .min = 16 * 57.00, | ||
1480 | .max = 16 * 858.00, | ||
1481 | .stepsize = 62500, | ||
1482 | }, | ||
1483 | |||
1484 | /* 50-59 */ | ||
1485 | [TUNER_TCL_2002N] = { /* TCL NTSC */ | ||
1486 | .name = "TCL 2002N", | ||
1487 | .params = tuner_tcl_2002n_params, | ||
1488 | .count = ARRAY_SIZE(tuner_tcl_2002n_params), | ||
1489 | }, | ||
1490 | [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */ | ||
1491 | .name = "Philips PAL/SECAM_D (FM 1256 I-H3)", | ||
1492 | .params = tuner_philips_fm1256_ih3_params, | ||
1493 | .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_params), | ||
1494 | }, | ||
1495 | [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */ | ||
1496 | .name = "Thomson DTT 7610 (ATSC/NTSC)", | ||
1497 | .params = tuner_thomson_dtt7610_params, | ||
1498 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_params), | ||
1499 | .min = 16 * 44.00, | ||
1500 | .max = 16 * 958.00, | ||
1501 | .stepsize = 62500, | ||
1502 | }, | ||
1503 | [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ | ||
1504 | .name = "Philips FQ1286", | ||
1505 | .params = tuner_philips_fq1286_params, | ||
1506 | .count = ARRAY_SIZE(tuner_philips_fq1286_params), | ||
1507 | }, | ||
1508 | [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ | ||
1509 | .name = "Philips/NXP TDA 8290/8295 + 8275/8275A/18271", | ||
1510 | /* see tda8290.c for details */ }, | ||
1511 | [TUNER_TCL_2002MB] = { /* TCL PAL */ | ||
1512 | .name = "TCL 2002MB", | ||
1513 | .params = tuner_tcl_2002mb_params, | ||
1514 | .count = ARRAY_SIZE(tuner_tcl_2002mb_params), | ||
1515 | }, | ||
1516 | [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */ | ||
1517 | .name = "Philips PAL/SECAM multi (FQ1216AME MK4)", | ||
1518 | .params = tuner_philips_fq1216ame_mk4_params, | ||
1519 | .count = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params), | ||
1520 | }, | ||
1521 | [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */ | ||
1522 | .name = "Philips FQ1236A MK4", | ||
1523 | .params = tuner_philips_fq1236a_mk4_params, | ||
1524 | .count = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params), | ||
1525 | }, | ||
1526 | [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */ | ||
1527 | .name = "Ymec TVision TVF-8531MF/8831MF/8731MF", | ||
1528 | .params = tuner_ymec_tvf_8531mf_params, | ||
1529 | .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params), | ||
1530 | }, | ||
1531 | [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */ | ||
1532 | .name = "Ymec TVision TVF-5533MF", | ||
1533 | .params = tuner_ymec_tvf_5533mf_params, | ||
1534 | .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params), | ||
1535 | }, | ||
1536 | |||
1537 | /* 60-69 */ | ||
1538 | [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */ | ||
1539 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ | ||
1540 | .name = "Thomson DTT 761X (ATSC/NTSC)", | ||
1541 | .params = tuner_thomson_dtt761x_params, | ||
1542 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_params), | ||
1543 | .min = 16 * 57.00, | ||
1544 | .max = 16 * 863.00, | ||
1545 | .stepsize = 62500, | ||
1546 | .initdata = tua603x_agc103, | ||
1547 | }, | ||
1548 | [TUNER_TENA_9533_DI] = { /* Philips PAL */ | ||
1549 | .name = "Tena TNF9533-D/IF/TNF9533-B/DF", | ||
1550 | .params = tuner_tena_9533_di_params, | ||
1551 | .count = ARRAY_SIZE(tuner_tena_9533_di_params), | ||
1552 | }, | ||
1553 | [TUNER_TEA5767] = { /* Philips RADIO */ | ||
1554 | .name = "Philips TEA5767HN FM Radio", | ||
1555 | /* see tea5767.c for details */ | ||
1556 | }, | ||
1557 | [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */ | ||
1558 | .name = "Philips FMD1216ME MK3 Hybrid Tuner", | ||
1559 | .params = tuner_philips_fmd1216me_mk3_params, | ||
1560 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), | ||
1561 | .min = 16 * 50.87, | ||
1562 | .max = 16 * 858.00, | ||
1563 | .stepsize = 166667, | ||
1564 | .initdata = tua603x_agc112, | ||
1565 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, | ||
1566 | }, | ||
1567 | [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */ | ||
1568 | .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */ | ||
1569 | .params = tuner_lg_tdvs_h06xf_params, | ||
1570 | .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params), | ||
1571 | .min = 16 * 54.00, | ||
1572 | .max = 16 * 863.00, | ||
1573 | .stepsize = 62500, | ||
1574 | .initdata = tua603x_agc103, | ||
1575 | }, | ||
1576 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ | ||
1577 | .name = "Ymec TVF66T5-B/DFF", | ||
1578 | .params = tuner_ymec_tvf66t5_b_dff_params, | ||
1579 | .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params), | ||
1580 | }, | ||
1581 | [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */ | ||
1582 | .name = "LG TALN series", | ||
1583 | .params = tuner_lg_taln_params, | ||
1584 | .count = ARRAY_SIZE(tuner_lg_taln_params), | ||
1585 | }, | ||
1586 | [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ | ||
1587 | .name = "Philips TD1316 Hybrid Tuner", | ||
1588 | .params = tuner_philips_td1316_params, | ||
1589 | .count = ARRAY_SIZE(tuner_philips_td1316_params), | ||
1590 | .min = 16 * 87.00, | ||
1591 | .max = 16 * 895.00, | ||
1592 | .stepsize = 166667, | ||
1593 | }, | ||
1594 | [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ | ||
1595 | .name = "Philips TUV1236D ATSC/NTSC dual in", | ||
1596 | .params = tuner_tuv1236d_params, | ||
1597 | .count = ARRAY_SIZE(tuner_tuv1236d_params), | ||
1598 | .min = 16 * 54.00, | ||
1599 | .max = 16 * 864.00, | ||
1600 | .stepsize = 62500, | ||
1601 | }, | ||
1602 | [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */ | ||
1603 | .name = "Tena TNF 5335 and similar models", | ||
1604 | .params = tuner_tnf_5335mf_params, | ||
1605 | .count = ARRAY_SIZE(tuner_tnf_5335mf_params), | ||
1606 | }, | ||
1607 | |||
1608 | /* 70-79 */ | ||
1609 | [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */ | ||
1610 | .name = "Samsung TCPN 2121P30A", | ||
1611 | .params = tuner_samsung_tcpn_2121p30a_params, | ||
1612 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params), | ||
1613 | }, | ||
1614 | [TUNER_XC2028] = { /* Xceive 2028 */ | ||
1615 | .name = "Xceive xc2028/xc3028 tuner", | ||
1616 | /* see tuner-xc2028.c for details */ | ||
1617 | }, | ||
1618 | [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */ | ||
1619 | .name = "Thomson FE6600", | ||
1620 | .params = tuner_thomson_fe6600_params, | ||
1621 | .count = ARRAY_SIZE(tuner_thomson_fe6600_params), | ||
1622 | .min = 16 * 44.25, | ||
1623 | .max = 16 * 858.00, | ||
1624 | .stepsize = 166667, | ||
1625 | }, | ||
1626 | [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */ | ||
1627 | .name = "Samsung TCPG 6121P30A", | ||
1628 | .params = tuner_samsung_tcpg_6121p30a_params, | ||
1629 | .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params), | ||
1630 | }, | ||
1631 | [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator. | ||
1632 | This chip is part of some modern tuners */ | ||
1633 | .name = "Philips TDA988[5,6,7] IF PLL Demodulator", | ||
1634 | /* see tda9887.c for details */ | ||
1635 | }, | ||
1636 | [TUNER_TEA5761] = { /* Philips RADIO */ | ||
1637 | .name = "Philips TEA5761 FM Radio", | ||
1638 | /* see tea5767.c for details */ | ||
1639 | }, | ||
1640 | [TUNER_XC5000] = { /* Xceive 5000 */ | ||
1641 | .name = "Xceive 5000 tuner", | ||
1642 | /* see xc5000.c for details */ | ||
1643 | }, | ||
1644 | }; | ||
1645 | EXPORT_SYMBOL(tuners); | ||
1646 | |||
1647 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | ||
1648 | EXPORT_SYMBOL(tuner_count); | ||
1649 | |||
1650 | MODULE_DESCRIPTION("Simple tuner device type database"); | ||
1651 | MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | ||
1652 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tuner-xc2028-types.h b/drivers/media/video/tuner-xc2028-types.h deleted file mode 100644 index 74dc46a71f64..000000000000 --- a/drivers/media/video/tuner-xc2028-types.h +++ /dev/null | |||
@@ -1,141 +0,0 @@ | |||
1 | /* tuner-xc2028_types | ||
2 | * | ||
3 | * This file includes internal tipes to be used inside tuner-xc2028. | ||
4 | * Shouldn't be included outside tuner-xc2028 | ||
5 | * | ||
6 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
7 | * This code is placed under the terms of the GNU General Public License v2 | ||
8 | */ | ||
9 | |||
10 | /* xc3028 firmware types */ | ||
11 | |||
12 | /* BASE firmware should be loaded before any other firmware */ | ||
13 | #define BASE (1<<0) | ||
14 | #define BASE_TYPES (BASE|F8MHZ|MTS|FM|INPUT1|INPUT2|INIT1) | ||
15 | |||
16 | /* F8MHZ marks BASE firmwares for 8 MHz Bandwidth */ | ||
17 | #define F8MHZ (1<<1) | ||
18 | |||
19 | /* Multichannel Television Sound (MTS) | ||
20 | Those firmwares are capable of using xc2038 DSP to decode audio and | ||
21 | produce a baseband audio output on some pins of the chip. | ||
22 | There are MTS firmwares for the most used video standards. It should be | ||
23 | required to use MTS firmwares, depending on the way audio is routed into | ||
24 | the bridge chip | ||
25 | */ | ||
26 | #define MTS (1<<2) | ||
27 | |||
28 | /* FIXME: I have no idea what's the difference between | ||
29 | D2620 and D2633 firmwares | ||
30 | */ | ||
31 | #define D2620 (1<<3) | ||
32 | #define D2633 (1<<4) | ||
33 | |||
34 | /* DTV firmwares for 6, 7 and 8 MHz | ||
35 | DTV6 - 6MHz - ATSC/DVB-C/DVB-T/ISDB-T/DOCSIS | ||
36 | DTV8 - 8MHz - DVB-C/DVB-T | ||
37 | */ | ||
38 | #define DTV6 (1 << 5) | ||
39 | #define QAM (1 << 6) | ||
40 | #define DTV7 (1<<7) | ||
41 | #define DTV78 (1<<8) | ||
42 | #define DTV8 (1<<9) | ||
43 | |||
44 | #define DTV_TYPES (D2620|D2633|DTV6|QAM|DTV7|DTV78|DTV8|ATSC) | ||
45 | |||
46 | /* There's a FM | BASE firmware + FM specific firmware (std=0) */ | ||
47 | #define FM (1<<10) | ||
48 | |||
49 | #define STD_SPECIFIC_TYPES (MTS|FM|LCD|NOGD) | ||
50 | |||
51 | /* Applies only for FM firmware | ||
52 | Makes it use RF input 1 (pin #2) instead of input 2 (pin #4) | ||
53 | */ | ||
54 | #define INPUT1 (1<<11) | ||
55 | |||
56 | |||
57 | /* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M) | ||
58 | and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr) | ||
59 | There are variants both with and without NOGD | ||
60 | Those firmwares produce better result with LCD displays | ||
61 | */ | ||
62 | #define LCD (1<<12) | ||
63 | |||
64 | /* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M) | ||
65 | and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr) | ||
66 | The NOGD firmwares don't have group delay compensation filter | ||
67 | */ | ||
68 | #define NOGD (1<<13) | ||
69 | |||
70 | /* Old firmwares were broken into init0 and init1 */ | ||
71 | #define INIT1 (1<<14) | ||
72 | |||
73 | /* SCODE firmware selects particular behaviours */ | ||
74 | #define MONO (1 << 15) | ||
75 | #define ATSC (1 << 16) | ||
76 | #define IF (1 << 17) | ||
77 | #define LG60 (1 << 18) | ||
78 | #define ATI638 (1 << 19) | ||
79 | #define OREN538 (1 << 20) | ||
80 | #define OREN36 (1 << 21) | ||
81 | #define TOYOTA388 (1 << 22) | ||
82 | #define TOYOTA794 (1 << 23) | ||
83 | #define DIBCOM52 (1 << 24) | ||
84 | #define ZARLINK456 (1 << 25) | ||
85 | #define CHINA (1 << 26) | ||
86 | #define F6MHZ (1 << 27) | ||
87 | #define INPUT2 (1 << 28) | ||
88 | #define SCODE (1 << 29) | ||
89 | |||
90 | /* This flag identifies that the scode table has a new format */ | ||
91 | #define HAS_IF (1 << 30) | ||
92 | |||
93 | /* There are different scode tables for MTS and non-MTS. | ||
94 | The MTS firmwares support mono only | ||
95 | */ | ||
96 | #define SCODE_TYPES (SCODE | MTS) | ||
97 | |||
98 | |||
99 | /* Newer types not defined on videodev2.h. | ||
100 | The original idea were to move all those types to videodev2.h, but | ||
101 | it seemed overkill, since, with the exception of SECAM/K3, the other | ||
102 | types seem to be autodetected. | ||
103 | It is not clear where secam/k3 is used, nor we have a feedback of this | ||
104 | working or being autodetected by the standard secam firmware. | ||
105 | */ | ||
106 | |||
107 | #define V4L2_STD_SECAM_K3 (0x04000000) | ||
108 | |||
109 | /* Audio types */ | ||
110 | |||
111 | #define V4L2_STD_A2_A (1LL<<32) | ||
112 | #define V4L2_STD_A2_B (1LL<<33) | ||
113 | #define V4L2_STD_NICAM_A (1LL<<34) | ||
114 | #define V4L2_STD_NICAM_B (1LL<<35) | ||
115 | #define V4L2_STD_AM (1LL<<36) | ||
116 | #define V4L2_STD_BTSC (1LL<<37) | ||
117 | #define V4L2_STD_EIAJ (1LL<<38) | ||
118 | |||
119 | #define V4L2_STD_A2 (V4L2_STD_A2_A | V4L2_STD_A2_B) | ||
120 | #define V4L2_STD_NICAM (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B) | ||
121 | |||
122 | /* To preserve backward compatibilty, | ||
123 | (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported | ||
124 | */ | ||
125 | |||
126 | #define V4L2_STD_AUDIO (V4L2_STD_A2 | \ | ||
127 | V4L2_STD_NICAM | \ | ||
128 | V4L2_STD_AM | \ | ||
129 | V4L2_STD_BTSC | \ | ||
130 | V4L2_STD_EIAJ) | ||
131 | |||
132 | /* Used standards with audio restrictions */ | ||
133 | |||
134 | #define V4L2_STD_PAL_BG_A2_A (V4L2_STD_PAL_BG | V4L2_STD_A2_A) | ||
135 | #define V4L2_STD_PAL_BG_A2_B (V4L2_STD_PAL_BG | V4L2_STD_A2_B) | ||
136 | #define V4L2_STD_PAL_BG_NICAM_A (V4L2_STD_PAL_BG | V4L2_STD_NICAM_A) | ||
137 | #define V4L2_STD_PAL_BG_NICAM_B (V4L2_STD_PAL_BG | V4L2_STD_NICAM_B) | ||
138 | #define V4L2_STD_PAL_DK_A2 (V4L2_STD_PAL_DK | V4L2_STD_A2) | ||
139 | #define V4L2_STD_PAL_DK_NICAM (V4L2_STD_PAL_DK | V4L2_STD_NICAM) | ||
140 | #define V4L2_STD_SECAM_L_NICAM (V4L2_STD_SECAM_L | V4L2_STD_NICAM) | ||
141 | #define V4L2_STD_SECAM_L_AM (V4L2_STD_SECAM_L | V4L2_STD_AM) | ||
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c deleted file mode 100644 index 9e9003cffc7f..000000000000 --- a/drivers/media/video/tuner-xc2028.c +++ /dev/null | |||
@@ -1,1227 +0,0 @@ | |||
1 | /* tuner-xc2028 | ||
2 | * | ||
3 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
4 | * | ||
5 | * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) | ||
6 | * - frontend interface | ||
7 | * | ||
8 | * This code is placed under the terms of the GNU General Public License v2 | ||
9 | */ | ||
10 | |||
11 | #include <linux/i2c.h> | ||
12 | #include <asm/div64.h> | ||
13 | #include <linux/firmware.h> | ||
14 | #include <linux/videodev2.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <media/tuner.h> | ||
17 | #include <linux/mutex.h> | ||
18 | #include "tuner-i2c.h" | ||
19 | #include "tuner-xc2028.h" | ||
20 | #include "tuner-xc2028-types.h" | ||
21 | |||
22 | #include <linux/dvb/frontend.h> | ||
23 | #include "dvb_frontend.h" | ||
24 | |||
25 | |||
26 | static int debug; | ||
27 | module_param(debug, int, 0644); | ||
28 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
29 | |||
30 | static char audio_std[8]; | ||
31 | module_param_string(audio_std, audio_std, sizeof(audio_std), 0); | ||
32 | MODULE_PARM_DESC(audio_std, | ||
33 | "Audio standard. XC3028 audio decoder explicitly " | ||
34 | "needs to know what audio\n" | ||
35 | "standard is needed for some video standards with audio A2 or NICAM.\n" | ||
36 | "The valid values are:\n" | ||
37 | "A2\n" | ||
38 | "A2/A\n" | ||
39 | "A2/B\n" | ||
40 | "NICAM\n" | ||
41 | "NICAM/A\n" | ||
42 | "NICAM/B\n"); | ||
43 | |||
44 | static char firmware_name[FIRMWARE_NAME_MAX]; | ||
45 | module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); | ||
46 | MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " | ||
47 | "default firmware name\n"); | ||
48 | |||
49 | static LIST_HEAD(xc2028_list); | ||
50 | static DEFINE_MUTEX(xc2028_list_mutex); | ||
51 | |||
52 | /* struct for storing firmware table */ | ||
53 | struct firmware_description { | ||
54 | unsigned int type; | ||
55 | v4l2_std_id id; | ||
56 | __u16 int_freq; | ||
57 | unsigned char *ptr; | ||
58 | unsigned int size; | ||
59 | }; | ||
60 | |||
61 | struct firmware_properties { | ||
62 | unsigned int type; | ||
63 | v4l2_std_id id; | ||
64 | v4l2_std_id std_req; | ||
65 | __u16 int_freq; | ||
66 | unsigned int scode_table; | ||
67 | int scode_nr; | ||
68 | }; | ||
69 | |||
70 | struct xc2028_data { | ||
71 | struct list_head xc2028_list; | ||
72 | struct tuner_i2c_props i2c_props; | ||
73 | int (*tuner_callback) (void *dev, | ||
74 | int command, int arg); | ||
75 | void *video_dev; | ||
76 | int count; | ||
77 | __u32 frequency; | ||
78 | |||
79 | struct firmware_description *firm; | ||
80 | int firm_size; | ||
81 | __u16 firm_version; | ||
82 | |||
83 | __u16 hwmodel; | ||
84 | __u16 hwvers; | ||
85 | |||
86 | struct xc2028_ctrl ctrl; | ||
87 | |||
88 | struct firmware_properties cur_fw; | ||
89 | |||
90 | struct mutex lock; | ||
91 | }; | ||
92 | |||
93 | #define i2c_send(priv, buf, size) ({ \ | ||
94 | int _rc; \ | ||
95 | _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \ | ||
96 | if (size != _rc) \ | ||
97 | tuner_info("i2c output error: rc = %d (should be %d)\n",\ | ||
98 | _rc, (int)size); \ | ||
99 | _rc; \ | ||
100 | }) | ||
101 | |||
102 | #define i2c_rcv(priv, buf, size) ({ \ | ||
103 | int _rc; \ | ||
104 | _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \ | ||
105 | if (size != _rc) \ | ||
106 | tuner_err("i2c input error: rc = %d (should be %d)\n", \ | ||
107 | _rc, (int)size); \ | ||
108 | _rc; \ | ||
109 | }) | ||
110 | |||
111 | #define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({ \ | ||
112 | int _rc; \ | ||
113 | _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize, \ | ||
114 | ibuf, isize); \ | ||
115 | if (isize != _rc) \ | ||
116 | tuner_err("i2c input error: rc = %d (should be %d)\n", \ | ||
117 | _rc, (int)isize); \ | ||
118 | _rc; \ | ||
119 | }) | ||
120 | |||
121 | #define send_seq(priv, data...) ({ \ | ||
122 | static u8 _val[] = data; \ | ||
123 | int _rc; \ | ||
124 | if (sizeof(_val) != \ | ||
125 | (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \ | ||
126 | _val, sizeof(_val)))) { \ | ||
127 | tuner_err("Error on line %d: %d\n", __LINE__, _rc); \ | ||
128 | } else \ | ||
129 | msleep(10); \ | ||
130 | _rc; \ | ||
131 | }) | ||
132 | |||
133 | static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) | ||
134 | { | ||
135 | unsigned char buf[2]; | ||
136 | unsigned char ibuf[2]; | ||
137 | |||
138 | tuner_dbg("%s %04x called\n", __func__, reg); | ||
139 | |||
140 | buf[0] = reg >> 8; | ||
141 | buf[1] = (unsigned char) reg; | ||
142 | |||
143 | if (i2c_send_recv(priv, buf, 2, ibuf, 2) != 2) | ||
144 | return -EIO; | ||
145 | |||
146 | *val = (ibuf[1]) | (ibuf[0] << 8); | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | #define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) | ||
151 | static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) | ||
152 | { | ||
153 | if (type & BASE) | ||
154 | printk("BASE "); | ||
155 | if (type & INIT1) | ||
156 | printk("INIT1 "); | ||
157 | if (type & F8MHZ) | ||
158 | printk("F8MHZ "); | ||
159 | if (type & MTS) | ||
160 | printk("MTS "); | ||
161 | if (type & D2620) | ||
162 | printk("D2620 "); | ||
163 | if (type & D2633) | ||
164 | printk("D2633 "); | ||
165 | if (type & DTV6) | ||
166 | printk("DTV6 "); | ||
167 | if (type & QAM) | ||
168 | printk("QAM "); | ||
169 | if (type & DTV7) | ||
170 | printk("DTV7 "); | ||
171 | if (type & DTV78) | ||
172 | printk("DTV78 "); | ||
173 | if (type & DTV8) | ||
174 | printk("DTV8 "); | ||
175 | if (type & FM) | ||
176 | printk("FM "); | ||
177 | if (type & INPUT1) | ||
178 | printk("INPUT1 "); | ||
179 | if (type & LCD) | ||
180 | printk("LCD "); | ||
181 | if (type & NOGD) | ||
182 | printk("NOGD "); | ||
183 | if (type & MONO) | ||
184 | printk("MONO "); | ||
185 | if (type & ATSC) | ||
186 | printk("ATSC "); | ||
187 | if (type & IF) | ||
188 | printk("IF "); | ||
189 | if (type & LG60) | ||
190 | printk("LG60 "); | ||
191 | if (type & ATI638) | ||
192 | printk("ATI638 "); | ||
193 | if (type & OREN538) | ||
194 | printk("OREN538 "); | ||
195 | if (type & OREN36) | ||
196 | printk("OREN36 "); | ||
197 | if (type & TOYOTA388) | ||
198 | printk("TOYOTA388 "); | ||
199 | if (type & TOYOTA794) | ||
200 | printk("TOYOTA794 "); | ||
201 | if (type & DIBCOM52) | ||
202 | printk("DIBCOM52 "); | ||
203 | if (type & ZARLINK456) | ||
204 | printk("ZARLINK456 "); | ||
205 | if (type & CHINA) | ||
206 | printk("CHINA "); | ||
207 | if (type & F6MHZ) | ||
208 | printk("F6MHZ "); | ||
209 | if (type & INPUT2) | ||
210 | printk("INPUT2 "); | ||
211 | if (type & SCODE) | ||
212 | printk("SCODE "); | ||
213 | if (type & HAS_IF) | ||
214 | printk("HAS_IF_%d ", int_freq); | ||
215 | } | ||
216 | |||
217 | static v4l2_std_id parse_audio_std_option(void) | ||
218 | { | ||
219 | if (strcasecmp(audio_std, "A2") == 0) | ||
220 | return V4L2_STD_A2; | ||
221 | if (strcasecmp(audio_std, "A2/A") == 0) | ||
222 | return V4L2_STD_A2_A; | ||
223 | if (strcasecmp(audio_std, "A2/B") == 0) | ||
224 | return V4L2_STD_A2_B; | ||
225 | if (strcasecmp(audio_std, "NICAM") == 0) | ||
226 | return V4L2_STD_NICAM; | ||
227 | if (strcasecmp(audio_std, "NICAM/A") == 0) | ||
228 | return V4L2_STD_NICAM_A; | ||
229 | if (strcasecmp(audio_std, "NICAM/B") == 0) | ||
230 | return V4L2_STD_NICAM_B; | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static void free_firmware(struct xc2028_data *priv) | ||
236 | { | ||
237 | int i; | ||
238 | tuner_dbg("%s called\n", __func__); | ||
239 | |||
240 | if (!priv->firm) | ||
241 | return; | ||
242 | |||
243 | for (i = 0; i < priv->firm_size; i++) | ||
244 | kfree(priv->firm[i].ptr); | ||
245 | |||
246 | kfree(priv->firm); | ||
247 | |||
248 | priv->firm = NULL; | ||
249 | priv->firm_size = 0; | ||
250 | |||
251 | memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); | ||
252 | } | ||
253 | |||
254 | static int load_all_firmwares(struct dvb_frontend *fe) | ||
255 | { | ||
256 | struct xc2028_data *priv = fe->tuner_priv; | ||
257 | const struct firmware *fw = NULL; | ||
258 | unsigned char *p, *endp; | ||
259 | int rc = 0; | ||
260 | int n, n_array; | ||
261 | char name[33]; | ||
262 | char *fname; | ||
263 | |||
264 | tuner_dbg("%s called\n", __func__); | ||
265 | |||
266 | if (!firmware_name[0]) | ||
267 | fname = priv->ctrl.fname; | ||
268 | else | ||
269 | fname = firmware_name; | ||
270 | |||
271 | tuner_dbg("Reading firmware %s\n", fname); | ||
272 | rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev); | ||
273 | if (rc < 0) { | ||
274 | if (rc == -ENOENT) | ||
275 | tuner_err("Error: firmware %s not found.\n", | ||
276 | fname); | ||
277 | else | ||
278 | tuner_err("Error %d while requesting firmware %s \n", | ||
279 | rc, fname); | ||
280 | |||
281 | return rc; | ||
282 | } | ||
283 | p = fw->data; | ||
284 | endp = p + fw->size; | ||
285 | |||
286 | if (fw->size < sizeof(name) - 1 + 2 + 2) { | ||
287 | tuner_err("Error: firmware file %s has invalid size!\n", | ||
288 | fname); | ||
289 | goto corrupt; | ||
290 | } | ||
291 | |||
292 | memcpy(name, p, sizeof(name) - 1); | ||
293 | name[sizeof(name) - 1] = 0; | ||
294 | p += sizeof(name) - 1; | ||
295 | |||
296 | priv->firm_version = le16_to_cpu(*(__u16 *) p); | ||
297 | p += 2; | ||
298 | |||
299 | n_array = le16_to_cpu(*(__u16 *) p); | ||
300 | p += 2; | ||
301 | |||
302 | tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", | ||
303 | n_array, fname, name, | ||
304 | priv->firm_version >> 8, priv->firm_version & 0xff); | ||
305 | |||
306 | priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL); | ||
307 | if (priv->firm == NULL) { | ||
308 | tuner_err("Not enough memory to load firmware file.\n"); | ||
309 | rc = -ENOMEM; | ||
310 | goto err; | ||
311 | } | ||
312 | priv->firm_size = n_array; | ||
313 | |||
314 | n = -1; | ||
315 | while (p < endp) { | ||
316 | __u32 type, size; | ||
317 | v4l2_std_id id; | ||
318 | __u16 int_freq = 0; | ||
319 | |||
320 | n++; | ||
321 | if (n >= n_array) { | ||
322 | tuner_err("More firmware images in file than " | ||
323 | "were expected!\n"); | ||
324 | goto corrupt; | ||
325 | } | ||
326 | |||
327 | /* Checks if there's enough bytes to read */ | ||
328 | if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) { | ||
329 | tuner_err("Firmware header is incomplete!\n"); | ||
330 | goto corrupt; | ||
331 | } | ||
332 | |||
333 | type = le32_to_cpu(*(__u32 *) p); | ||
334 | p += sizeof(type); | ||
335 | |||
336 | id = le64_to_cpu(*(v4l2_std_id *) p); | ||
337 | p += sizeof(id); | ||
338 | |||
339 | if (type & HAS_IF) { | ||
340 | int_freq = le16_to_cpu(*(__u16 *) p); | ||
341 | p += sizeof(int_freq); | ||
342 | } | ||
343 | |||
344 | size = le32_to_cpu(*(__u32 *) p); | ||
345 | p += sizeof(size); | ||
346 | |||
347 | if ((!size) || (size + p > endp)) { | ||
348 | tuner_err("Firmware type "); | ||
349 | dump_firm_type(type); | ||
350 | printk("(%x), id %llx is corrupted " | ||
351 | "(size=%d, expected %d)\n", | ||
352 | type, (unsigned long long)id, | ||
353 | (unsigned)(endp - p), size); | ||
354 | goto corrupt; | ||
355 | } | ||
356 | |||
357 | priv->firm[n].ptr = kzalloc(size, GFP_KERNEL); | ||
358 | if (priv->firm[n].ptr == NULL) { | ||
359 | tuner_err("Not enough memory to load firmware file.\n"); | ||
360 | rc = -ENOMEM; | ||
361 | goto err; | ||
362 | } | ||
363 | tuner_dbg("Reading firmware type "); | ||
364 | if (debug) { | ||
365 | dump_firm_type_and_int_freq(type, int_freq); | ||
366 | printk("(%x), id %llx, size=%d.\n", | ||
367 | type, (unsigned long long)id, size); | ||
368 | } | ||
369 | |||
370 | memcpy(priv->firm[n].ptr, p, size); | ||
371 | priv->firm[n].type = type; | ||
372 | priv->firm[n].id = id; | ||
373 | priv->firm[n].size = size; | ||
374 | priv->firm[n].int_freq = int_freq; | ||
375 | |||
376 | p += size; | ||
377 | } | ||
378 | |||
379 | if (n + 1 != priv->firm_size) { | ||
380 | tuner_err("Firmware file is incomplete!\n"); | ||
381 | goto corrupt; | ||
382 | } | ||
383 | |||
384 | goto done; | ||
385 | |||
386 | corrupt: | ||
387 | rc = -EINVAL; | ||
388 | tuner_err("Error: firmware file is corrupted!\n"); | ||
389 | |||
390 | err: | ||
391 | tuner_info("Releasing partially loaded firmware file.\n"); | ||
392 | free_firmware(priv); | ||
393 | |||
394 | done: | ||
395 | release_firmware(fw); | ||
396 | if (rc == 0) | ||
397 | tuner_dbg("Firmware files loaded.\n"); | ||
398 | |||
399 | return rc; | ||
400 | } | ||
401 | |||
402 | static int seek_firmware(struct dvb_frontend *fe, unsigned int type, | ||
403 | v4l2_std_id *id) | ||
404 | { | ||
405 | struct xc2028_data *priv = fe->tuner_priv; | ||
406 | int i, best_i = -1, best_nr_matches = 0; | ||
407 | unsigned int type_mask = 0; | ||
408 | |||
409 | tuner_dbg("%s called, want type=", __func__); | ||
410 | if (debug) { | ||
411 | dump_firm_type(type); | ||
412 | printk("(%x), id %016llx.\n", type, (unsigned long long)*id); | ||
413 | } | ||
414 | |||
415 | if (!priv->firm) { | ||
416 | tuner_err("Error! firmware not loaded\n"); | ||
417 | return -EINVAL; | ||
418 | } | ||
419 | |||
420 | if (((type & ~SCODE) == 0) && (*id == 0)) | ||
421 | *id = V4L2_STD_PAL; | ||
422 | |||
423 | if (type & BASE) | ||
424 | type_mask = BASE_TYPES; | ||
425 | else if (type & SCODE) { | ||
426 | type &= SCODE_TYPES; | ||
427 | type_mask = SCODE_TYPES & ~HAS_IF; | ||
428 | } else if (type & DTV_TYPES) | ||
429 | type_mask = DTV_TYPES; | ||
430 | else if (type & STD_SPECIFIC_TYPES) | ||
431 | type_mask = STD_SPECIFIC_TYPES; | ||
432 | |||
433 | type &= type_mask; | ||
434 | |||
435 | if (!(type & SCODE)) | ||
436 | type_mask = ~0; | ||
437 | |||
438 | /* Seek for exact match */ | ||
439 | for (i = 0; i < priv->firm_size; i++) { | ||
440 | if ((type == (priv->firm[i].type & type_mask)) && | ||
441 | (*id == priv->firm[i].id)) | ||
442 | goto found; | ||
443 | } | ||
444 | |||
445 | /* Seek for generic video standard match */ | ||
446 | for (i = 0; i < priv->firm_size; i++) { | ||
447 | v4l2_std_id match_mask; | ||
448 | int nr_matches; | ||
449 | |||
450 | if (type != (priv->firm[i].type & type_mask)) | ||
451 | continue; | ||
452 | |||
453 | match_mask = *id & priv->firm[i].id; | ||
454 | if (!match_mask) | ||
455 | continue; | ||
456 | |||
457 | if ((*id & match_mask) == *id) | ||
458 | goto found; /* Supports all the requested standards */ | ||
459 | |||
460 | nr_matches = hweight64(match_mask); | ||
461 | if (nr_matches > best_nr_matches) { | ||
462 | best_nr_matches = nr_matches; | ||
463 | best_i = i; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | if (best_nr_matches > 0) { | ||
468 | tuner_dbg("Selecting best matching firmware (%d bits) for " | ||
469 | "type=", best_nr_matches); | ||
470 | dump_firm_type(type); | ||
471 | printk("(%x), id %016llx:\n", type, (unsigned long long)*id); | ||
472 | i = best_i; | ||
473 | goto found; | ||
474 | } | ||
475 | |||
476 | /*FIXME: Would make sense to seek for type "hint" match ? */ | ||
477 | |||
478 | i = -ENOENT; | ||
479 | goto ret; | ||
480 | |||
481 | found: | ||
482 | *id = priv->firm[i].id; | ||
483 | |||
484 | ret: | ||
485 | tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found"); | ||
486 | if (debug) { | ||
487 | dump_firm_type(type); | ||
488 | printk("(%x), id %016llx.\n", type, (unsigned long long)*id); | ||
489 | } | ||
490 | return i; | ||
491 | } | ||
492 | |||
493 | static int load_firmware(struct dvb_frontend *fe, unsigned int type, | ||
494 | v4l2_std_id *id) | ||
495 | { | ||
496 | struct xc2028_data *priv = fe->tuner_priv; | ||
497 | int pos, rc; | ||
498 | unsigned char *p, *endp, buf[priv->ctrl.max_len]; | ||
499 | |||
500 | tuner_dbg("%s called\n", __func__); | ||
501 | |||
502 | pos = seek_firmware(fe, type, id); | ||
503 | if (pos < 0) | ||
504 | return pos; | ||
505 | |||
506 | tuner_info("Loading firmware for type="); | ||
507 | dump_firm_type(priv->firm[pos].type); | ||
508 | printk("(%x), id %016llx.\n", priv->firm[pos].type, | ||
509 | (unsigned long long)*id); | ||
510 | |||
511 | p = priv->firm[pos].ptr; | ||
512 | endp = p + priv->firm[pos].size; | ||
513 | |||
514 | while (p < endp) { | ||
515 | __u16 size; | ||
516 | |||
517 | /* Checks if there's enough bytes to read */ | ||
518 | if (p + sizeof(size) > endp) { | ||
519 | tuner_err("Firmware chunk size is wrong\n"); | ||
520 | return -EINVAL; | ||
521 | } | ||
522 | |||
523 | size = le16_to_cpu(*(__u16 *) p); | ||
524 | p += sizeof(size); | ||
525 | |||
526 | if (size == 0xffff) | ||
527 | return 0; | ||
528 | |||
529 | if (!size) { | ||
530 | /* Special callback command received */ | ||
531 | rc = priv->tuner_callback(priv->video_dev, | ||
532 | XC2028_TUNER_RESET, 0); | ||
533 | if (rc < 0) { | ||
534 | tuner_err("Error at RESET code %d\n", | ||
535 | (*p) & 0x7f); | ||
536 | return -EINVAL; | ||
537 | } | ||
538 | continue; | ||
539 | } | ||
540 | if (size >= 0xff00) { | ||
541 | switch (size) { | ||
542 | case 0xff00: | ||
543 | rc = priv->tuner_callback(priv->video_dev, | ||
544 | XC2028_RESET_CLK, 0); | ||
545 | if (rc < 0) { | ||
546 | tuner_err("Error at RESET code %d\n", | ||
547 | (*p) & 0x7f); | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | break; | ||
551 | default: | ||
552 | tuner_info("Invalid RESET code %d\n", | ||
553 | size & 0x7f); | ||
554 | return -EINVAL; | ||
555 | |||
556 | } | ||
557 | continue; | ||
558 | } | ||
559 | |||
560 | /* Checks for a sleep command */ | ||
561 | if (size & 0x8000) { | ||
562 | msleep(size & 0x7fff); | ||
563 | continue; | ||
564 | } | ||
565 | |||
566 | if ((size + p > endp)) { | ||
567 | tuner_err("missing bytes: need %d, have %d\n", | ||
568 | size, (int)(endp - p)); | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | |||
572 | buf[0] = *p; | ||
573 | p++; | ||
574 | size--; | ||
575 | |||
576 | /* Sends message chunks */ | ||
577 | while (size > 0) { | ||
578 | int len = (size < priv->ctrl.max_len - 1) ? | ||
579 | size : priv->ctrl.max_len - 1; | ||
580 | |||
581 | memcpy(buf + 1, p, len); | ||
582 | |||
583 | rc = i2c_send(priv, buf, len + 1); | ||
584 | if (rc < 0) { | ||
585 | tuner_err("%d returned from send\n", rc); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | p += len; | ||
590 | size -= len; | ||
591 | } | ||
592 | } | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int load_scode(struct dvb_frontend *fe, unsigned int type, | ||
597 | v4l2_std_id *id, __u16 int_freq, int scode) | ||
598 | { | ||
599 | struct xc2028_data *priv = fe->tuner_priv; | ||
600 | int pos, rc; | ||
601 | unsigned char *p; | ||
602 | |||
603 | tuner_dbg("%s called\n", __func__); | ||
604 | |||
605 | if (!int_freq) { | ||
606 | pos = seek_firmware(fe, type, id); | ||
607 | if (pos < 0) | ||
608 | return pos; | ||
609 | } else { | ||
610 | for (pos = 0; pos < priv->firm_size; pos++) { | ||
611 | if ((priv->firm[pos].int_freq == int_freq) && | ||
612 | (priv->firm[pos].type & HAS_IF)) | ||
613 | break; | ||
614 | } | ||
615 | if (pos == priv->firm_size) | ||
616 | return -ENOENT; | ||
617 | } | ||
618 | |||
619 | p = priv->firm[pos].ptr; | ||
620 | |||
621 | if (priv->firm[pos].type & HAS_IF) { | ||
622 | if (priv->firm[pos].size != 12 * 16 || scode >= 16) | ||
623 | return -EINVAL; | ||
624 | p += 12 * scode; | ||
625 | } else { | ||
626 | /* 16 SCODE entries per file; each SCODE entry is 12 bytes and | ||
627 | * has a 2-byte size header in the firmware format. */ | ||
628 | if (priv->firm[pos].size != 14 * 16 || scode >= 16 || | ||
629 | le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12) | ||
630 | return -EINVAL; | ||
631 | p += 14 * scode + 2; | ||
632 | } | ||
633 | |||
634 | tuner_info("Loading SCODE for type="); | ||
635 | dump_firm_type_and_int_freq(priv->firm[pos].type, | ||
636 | priv->firm[pos].int_freq); | ||
637 | printk("(%x), id %016llx.\n", priv->firm[pos].type, | ||
638 | (unsigned long long)*id); | ||
639 | |||
640 | if (priv->firm_version < 0x0202) | ||
641 | rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00}); | ||
642 | else | ||
643 | rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00}); | ||
644 | if (rc < 0) | ||
645 | return -EIO; | ||
646 | |||
647 | rc = i2c_send(priv, p, 12); | ||
648 | if (rc < 0) | ||
649 | return -EIO; | ||
650 | |||
651 | rc = send_seq(priv, {0x00, 0x8c}); | ||
652 | if (rc < 0) | ||
653 | return -EIO; | ||
654 | |||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | static int check_firmware(struct dvb_frontend *fe, unsigned int type, | ||
659 | v4l2_std_id std, __u16 int_freq) | ||
660 | { | ||
661 | struct xc2028_data *priv = fe->tuner_priv; | ||
662 | struct firmware_properties new_fw; | ||
663 | int rc = 0, is_retry = 0; | ||
664 | u16 version, hwmodel; | ||
665 | v4l2_std_id std0; | ||
666 | |||
667 | tuner_dbg("%s called\n", __func__); | ||
668 | |||
669 | if (!priv->firm) { | ||
670 | if (!priv->ctrl.fname) { | ||
671 | tuner_info("xc2028/3028 firmware name not set!\n"); | ||
672 | return -EINVAL; | ||
673 | } | ||
674 | |||
675 | rc = load_all_firmwares(fe); | ||
676 | if (rc < 0) | ||
677 | return rc; | ||
678 | } | ||
679 | |||
680 | if (priv->ctrl.mts && !(type & FM)) | ||
681 | type |= MTS; | ||
682 | |||
683 | retry: | ||
684 | new_fw.type = type; | ||
685 | new_fw.id = std; | ||
686 | new_fw.std_req = std; | ||
687 | new_fw.scode_table = SCODE | priv->ctrl.scode_table; | ||
688 | new_fw.scode_nr = 0; | ||
689 | new_fw.int_freq = int_freq; | ||
690 | |||
691 | tuner_dbg("checking firmware, user requested type="); | ||
692 | if (debug) { | ||
693 | dump_firm_type(new_fw.type); | ||
694 | printk("(%x), id %016llx, ", new_fw.type, | ||
695 | (unsigned long long)new_fw.std_req); | ||
696 | if (!int_freq) { | ||
697 | printk("scode_tbl "); | ||
698 | dump_firm_type(priv->ctrl.scode_table); | ||
699 | printk("(%x), ", priv->ctrl.scode_table); | ||
700 | } else | ||
701 | printk("int_freq %d, ", new_fw.int_freq); | ||
702 | printk("scode_nr %d\n", new_fw.scode_nr); | ||
703 | } | ||
704 | |||
705 | /* No need to reload base firmware if it matches */ | ||
706 | if (((BASE | new_fw.type) & BASE_TYPES) == | ||
707 | (priv->cur_fw.type & BASE_TYPES)) { | ||
708 | tuner_dbg("BASE firmware not changed.\n"); | ||
709 | goto skip_base; | ||
710 | } | ||
711 | |||
712 | /* Updating BASE - forget about all currently loaded firmware */ | ||
713 | memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); | ||
714 | |||
715 | /* Reset is needed before loading firmware */ | ||
716 | rc = priv->tuner_callback(priv->video_dev, | ||
717 | XC2028_TUNER_RESET, 0); | ||
718 | if (rc < 0) | ||
719 | goto fail; | ||
720 | |||
721 | /* BASE firmwares are all std0 */ | ||
722 | std0 = 0; | ||
723 | rc = load_firmware(fe, BASE | new_fw.type, &std0); | ||
724 | if (rc < 0) { | ||
725 | tuner_err("Error %d while loading base firmware\n", | ||
726 | rc); | ||
727 | goto fail; | ||
728 | } | ||
729 | |||
730 | /* Load INIT1, if needed */ | ||
731 | tuner_dbg("Load init1 firmware, if exists\n"); | ||
732 | |||
733 | rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0); | ||
734 | if (rc == -ENOENT) | ||
735 | rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ, | ||
736 | &std0); | ||
737 | if (rc < 0 && rc != -ENOENT) { | ||
738 | tuner_err("Error %d while loading init1 firmware\n", | ||
739 | rc); | ||
740 | goto fail; | ||
741 | } | ||
742 | |||
743 | skip_base: | ||
744 | /* | ||
745 | * No need to reload standard specific firmware if base firmware | ||
746 | * was not reloaded and requested video standards have not changed. | ||
747 | */ | ||
748 | if (priv->cur_fw.type == (BASE | new_fw.type) && | ||
749 | priv->cur_fw.std_req == std) { | ||
750 | tuner_dbg("Std-specific firmware already loaded.\n"); | ||
751 | goto skip_std_specific; | ||
752 | } | ||
753 | |||
754 | /* Reloading std-specific firmware forces a SCODE update */ | ||
755 | priv->cur_fw.scode_table = 0; | ||
756 | |||
757 | rc = load_firmware(fe, new_fw.type, &new_fw.id); | ||
758 | if (rc == -ENOENT) | ||
759 | rc = load_firmware(fe, new_fw.type & ~F8MHZ, &new_fw.id); | ||
760 | |||
761 | if (rc < 0) | ||
762 | goto fail; | ||
763 | |||
764 | skip_std_specific: | ||
765 | if (priv->cur_fw.scode_table == new_fw.scode_table && | ||
766 | priv->cur_fw.scode_nr == new_fw.scode_nr) { | ||
767 | tuner_dbg("SCODE firmware already loaded.\n"); | ||
768 | goto check_device; | ||
769 | } | ||
770 | |||
771 | if (new_fw.type & FM) | ||
772 | goto check_device; | ||
773 | |||
774 | /* Load SCODE firmware, if exists */ | ||
775 | tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); | ||
776 | |||
777 | rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id, | ||
778 | new_fw.int_freq, new_fw.scode_nr); | ||
779 | |||
780 | check_device: | ||
781 | if (xc2028_get_reg(priv, 0x0004, &version) < 0 || | ||
782 | xc2028_get_reg(priv, 0x0008, &hwmodel) < 0) { | ||
783 | tuner_err("Unable to read tuner registers.\n"); | ||
784 | goto fail; | ||
785 | } | ||
786 | |||
787 | tuner_dbg("Device is Xceive %d version %d.%d, " | ||
788 | "firmware version %d.%d\n", | ||
789 | hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, | ||
790 | (version & 0xf0) >> 4, version & 0xf); | ||
791 | |||
792 | /* Check firmware version against what we downloaded. */ | ||
793 | if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) { | ||
794 | tuner_err("Incorrect readback of firmware version.\n"); | ||
795 | goto fail; | ||
796 | } | ||
797 | |||
798 | /* Check that the tuner hardware model remains consistent over time. */ | ||
799 | if (priv->hwmodel == 0 && (hwmodel == 2028 || hwmodel == 3028)) { | ||
800 | priv->hwmodel = hwmodel; | ||
801 | priv->hwvers = version & 0xff00; | ||
802 | } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel || | ||
803 | priv->hwvers != (version & 0xff00)) { | ||
804 | tuner_err("Read invalid device hardware information - tuner " | ||
805 | "hung?\n"); | ||
806 | goto fail; | ||
807 | } | ||
808 | |||
809 | memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw)); | ||
810 | |||
811 | /* | ||
812 | * By setting BASE in cur_fw.type only after successfully loading all | ||
813 | * firmwares, we can: | ||
814 | * 1. Identify that BASE firmware with type=0 has been loaded; | ||
815 | * 2. Tell whether BASE firmware was just changed the next time through. | ||
816 | */ | ||
817 | priv->cur_fw.type |= BASE; | ||
818 | |||
819 | return 0; | ||
820 | |||
821 | fail: | ||
822 | memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); | ||
823 | if (!is_retry) { | ||
824 | msleep(50); | ||
825 | is_retry = 1; | ||
826 | tuner_dbg("Retrying firmware load\n"); | ||
827 | goto retry; | ||
828 | } | ||
829 | |||
830 | if (rc == -ENOENT) | ||
831 | rc = -EINVAL; | ||
832 | return rc; | ||
833 | } | ||
834 | |||
835 | static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | ||
836 | { | ||
837 | struct xc2028_data *priv = fe->tuner_priv; | ||
838 | u16 frq_lock, signal = 0; | ||
839 | int rc; | ||
840 | |||
841 | tuner_dbg("%s called\n", __func__); | ||
842 | |||
843 | mutex_lock(&priv->lock); | ||
844 | |||
845 | /* Sync Lock Indicator */ | ||
846 | rc = xc2028_get_reg(priv, 0x0002, &frq_lock); | ||
847 | if (rc < 0) | ||
848 | goto ret; | ||
849 | |||
850 | /* Frequency is locked */ | ||
851 | if (frq_lock == 1) | ||
852 | signal = 32768; | ||
853 | |||
854 | /* Get SNR of the video signal */ | ||
855 | rc = xc2028_get_reg(priv, 0x0040, &signal); | ||
856 | if (rc < 0) | ||
857 | goto ret; | ||
858 | |||
859 | /* Use both frq_lock and signal to generate the result */ | ||
860 | signal = signal || ((signal & 0x07) << 12); | ||
861 | |||
862 | ret: | ||
863 | mutex_unlock(&priv->lock); | ||
864 | |||
865 | *strength = signal; | ||
866 | |||
867 | tuner_dbg("signal strength is %d\n", signal); | ||
868 | |||
869 | return rc; | ||
870 | } | ||
871 | |||
872 | #define DIV 15625 | ||
873 | |||
874 | static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | ||
875 | enum tuner_mode new_mode, | ||
876 | unsigned int type, | ||
877 | v4l2_std_id std, | ||
878 | u16 int_freq) | ||
879 | { | ||
880 | struct xc2028_data *priv = fe->tuner_priv; | ||
881 | int rc = -EINVAL; | ||
882 | unsigned char buf[4]; | ||
883 | u32 div, offset = 0; | ||
884 | |||
885 | tuner_dbg("%s called\n", __func__); | ||
886 | |||
887 | mutex_lock(&priv->lock); | ||
888 | |||
889 | tuner_dbg("should set frequency %d kHz\n", freq / 1000); | ||
890 | |||
891 | if (check_firmware(fe, type, std, int_freq) < 0) | ||
892 | goto ret; | ||
893 | |||
894 | /* On some cases xc2028 can disable video output, if | ||
895 | * very weak signals are received. By sending a soft | ||
896 | * reset, this is re-enabled. So, it is better to always | ||
897 | * send a soft reset before changing channels, to be sure | ||
898 | * that xc2028 will be in a safe state. | ||
899 | * Maybe this might also be needed for DTV. | ||
900 | */ | ||
901 | if (new_mode == T_ANALOG_TV) { | ||
902 | rc = send_seq(priv, {0x00, 0x00}); | ||
903 | } else if (priv->cur_fw.type & ATSC) { | ||
904 | offset = 1750000; | ||
905 | } else { | ||
906 | offset = 2750000; | ||
907 | /* | ||
908 | * We must adjust the offset by 500kHz in two cases in order | ||
909 | * to correctly center the IF output: | ||
910 | * 1) When the ZARLINK456 or DIBCOM52 tables were explicitly | ||
911 | * selected and a 7MHz channel is tuned; | ||
912 | * 2) When tuning a VHF channel with DTV78 firmware. | ||
913 | */ | ||
914 | if (((priv->cur_fw.type & DTV7) && | ||
915 | (priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) || | ||
916 | ((priv->cur_fw.type & DTV78) && freq < 470000000)) | ||
917 | offset -= 500000; | ||
918 | } | ||
919 | |||
920 | div = (freq - offset + DIV / 2) / DIV; | ||
921 | |||
922 | /* CMD= Set frequency */ | ||
923 | if (priv->firm_version < 0x0202) | ||
924 | rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00}); | ||
925 | else | ||
926 | rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00}); | ||
927 | if (rc < 0) | ||
928 | goto ret; | ||
929 | |||
930 | /* Return code shouldn't be checked. | ||
931 | The reset CLK is needed only with tm6000. | ||
932 | Driver should work fine even if this fails. | ||
933 | */ | ||
934 | priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); | ||
935 | |||
936 | msleep(10); | ||
937 | |||
938 | buf[0] = 0xff & (div >> 24); | ||
939 | buf[1] = 0xff & (div >> 16); | ||
940 | buf[2] = 0xff & (div >> 8); | ||
941 | buf[3] = 0xff & (div); | ||
942 | |||
943 | rc = i2c_send(priv, buf, sizeof(buf)); | ||
944 | if (rc < 0) | ||
945 | goto ret; | ||
946 | msleep(100); | ||
947 | |||
948 | priv->frequency = freq; | ||
949 | |||
950 | tuner_dbg("divisor= %02x %02x %02x %02x (freq=%d.%03d)\n", | ||
951 | buf[0], buf[1], buf[2], buf[3], | ||
952 | freq / 1000000, (freq % 1000000) / 1000); | ||
953 | |||
954 | rc = 0; | ||
955 | |||
956 | ret: | ||
957 | mutex_unlock(&priv->lock); | ||
958 | |||
959 | return rc; | ||
960 | } | ||
961 | |||
962 | static int xc2028_set_analog_freq(struct dvb_frontend *fe, | ||
963 | struct analog_parameters *p) | ||
964 | { | ||
965 | struct xc2028_data *priv = fe->tuner_priv; | ||
966 | unsigned int type=0; | ||
967 | |||
968 | tuner_dbg("%s called\n", __func__); | ||
969 | |||
970 | if (p->mode == V4L2_TUNER_RADIO) { | ||
971 | type |= FM; | ||
972 | if (priv->ctrl.input1) | ||
973 | type |= INPUT1; | ||
974 | return generic_set_freq(fe, (625l * p->frequency) / 10, | ||
975 | T_ANALOG_TV, type, 0, 0); | ||
976 | } | ||
977 | |||
978 | /* if std is not defined, choose one */ | ||
979 | if (!p->std) | ||
980 | p->std = V4L2_STD_MN; | ||
981 | |||
982 | /* PAL/M, PAL/N, PAL/Nc and NTSC variants should use 6MHz firmware */ | ||
983 | if (!(p->std & V4L2_STD_MN)) | ||
984 | type |= F8MHZ; | ||
985 | |||
986 | /* Add audio hack to std mask */ | ||
987 | p->std |= parse_audio_std_option(); | ||
988 | |||
989 | return generic_set_freq(fe, 62500l * p->frequency, | ||
990 | T_ANALOG_TV, type, p->std, 0); | ||
991 | } | ||
992 | |||
993 | static int xc2028_set_params(struct dvb_frontend *fe, | ||
994 | struct dvb_frontend_parameters *p) | ||
995 | { | ||
996 | struct xc2028_data *priv = fe->tuner_priv; | ||
997 | unsigned int type=0; | ||
998 | fe_bandwidth_t bw = BANDWIDTH_8_MHZ; | ||
999 | u16 demod = 0; | ||
1000 | |||
1001 | tuner_dbg("%s called\n", __func__); | ||
1002 | |||
1003 | if (priv->ctrl.d2633) | ||
1004 | type |= D2633; | ||
1005 | else | ||
1006 | type |= D2620; | ||
1007 | |||
1008 | switch(fe->ops.info.type) { | ||
1009 | case FE_OFDM: | ||
1010 | bw = p->u.ofdm.bandwidth; | ||
1011 | break; | ||
1012 | case FE_QAM: | ||
1013 | tuner_info("WARN: There are some reports that " | ||
1014 | "QAM 6 MHz doesn't work.\n" | ||
1015 | "If this works for you, please report by " | ||
1016 | "e-mail to: v4l-dvb-maintainer@linuxtv.org\n"); | ||
1017 | bw = BANDWIDTH_6_MHZ; | ||
1018 | type |= QAM; | ||
1019 | break; | ||
1020 | case FE_ATSC: | ||
1021 | bw = BANDWIDTH_6_MHZ; | ||
1022 | /* The only ATSC firmware (at least on v2.7) is D2633, | ||
1023 | so overrides ctrl->d2633 */ | ||
1024 | type |= ATSC| D2633; | ||
1025 | type &= ~D2620; | ||
1026 | break; | ||
1027 | /* DVB-S is not supported */ | ||
1028 | default: | ||
1029 | return -EINVAL; | ||
1030 | } | ||
1031 | |||
1032 | switch (bw) { | ||
1033 | case BANDWIDTH_8_MHZ: | ||
1034 | if (p->frequency < 470000000) | ||
1035 | priv->ctrl.vhfbw7 = 0; | ||
1036 | else | ||
1037 | priv->ctrl.uhfbw8 = 1; | ||
1038 | type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8; | ||
1039 | type |= F8MHZ; | ||
1040 | break; | ||
1041 | case BANDWIDTH_7_MHZ: | ||
1042 | if (p->frequency < 470000000) | ||
1043 | priv->ctrl.vhfbw7 = 1; | ||
1044 | else | ||
1045 | priv->ctrl.uhfbw8 = 0; | ||
1046 | type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7; | ||
1047 | type |= F8MHZ; | ||
1048 | break; | ||
1049 | case BANDWIDTH_6_MHZ: | ||
1050 | type |= DTV6; | ||
1051 | priv->ctrl.vhfbw7 = 0; | ||
1052 | priv->ctrl.uhfbw8 = 0; | ||
1053 | break; | ||
1054 | default: | ||
1055 | tuner_err("error: bandwidth not supported.\n"); | ||
1056 | }; | ||
1057 | |||
1058 | /* All S-code tables need a 200kHz shift */ | ||
1059 | if (priv->ctrl.demod) | ||
1060 | demod = priv->ctrl.demod + 200; | ||
1061 | |||
1062 | return generic_set_freq(fe, p->frequency, | ||
1063 | T_DIGITAL_TV, type, 0, demod); | ||
1064 | } | ||
1065 | |||
1066 | |||
1067 | static int xc2028_dvb_release(struct dvb_frontend *fe) | ||
1068 | { | ||
1069 | struct xc2028_data *priv = fe->tuner_priv; | ||
1070 | |||
1071 | tuner_dbg("%s called\n", __func__); | ||
1072 | |||
1073 | mutex_lock(&xc2028_list_mutex); | ||
1074 | |||
1075 | priv->count--; | ||
1076 | |||
1077 | if (!priv->count) { | ||
1078 | list_del(&priv->xc2028_list); | ||
1079 | |||
1080 | kfree(priv->ctrl.fname); | ||
1081 | |||
1082 | free_firmware(priv); | ||
1083 | kfree(priv); | ||
1084 | fe->tuner_priv = NULL; | ||
1085 | } | ||
1086 | |||
1087 | mutex_unlock(&xc2028_list_mutex); | ||
1088 | |||
1089 | return 0; | ||
1090 | } | ||
1091 | |||
1092 | static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
1093 | { | ||
1094 | struct xc2028_data *priv = fe->tuner_priv; | ||
1095 | |||
1096 | tuner_dbg("%s called\n", __func__); | ||
1097 | |||
1098 | *frequency = priv->frequency; | ||
1099 | |||
1100 | return 0; | ||
1101 | } | ||
1102 | |||
1103 | static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) | ||
1104 | { | ||
1105 | struct xc2028_data *priv = fe->tuner_priv; | ||
1106 | struct xc2028_ctrl *p = priv_cfg; | ||
1107 | int rc = 0; | ||
1108 | |||
1109 | tuner_dbg("%s called\n", __func__); | ||
1110 | |||
1111 | mutex_lock(&priv->lock); | ||
1112 | |||
1113 | memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); | ||
1114 | if (priv->ctrl.max_len < 9) | ||
1115 | priv->ctrl.max_len = 13; | ||
1116 | |||
1117 | if (p->fname) { | ||
1118 | if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) { | ||
1119 | kfree(priv->ctrl.fname); | ||
1120 | free_firmware(priv); | ||
1121 | } | ||
1122 | |||
1123 | priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); | ||
1124 | if (priv->ctrl.fname == NULL) | ||
1125 | rc = -ENOMEM; | ||
1126 | } | ||
1127 | |||
1128 | mutex_unlock(&priv->lock); | ||
1129 | |||
1130 | return rc; | ||
1131 | } | ||
1132 | |||
1133 | static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = { | ||
1134 | .info = { | ||
1135 | .name = "Xceive XC3028", | ||
1136 | .frequency_min = 42000000, | ||
1137 | .frequency_max = 864000000, | ||
1138 | .frequency_step = 50000, | ||
1139 | }, | ||
1140 | |||
1141 | .set_config = xc2028_set_config, | ||
1142 | .set_analog_params = xc2028_set_analog_freq, | ||
1143 | .release = xc2028_dvb_release, | ||
1144 | .get_frequency = xc2028_get_frequency, | ||
1145 | .get_rf_strength = xc2028_signal, | ||
1146 | .set_params = xc2028_set_params, | ||
1147 | }; | ||
1148 | |||
1149 | struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | ||
1150 | struct xc2028_config *cfg) | ||
1151 | { | ||
1152 | struct xc2028_data *priv; | ||
1153 | void *video_dev; | ||
1154 | |||
1155 | if (debug) | ||
1156 | printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); | ||
1157 | |||
1158 | if (NULL == cfg) | ||
1159 | return NULL; | ||
1160 | |||
1161 | if (!fe) { | ||
1162 | printk(KERN_ERR "xc2028: No frontend!\n"); | ||
1163 | return NULL; | ||
1164 | } | ||
1165 | |||
1166 | video_dev = cfg->i2c_adap->algo_data; | ||
1167 | |||
1168 | if (debug) | ||
1169 | printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev); | ||
1170 | |||
1171 | mutex_lock(&xc2028_list_mutex); | ||
1172 | |||
1173 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { | ||
1174 | if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) { | ||
1175 | video_dev = NULL; | ||
1176 | if (debug) | ||
1177 | printk(KERN_DEBUG "xc2028: reusing device\n"); | ||
1178 | |||
1179 | break; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | if (video_dev) { | ||
1184 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1185 | if (priv == NULL) { | ||
1186 | mutex_unlock(&xc2028_list_mutex); | ||
1187 | return NULL; | ||
1188 | } | ||
1189 | |||
1190 | priv->i2c_props.addr = cfg->i2c_addr; | ||
1191 | priv->i2c_props.adap = cfg->i2c_adap; | ||
1192 | priv->i2c_props.name = "xc2028"; | ||
1193 | |||
1194 | priv->video_dev = video_dev; | ||
1195 | priv->tuner_callback = cfg->callback; | ||
1196 | priv->ctrl.max_len = 13; | ||
1197 | |||
1198 | mutex_init(&priv->lock); | ||
1199 | |||
1200 | list_add_tail(&priv->xc2028_list, &xc2028_list); | ||
1201 | } | ||
1202 | |||
1203 | fe->tuner_priv = priv; | ||
1204 | priv->count++; | ||
1205 | |||
1206 | if (debug) | ||
1207 | printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count); | ||
1208 | |||
1209 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, | ||
1210 | sizeof(xc2028_dvb_tuner_ops)); | ||
1211 | |||
1212 | tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner"); | ||
1213 | |||
1214 | if (cfg->ctrl) | ||
1215 | xc2028_set_config(fe, cfg->ctrl); | ||
1216 | |||
1217 | mutex_unlock(&xc2028_list_mutex); | ||
1218 | |||
1219 | return fe; | ||
1220 | } | ||
1221 | |||
1222 | EXPORT_SYMBOL(xc2028_attach); | ||
1223 | |||
1224 | MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); | ||
1225 | MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>"); | ||
1226 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | ||
1227 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tuner-xc2028.h b/drivers/media/video/tuner-xc2028.h deleted file mode 100644 index fc2f132a5541..000000000000 --- a/drivers/media/video/tuner-xc2028.h +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | /* tuner-xc2028 | ||
2 | * | ||
3 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
4 | * This code is placed under the terms of the GNU General Public License v2 | ||
5 | */ | ||
6 | |||
7 | #ifndef __TUNER_XC2028_H__ | ||
8 | #define __TUNER_XC2028_H__ | ||
9 | |||
10 | #include "dvb_frontend.h" | ||
11 | |||
12 | #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw" | ||
13 | |||
14 | /* Dmoduler IF (kHz) */ | ||
15 | #define XC3028_FE_DEFAULT 0 /* Don't load SCODE */ | ||
16 | #define XC3028_FE_LG60 6000 | ||
17 | #define XC3028_FE_ATI638 6380 | ||
18 | #define XC3028_FE_OREN538 5380 | ||
19 | #define XC3028_FE_OREN36 3600 | ||
20 | #define XC3028_FE_TOYOTA388 3880 | ||
21 | #define XC3028_FE_TOYOTA794 7940 | ||
22 | #define XC3028_FE_DIBCOM52 5200 | ||
23 | #define XC3028_FE_ZARLINK456 4560 | ||
24 | #define XC3028_FE_CHINA 5200 | ||
25 | |||
26 | struct xc2028_ctrl { | ||
27 | char *fname; | ||
28 | int max_len; | ||
29 | unsigned int scode_table; | ||
30 | unsigned int mts :1; | ||
31 | unsigned int d2633 :1; | ||
32 | unsigned int input1:1; | ||
33 | unsigned int vhfbw7:1; | ||
34 | unsigned int uhfbw8:1; | ||
35 | unsigned int demod; | ||
36 | }; | ||
37 | |||
38 | struct xc2028_config { | ||
39 | struct i2c_adapter *i2c_adap; | ||
40 | u8 i2c_addr; | ||
41 | void *video_dev; | ||
42 | struct xc2028_ctrl *ctrl; | ||
43 | int (*callback) (void *dev, int command, int arg); | ||
44 | }; | ||
45 | |||
46 | /* xc2028 commands for callback */ | ||
47 | #define XC2028_TUNER_RESET 0 | ||
48 | #define XC2028_RESET_CLK 1 | ||
49 | |||
50 | #if defined(CONFIG_TUNER_XC2028) || (defined(CONFIG_TUNER_XC2028_MODULE) && defined(MODULE)) | ||
51 | extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | ||
52 | struct xc2028_config *cfg); | ||
53 | #else | ||
54 | static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | ||
55 | struct xc2028_config *cfg) | ||
56 | { | ||
57 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | ||
58 | __func__); | ||
59 | return NULL; | ||
60 | } | ||
61 | #endif | ||
62 | |||
63 | #endif /* __TUNER_XC2028_H__ */ | ||
diff --git a/drivers/media/video/usbvision/Makefile b/drivers/media/video/usbvision/Makefile index 9ac92a80c645..338718750945 100644 --- a/drivers/media/video/usbvision/Makefile +++ b/drivers/media/video/usbvision/Makefile | |||
@@ -3,3 +3,4 @@ usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision- | |||
3 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o | 3 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o |
4 | 4 | ||
5 | EXTRA_CFLAGS += -Idrivers/media/video | 5 | EXTRA_CFLAGS += -Idrivers/media/video |
6 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||