aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-07-12 16:58:55 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-12 19:01:06 -0400
commitf7ce3cc67052de63a29bad90110640b687d12058 (patch)
treef3978eb08434d0e87b2467949bd22513c3535416
parentebe4c6fa535b0410e58e9c8352320896d07e2efb (diff)
[PATCH] v4l: I2C Tuner
- Fixed a trouble on tuner-core that generates erros on computers with more than one TV card. - Rename tuner structures fields. - Tail spaces removed. - I2C cleanups and converged to a basic reference structure. - Removed unused structures. - Fix setting frequency on tda8290. - Added code for TEA5767 autodetection. - Standby mode support implemented. It is used to disable a non used tuner. Currenlty implemented on tea5767. - New macro: set_type disables other tuner when changing mode. - Some cleanups. - Use 50 kHz step when tunning radio for most tuners to improve precision. Signed-off-by: Fabien Perrot <perrot1983@yahoo.fr> Signed-off-by: Michael Krufky <mkrufky@m1k.net> Signed-off-By: Nickolay V. Shmyrev <nshmyrev@yandex.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/media/video/mt20xx.c16
-rw-r--r--drivers/media/video/tda8290.c13
-rw-r--r--drivers/media/video/tda9887.c9
-rw-r--r--drivers/media/video/tea5767.c158
-rw-r--r--drivers/media/video/tuner-core.c707
-rw-r--r--drivers/media/video/tuner-simple.c85
-rw-r--r--include/media/tuner.h51
7 files changed, 545 insertions, 494 deletions
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 9c005cb128d7..2fb7c2d1787a 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -511,22 +511,6 @@ int microtune_init(struct i2c_client *c)
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", 511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]); 512 company_code,buf[0x13],buf[0x14]);
513 513
514#if 0
515 /* seems to cause more problems than it solves ... */
516 switch (company_code) {
517 case 0x30bf:
518 case 0x3cbf:
519 case 0x3dbf:
520 case 0x4d54:
521 case 0x8e81:
522 case 0x8e91:
523 /* ok (?) */
524 break;
525 default:
526 tuner_warn("tuner: microtune: unknown companycode\n");
527 return 0;
528 }
529#endif
530 514
531 if (buf[0x13] < ARRAY_SIZE(microtune_part) && 515 if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
532 NULL != microtune_part[buf[0x13]]) 516 NULL != microtune_part[buf[0x13]])
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index f59d4601cc63..a8b6a8df5109 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $ 2 * $Id: tda8290.c,v 1.15 2005/07/08 20:21:33 mchehab Exp $
3 * 3 *
4 * i2c tv tuner chip device driver 4 * i2c tv tuner chip device driver
5 * controls the philips tda8290+75 tuner chip combo. 5 * controls the philips tda8290+75 tuner chip combo.
@@ -136,15 +136,12 @@ static int tda8290_tune(struct i2c_client *c)
136 return 0; 136 return 0;
137} 137}
138 138
139static void set_frequency(struct tuner *t, u16 ifc) 139static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
140{ 140{
141 u32 freq;
142 u32 N; 141 u32 N;
143 142
144 if (t->mode == V4L2_TUNER_RADIO) 143 if (t->mode == V4L2_TUNER_RADIO)
145 freq = t->freq / 1000; 144 freq = freq / 1000;
146 else
147 freq = t->freq;
148 145
149 N = (((freq<<3)+ifc)&0x3fffc); 146 N = (((freq<<3)+ifc)&0x3fffc);
150 147
@@ -187,14 +184,14 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
187 struct tuner *t = i2c_get_clientdata(c); 184 struct tuner *t = i2c_get_clientdata(c);
188 185
189 set_audio(t); 186 set_audio(t);
190 set_frequency(t, 864); 187 set_frequency(t, 864, freq);
191 tda8290_tune(c); 188 tda8290_tune(c);
192} 189}
193 190
194static void set_radio_freq(struct i2c_client *c, unsigned int freq) 191static void set_radio_freq(struct i2c_client *c, unsigned int freq)
195{ 192{
196 struct tuner *t = i2c_get_clientdata(c); 193 struct tuner *t = i2c_get_clientdata(c);
197 set_frequency(t, 704); 194 set_frequency(t, 704, freq);
198 tda8290_tune(c); 195 tda8290_tune(c);
199} 196}
200 197
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index ee35562f4d1a..108c3ad7d622 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -569,15 +569,6 @@ static int tda9887_configure(struct tda9887 *t)
569 tda9887_set_config(t,buf); 569 tda9887_set_config(t,buf);
570 tda9887_set_insmod(t,buf); 570 tda9887_set_insmod(t,buf);
571 571
572#if 0
573 /* This as-is breaks some cards, must be fixed in a
574 * card-specific way, probably using TDA9887_SET_CONFIG to
575 * turn on/off port2 */
576 if (t->std & V4L2_STD_SECAM_L) {
577 /* secam fixup (FIXME: move this to tvnorms array?) */
578 buf[1] &= ~cOutputPort2Inactive;
579 }
580#endif
581 572
582 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", 573 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
583 buf[1],buf[2],buf[3]); 574 buf[1],buf[2],buf[3]);
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index a29f08f81f63..b53c748caf2a 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -2,7 +2,7 @@
2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview 2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
3 * I2C address is allways 0xC0. 3 * I2C address is allways 0xC0.
4 * 4 *
5 * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $ 5 * $Id: tea5767.c,v 1.18 2005/07/07 03:02:55 mchehab Exp $
6 * 6 *
7 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) 7 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
8 * This code is placed under the terms of the GNU General Public License 8 * This code is placed under the terms of the GNU General Public License
@@ -11,23 +11,11 @@
11 * from their contributions on DScaler. 11 * from their contributions on DScaler.
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/string.h>
19#include <linux/timer.h>
20#include <linux/delay.h>
21#include <linux/errno.h>
22#include <linux/slab.h>
23#include <linux/videodev.h>
24#include <linux/i2c.h> 14#include <linux/i2c.h>
25#include <linux/i2c-algo-bit.h> 15#include <linux/videodev.h>
26 16#include <linux/delay.h>
17#include <media/tuner.h>
27#include <media/tuner.h> 18#include <media/tuner.h>
28
29/* Declared at tuner-core.c */
30extern unsigned int tuner_debug;
31 19
32#define PREFIX "TEA5767 " 20#define PREFIX "TEA5767 "
33 21
@@ -38,8 +26,8 @@ extern unsigned int tuner_debug;
38 ******************************/ 26 ******************************/
39 27
40/* First register */ 28/* First register */
41#define TEA5767_MUTE 0x80 /* Mutes output */ 29#define TEA5767_MUTE 0x80 /* Mutes output */
42#define TEA5767_SEARCH 0x40 /* Activates station search */ 30#define TEA5767_SEARCH 0x40 /* Activates station search */
43/* Bits 0-5 for divider MSB */ 31/* Bits 0-5 for divider MSB */
44 32
45/* Second register */ 33/* Second register */
@@ -130,6 +118,14 @@ extern unsigned int tuner_debug;
130/* Reserved for future extensions */ 118/* Reserved for future extensions */
131#define TEA5767_RESERVED_MASK 0xff 119#define TEA5767_RESERVED_MASK 0xff
132 120
121enum tea5767_xtal_freq {
122 TEA5767_LOW_LO_32768 = 0,
123 TEA5767_HIGH_LO_32768 = 1,
124 TEA5767_LOW_LO_13MHz = 2,
125 TEA5767_HIGH_LO_13MHz = 3,
126};
127
128
133/*****************************************************************************/ 129/*****************************************************************************/
134 130
135static void set_tv_freq(struct i2c_client *c, unsigned int freq) 131static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -153,103 +149,112 @@ static void tea5767_status_dump(unsigned char *buffer)
153 else 149 else
154 printk(PREFIX "Tuner not at band limit\n"); 150 printk(PREFIX "Tuner not at band limit\n");
155 151
156 div=((buffer[0]&0x3f)<<8) | buffer[1]; 152 div = ((buffer[0] & 0x3f) << 8) | buffer[1];
157 153
158 switch (TEA5767_HIGH_LO_32768) { 154 switch (TEA5767_HIGH_LO_32768) {
159 case TEA5767_HIGH_LO_13MHz: 155 case TEA5767_HIGH_LO_13MHz:
160 frq = 1000*(div*50-700-225)/4; /* Freq in KHz */ 156 frq = 1000 * (div * 50 - 700 - 225) / 4; /* Freq in KHz */
161 break; 157 break;
162 case TEA5767_LOW_LO_13MHz: 158 case TEA5767_LOW_LO_13MHz:
163 frq = 1000*(div*50+700+225)/4; /* Freq in KHz */ 159 frq = 1000 * (div * 50 + 700 + 225) / 4; /* Freq in KHz */
164 break; 160 break;
165 case TEA5767_LOW_LO_32768: 161 case TEA5767_LOW_LO_32768:
166 frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */ 162 frq = 1000 * (div * 32768 / 1000 + 700 + 225) / 4; /* Freq in KHz */
167 break; 163 break;
168 case TEA5767_HIGH_LO_32768: 164 case TEA5767_HIGH_LO_32768:
169 default: 165 default:
170 frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */ 166 frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4; /* Freq in KHz */
171 break; 167 break;
172 } 168 }
173 buffer[0] = (div>>8) & 0x3f; 169 buffer[0] = (div >> 8) & 0x3f;
174 buffer[1] = div & 0xff; 170 buffer[1] = div & 0xff;
175 171
176 printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", 172 printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
177 frq/1000,frq%1000,div); 173 frq / 1000, frq % 1000, div);
178 174
179 if (TEA5767_STEREO_MASK & buffer[2]) 175 if (TEA5767_STEREO_MASK & buffer[2])
180 printk(PREFIX "Stereo\n"); 176 printk(PREFIX "Stereo\n");
181 else 177 else
182 printk(PREFIX "Mono\n"); 178 printk(PREFIX "Mono\n");
183 179
184 printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK); 180 printk(PREFIX "IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
185 181
186 printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4); 182 printk(PREFIX "ADC Level = %d\n",
183 (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
187 184
188 printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK)); 185 printk(PREFIX "Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
189 186
190 printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK)); 187 printk(PREFIX "Reserved = 0x%02x\n",
188 (buffer[4] & TEA5767_RESERVED_MASK));
191} 189}
192 190
193/* Freq should be specifyed at 62.5 Hz */ 191/* Freq should be specifyed at 62.5 Hz */
194static void set_radio_freq(struct i2c_client *c, unsigned int frq) 192static void set_radio_freq(struct i2c_client *c, unsigned int frq)
195{ 193{
196 struct tuner *t = i2c_get_clientdata(c); 194 struct tuner *t = i2c_get_clientdata(c);
197 unsigned char buffer[5]; 195 unsigned char buffer[5];
198 unsigned div; 196 unsigned div;
199 int rc; 197 int rc;
200 198
201 if ( tuner_debug ) 199 tuner_dbg (PREFIX "radio freq counter %d\n", frq);
202 printk(PREFIX "radio freq counter %d\n",frq);
203 200
204 /* Rounds freq to next decimal value - for 62.5 KHz step */ 201 /* Rounds freq to next decimal value - for 62.5 KHz step */
205 /* frq = 20*(frq/16)+radio_frq[frq%16]; */ 202 /* frq = 20*(frq/16)+radio_frq[frq%16]; */
206 203
207 buffer[2] = TEA5767_PORT1_HIGH; 204 buffer[2] = TEA5767_PORT1_HIGH;
208 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND; 205 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
209 buffer[4]=0; 206 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
207 buffer[4] = 0;
208
209 if (t->mode == T_STANDBY) {
210 tuner_dbg("TEA5767 set to standby mode\n");
211 buffer[3] |= TEA5767_STDBY;
212 }
210 213
211 if (t->audmode == V4L2_TUNER_MODE_MONO) { 214 if (t->audmode == V4L2_TUNER_MODE_MONO) {
212 tuner_dbg("TEA5767 set to mono\n"); 215 tuner_dbg("TEA5767 set to mono\n");
213 buffer[2] |= TEA5767_MONO; 216 buffer[2] |= TEA5767_MONO;
214 } else 217 } else {
215 tuner_dbg("TEA5767 set to stereo\n"); 218 tuner_dbg("TEA5767 set to stereo\n");
219 }
216 220
217 switch (t->type) { 221 /* Should be replaced */
222 switch (TEA5767_HIGH_LO_32768) {
218 case TEA5767_HIGH_LO_13MHz: 223 case TEA5767_HIGH_LO_13MHz:
219 tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); 224 tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
220 buffer[2] |= TEA5767_HIGH_LO_INJECT; 225 buffer[2] |= TEA5767_HIGH_LO_INJECT;
221 buffer[4] |= TEA5767_PLLREF_ENABLE; 226 buffer[4] |= TEA5767_PLLREF_ENABLE;
222 div = (frq*4/16+700+225+25)/50; 227 div = (frq * 4 / 16 + 700 + 225 + 25) / 50;
223 break; 228 break;
224 case TEA5767_LOW_LO_13MHz: 229 case TEA5767_LOW_LO_13MHz:
225 tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); 230 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
226 231
227 buffer[4] |= TEA5767_PLLREF_ENABLE; 232 buffer[4] |= TEA5767_PLLREF_ENABLE;
228 div = (frq*4/16-700-225+25)/50; 233 div = (frq * 4 / 16 - 700 - 225 + 25) / 50;
229 break; 234 break;
230 case TEA5767_LOW_LO_32768: 235 case TEA5767_LOW_LO_32768:
231 tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); 236 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
232 buffer[3] |= TEA5767_XTAL_32768; 237 buffer[3] |= TEA5767_XTAL_32768;
233 /* const 700=4000*175 Khz - to adjust freq to right value */ 238 /* const 700=4000*175 Khz - to adjust freq to right value */
234 div = (1000*(frq*4/16-700-225)+16384)>>15; 239 div = (1000 * (frq * 4 / 16 - 700 - 225) + 16384) >> 15;
235 break; 240 break;
236 case TEA5767_HIGH_LO_32768: 241 case TEA5767_HIGH_LO_32768:
237 default: 242 default:
238 tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n"); 243 tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
239 244
240 buffer[2] |= TEA5767_HIGH_LO_INJECT; 245 buffer[2] |= TEA5767_HIGH_LO_INJECT;
241 buffer[3] |= TEA5767_XTAL_32768; 246 buffer[3] |= TEA5767_XTAL_32768;
242 div = (1000*(frq*4/16+700+225)+16384)>>15; 247 div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15;
243 break; 248 break;
244 } 249 }
245 buffer[0] = (div>>8) & 0x3f; 250 buffer[0] = (div >> 8) & 0x3f;
246 buffer[1] = div & 0xff; 251 buffer[1] = div & 0xff;
247 252
248 if ( tuner_debug ) 253 if (tuner_debug)
249 tea5767_status_dump(buffer); 254 tea5767_status_dump(buffer);
250 255
251 if (5 != (rc = i2c_master_send(c,buffer,5))) 256 if (5 != (rc = i2c_master_send(c, buffer, 5)))
252 tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc); 257 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
253} 258}
254 259
255static int tea5767_signal(struct i2c_client *c) 260static int tea5767_signal(struct i2c_client *c)
@@ -258,11 +263,11 @@ static int tea5767_signal(struct i2c_client *c)
258 int rc; 263 int rc;
259 struct tuner *t = i2c_get_clientdata(c); 264 struct tuner *t = i2c_get_clientdata(c);
260 265
261 memset(buffer,0,sizeof(buffer)); 266 memset(buffer, 0, sizeof(buffer));
262 if (5 != (rc = i2c_master_recv(c,buffer,5))) 267 if (5 != (rc = i2c_master_recv(c, buffer, 5)))
263 tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); 268 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
264 269
265 return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4)); 270 return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4));
266} 271}
267 272
268static int tea5767_stereo(struct i2c_client *c) 273static int tea5767_stereo(struct i2c_client *c)
@@ -271,47 +276,46 @@ static int tea5767_stereo(struct i2c_client *c)
271 int rc; 276 int rc;
272 struct tuner *t = i2c_get_clientdata(c); 277 struct tuner *t = i2c_get_clientdata(c);
273 278
274 memset(buffer,0,sizeof(buffer)); 279 memset(buffer, 0, sizeof(buffer));
275 if (5 != (rc = i2c_master_recv(c,buffer,5))) 280 if (5 != (rc = i2c_master_recv(c, buffer, 5)))
276 tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); 281 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
277 282
278 rc = buffer[2] & TEA5767_STEREO_MASK; 283 rc = buffer[2] & TEA5767_STEREO_MASK;
279 284
280 if ( tuner_debug ) 285 tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
281 tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
282 286
283 return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0); 287 return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
284} 288}
285 289
286int tea_detection(struct i2c_client *c) 290int tea5767_autodetection(struct i2c_client *c)
287{ 291{
288 unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff }; 292 unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff };
289 int rc; 293 int rc;
290 struct tuner *t = i2c_get_clientdata(c); 294 struct tuner *t = i2c_get_clientdata(c);
291 295
292 if (5 != (rc = i2c_master_recv(c,buffer,5))) { 296 if (5 != (rc = i2c_master_recv(c, buffer, 5))) {
293 tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc ); 297 tuner_warn("it is not a TEA5767. Received %i chars.\n", rc);
294 return EINVAL; 298 return EINVAL;
295 } 299 }
296 300
297 /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */ 301 /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */
298 if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && 302 if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
299 buffer[0] == buffer[3] && buffer[0] == buffer[4]) { 303 buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
300 tuner_warn ( "All bytes are equal. It is not a TEA5767\n" ); 304 tuner_warn("All bytes are equal. It is not a TEA5767\n");
301 return EINVAL; 305 return EINVAL;
302 } 306 }
303 307
304 /* Status bytes: 308 /* Status bytes:
305 * Byte 4: bit 3:1 : CI (Chip Identification) == 0 309 * Byte 4: bit 3:1 : CI (Chip Identification) == 0
306 * bit 0 : internally set to 0 310 * bit 0 : internally set to 0
307 * Byte 5: bit 7:0 : == 0 311 * Byte 5: bit 7:0 : == 0
308 */ 312 */
309 313
310 if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { 314 if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
311 tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" ); 315 tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
312 return EINVAL; 316 return EINVAL;
313 } 317 }
314 tuner_warn ( "TEA5767 detected.\n" ); 318 tuner_warn("TEA5767 detected.\n");
315 return 0; 319 return 0;
316} 320}
317 321
@@ -319,16 +323,16 @@ int tea5767_tuner_init(struct i2c_client *c)
319{ 323{
320 struct tuner *t = i2c_get_clientdata(c); 324 struct tuner *t = i2c_get_clientdata(c);
321 325
322 if (tea_detection(c)==EINVAL) return EINVAL; 326 if (tea5767_autodetection(c) == EINVAL)
327 return EINVAL;
323 328
324 tuner_info("type set to %d (%s)\n", 329 tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio");
325 t->type, TEA5767_TUNER_NAME); 330 strlcpy(c->name, "tea5767", sizeof(c->name));
326 strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name));
327 331
328 t->tv_freq = set_tv_freq; 332 t->tv_freq = set_tv_freq;
329 t->radio_freq = set_radio_freq; 333 t->radio_freq = set_radio_freq;
330 t->has_signal = tea5767_signal; 334 t->has_signal = tea5767_signal;
331 t->is_stereo = tea5767_stereo; 335 t->is_stereo = tea5767_stereo;
332 336
333 return (0); 337 return (0);
334} 338}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 6f6bf4a633fc..de190630babb 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $ 2 * $Id: tuner-core.c,v 1.55 2005/07/08 13:20:33 mchehab Exp $
3 * 3 *
4 * i2c tv tuner chip device driver 4 * i2c tv tuner chip device driver
5 * core core, i.e. kernel interfaces, registering and so on 5 * core core, i.e. kernel interfaces, registering and so on
@@ -23,42 +23,36 @@
23#include <media/tuner.h> 23#include <media/tuner.h>
24#include <media/audiochip.h> 24#include <media/audiochip.h>
25 25
26/*
27 * comment line bellow to return to old behavor, where only one I2C device is supported
28 */
29
30#define UNSET (-1U) 26#define UNSET (-1U)
31 27
32/* standard i2c insmod options */ 28/* standard i2c insmod options */
33static unsigned short normal_i2c[] = { 29static unsigned short normal_i2c[] = {
34 0x4b, /* tda8290 */ 30 0x4b, /* tda8290 */
35 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 31 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
36 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 32 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
37 I2C_CLIENT_END 33 I2C_CLIENT_END
38}; 34};
35
39I2C_CLIENT_INSMOD; 36I2C_CLIENT_INSMOD;
40 37
41/* insmod options used at init time => read/only */ 38/* insmod options used at init time => read/only */
42static unsigned int addr = 0; 39static unsigned int addr = 0;
43module_param(addr, int, 0444); 40module_param(addr, int, 0444);
44 41
45/* insmod options used at runtime => read/write */ 42/* insmod options used at runtime => read/write */
46unsigned int tuner_debug = 0; 43unsigned int tuner_debug = 0;
47module_param(tuner_debug, int, 0644); 44module_param(tuner_debug, int, 0644);
48 45
49static unsigned int tv_range[2] = { 44, 958 }; 46static unsigned int tv_range[2] = { 44, 958 };
50static unsigned int radio_range[2] = { 65, 108 }; 47static unsigned int radio_range[2] = { 65, 108 };
51 48
52module_param_array(tv_range, int, NULL, 0644); 49module_param_array(tv_range, int, NULL, 0644);
53module_param_array(radio_range, int, NULL, 0644); 50module_param_array(radio_range, int, NULL, 0644);
54 51
55MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners"); 52MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
56MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); 53MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
57MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
58 55
59static int this_adap;
60static unsigned short first_tuner, tv_tuner, radio_tuner;
61
62static struct i2c_driver driver; 56static struct i2c_driver driver;
63static struct i2c_client client_template; 57static struct i2c_client client_template;
64 58
@@ -70,18 +64,19 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
70 struct tuner *t = i2c_get_clientdata(c); 64 struct tuner *t = i2c_get_clientdata(c);
71 65
72 if (t->type == UNSET) { 66 if (t->type == UNSET) {
73 tuner_info("tuner type not set\n"); 67 tuner_warn ("tuner type not set\n");
74 return; 68 return;
75 } 69 }
76 if (NULL == t->tv_freq) { 70 if (NULL == t->tv_freq) {
77 tuner_info("Huh? tv_set is NULL?\n"); 71 tuner_warn ("Tuner has no way to set tv freq\n");
78 return; 72 return;
79 } 73 }
80 if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { 74 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
81 tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", 75 tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
82 freq/16,freq%16*100/16,tv_range[0],tv_range[1]); 76 freq / 16, freq % 16 * 100 / 16, tv_range[0],
77 tv_range[1]);
83 } 78 }
84 t->tv_freq(c,freq); 79 t->tv_freq(c, freq);
85} 80}
86 81
87static void set_radio_freq(struct i2c_client *c, unsigned int freq) 82static void set_radio_freq(struct i2c_client *c, unsigned int freq)
@@ -89,24 +84,20 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
89 struct tuner *t = i2c_get_clientdata(c); 84 struct tuner *t = i2c_get_clientdata(c);
90 85
91 if (t->type == UNSET) { 86 if (t->type == UNSET) {
92 tuner_info("tuner type not set\n"); 87 tuner_warn ("tuner type not set\n");
93 return; 88 return;
94 } 89 }
95 if (NULL == t->radio_freq) { 90 if (NULL == t->radio_freq) {
96 tuner_info("no radio tuning for this one, sorry.\n"); 91 tuner_warn ("tuner has no way to set radio frequency\n");
97 return; 92 return;
98 } 93 }
99 if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) { 94 if (freq <= radio_range[0] * 16000 || freq >= radio_range[1] * 16000) {
100 if (tuner_debug) 95 tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
101 tuner_info("radio freq step 62.5Hz (%d.%06d)\n", 96 freq / 16000, freq % 16000 * 100 / 16000,
102 freq/16000,freq%16000*1000/16); 97 radio_range[0], radio_range[1]);
103 t->radio_freq(c,freq);
104 } else {
105 tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
106 freq/16,freq%16*100/16,
107 radio_range[0],radio_range[1]);
108 } 98 }
109 99
100 t->radio_freq(c, freq);
110 return; 101 return;
111} 102}
112 103
@@ -117,42 +108,45 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
117 switch (t->mode) { 108 switch (t->mode) {
118 case V4L2_TUNER_RADIO: 109 case V4L2_TUNER_RADIO:
119 tuner_dbg("radio freq set to %lu.%02lu\n", 110 tuner_dbg("radio freq set to %lu.%02lu\n",
120 freq/16,freq%16*100/16); 111 freq / 16000, freq % 16000 * 100 / 16000);
121 set_radio_freq(c,freq); 112 set_radio_freq(c, freq);
122 break; 113 break;
123 case V4L2_TUNER_ANALOG_TV: 114 case V4L2_TUNER_ANALOG_TV:
124 case V4L2_TUNER_DIGITAL_TV: 115 case V4L2_TUNER_DIGITAL_TV:
125 tuner_dbg("tv freq set to %lu.%02lu\n", 116 tuner_dbg("tv freq set to %lu.%02lu\n",
126 freq/16,freq%16*100/16); 117 freq / 16, freq % 16 * 100 / 16);
127 set_tv_freq(c, freq); 118 set_tv_freq(c, freq);
128 break; 119 break;
129 } 120 }
130 t->freq = freq; 121 t->freq = freq;
131} 122}
132 123
133static void set_type(struct i2c_client *c, unsigned int type) 124static void set_type(struct i2c_client *c, unsigned int type,
125 unsigned int new_mode_mask)
134{ 126{
135 struct tuner *t = i2c_get_clientdata(c); 127 struct tuner *t = i2c_get_clientdata(c);
136 unsigned char buffer[4]; 128 unsigned char buffer[4];
137 129
138 /* sanity check */ 130 if (type == UNSET || type == TUNER_ABSENT) {
139 if (type == UNSET || type == TUNER_ABSENT) 131 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
140 return; 132 return;
141 if (type >= tuner_count) 133 }
134
135 if (type >= tuner_count) {
136 tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count);
142 return; 137 return;
138 }
143 139
140 /* This code detects calls by card attach_inform */
144 if (NULL == t->i2c.dev.driver) { 141 if (NULL == t->i2c.dev.driver) {
145 /* not registered yet */ 142 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
146 t->type = type; 143
144 t->type=type;
147 return; 145 return;
148 } 146 }
149 if ((t->initialized) && (t->type == type))
150 /* run only once except type change Hac 04/05*/
151 return;
152
153 t->initialized = 1;
154 147
155 t->type = type; 148 t->type = type;
149
156 switch (t->type) { 150 switch (t->type) {
157 case TUNER_MT2032: 151 case TUNER_MT2032:
158 microtune_init(c); 152 microtune_init(c);
@@ -161,136 +155,194 @@ static void set_type(struct i2c_client *c, unsigned int type)
161 tda8290_init(c); 155 tda8290_init(c);
162 break; 156 break;
163 case TUNER_TEA5767: 157 case TUNER_TEA5767:
164 if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT; 158 if (tea5767_tuner_init(c) == EINVAL) {
159 t->type = TUNER_ABSENT;
160 t->mode_mask = T_UNINITIALIZED;
161 return;
162 }
163 t->mode_mask = T_RADIO;
165 break; 164 break;
166 case TUNER_PHILIPS_FMD1216ME_MK3: 165 case TUNER_PHILIPS_FMD1216ME_MK3:
167 buffer[0] = 0x0b; 166 buffer[0] = 0x0b;
168 buffer[1] = 0xdc; 167 buffer[1] = 0xdc;
169 buffer[2] = 0x9c; 168 buffer[2] = 0x9c;
170 buffer[3] = 0x60; 169 buffer[3] = 0x60;
171 i2c_master_send(c,buffer,4); 170 i2c_master_send(c, buffer, 4);
172 mdelay(1); 171 mdelay(1);
173 buffer[2] = 0x86; 172 buffer[2] = 0x86;
174 buffer[3] = 0x54; 173 buffer[3] = 0x54;
175 i2c_master_send(c,buffer,4); 174 i2c_master_send(c, buffer, 4);
176 default_tuner_init(c); 175 default_tuner_init(c);
177 break; 176 break;
178 default: 177 default:
179 /* TEA5767 autodetection code */
180 if (tea5767_tuner_init(c)!=EINVAL) {
181 t->type = TUNER_TEA5767;
182 if (first_tuner == 0x60)
183 first_tuner++;
184 break;
185 }
186
187 default_tuner_init(c); 178 default_tuner_init(c);
188 break; 179 break;
189 } 180 }
190 tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); 181
182 if (t->mode_mask == T_UNINITIALIZED)
183 t->mode_mask = new_mode_mask;
184
185 set_freq(c, t->freq);
186 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
187 c->adapter->name, c->driver->name, c->addr << 1, type,
188 t->mode_mask);
191} 189}
192 190
193#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ 191/*
194 return 0; } else if (tuner_debug) \ 192 * This function apply tuner config to tuner specified
195 tuner_info ("Cmd %s accepted to "tun"\n",cmd); 193 * by tun_setup structure. I addr is unset, then admin status
196#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ 194 * and tun addr status is more precise then current status,
197 CHECK_ADDR(radio_tuner,cmd,"radio") } else \ 195 * it's applied. Otherwise status and type are applied only to
198 { CHECK_ADDR(tv_tuner,cmd,"TV"); } 196 * tuner with exactly the same addr.
197*/
198
199static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
200{
201 struct tuner *t = i2c_get_clientdata(c);
202
203 if (tun_setup->addr == ADDR_UNSET) {
204 if (t->mode_mask & tun_setup->mode_mask)
205 set_type(c, tun_setup->type, tun_setup->mode_mask);
206 } else if (tun_setup->addr == c->addr) {
207 set_type(c, tun_setup->type, tun_setup->mode_mask);
208 }
209}
199 210
200static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) 211static inline int check_mode(struct tuner *t, char *cmd)
201{ 212{
202 /* ADDR_UNSET defaults to first available tuner */ 213 if (1 << t->mode & t->mode_mask) {
203 if ( tun_addr->addr == ADDR_UNSET ) { 214 switch (t->mode) {
204 if (first_tuner != c->addr)
205 return;
206 switch (tun_addr->v4l2_tuner) {
207 case V4L2_TUNER_RADIO: 215 case V4L2_TUNER_RADIO:
208 radio_tuner=c->addr; 216 tuner_dbg("Cmd %s accepted for radio\n", cmd);
209 break; 217 break;
210 default: 218 case V4L2_TUNER_ANALOG_TV:
211 tv_tuner=c->addr; 219 tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
220 break;
221 case V4L2_TUNER_DIGITAL_TV:
222 tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
212 break; 223 break;
213 } 224 }
214 } else { 225 return 0;
215 /* Sets tuner to its configured value */
216 switch (tun_addr->v4l2_tuner) {
217 case V4L2_TUNER_RADIO:
218 radio_tuner=tun_addr->addr;
219 if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
220 return;
221 default:
222 tv_tuner=tun_addr->addr;
223 if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
224 return;
225 }
226 } 226 }
227 set_type(c,tun_addr->type); 227 return EINVAL;
228} 228}
229 229
230static char pal[] = "-"; 230static char pal[] = "-";
231module_param_string(pal, pal, sizeof(pal), 0644); 231module_param_string(pal, pal, sizeof(pal), 0644);
232static char secam[] = "-";
233module_param_string(secam, secam, sizeof(secam), 0644);
232 234
235/* get more precise norm info from insmod option */
233static int tuner_fixup_std(struct tuner *t) 236static int tuner_fixup_std(struct tuner *t)
234{ 237{
235 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { 238 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
236 /* get more precise norm info from insmod option */
237 switch (pal[0]) { 239 switch (pal[0]) {
238 case 'b': 240 case 'b':
239 case 'B': 241 case 'B':
240 case 'g': 242 case 'g':
241 case 'G': 243 case 'G':
242 tuner_dbg("insmod fixup: PAL => PAL-BG\n"); 244 tuner_dbg ("insmod fixup: PAL => PAL-BG\n");
243 t->std = V4L2_STD_PAL_BG; 245 t->std = V4L2_STD_PAL_BG;
244 break; 246 break;
245 case 'i': 247 case 'i':
246 case 'I': 248 case 'I':
247 tuner_dbg("insmod fixup: PAL => PAL-I\n"); 249 tuner_dbg ("insmod fixup: PAL => PAL-I\n");
248 t->std = V4L2_STD_PAL_I; 250 t->std = V4L2_STD_PAL_I;
249 break; 251 break;
250 case 'd': 252 case 'd':
251 case 'D': 253 case 'D':
252 case 'k': 254 case 'k':
253 case 'K': 255 case 'K':
254 tuner_dbg("insmod fixup: PAL => PAL-DK\n"); 256 tuner_dbg ("insmod fixup: PAL => PAL-DK\n");
255 t->std = V4L2_STD_PAL_DK; 257 t->std = V4L2_STD_PAL_DK;
256 break; 258 break;
259 case 'M':
260 case 'm':
261 tuner_dbg ("insmod fixup: PAL => PAL-M\n");
262 t->std = V4L2_STD_PAL_M;
263 break;
264 case 'N':
265 case 'n':
266 tuner_dbg ("insmod fixup: PAL => PAL-N\n");
267 t->std = V4L2_STD_PAL_N;
268 break;
257 } 269 }
258 } 270 }
271 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
272 switch (secam[0]) {
273 case 'd':
274 case 'D':
275 case 'k':
276 case 'K':
277 tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n");
278 t->std = V4L2_STD_SECAM_DK;
279 break;
280 case 'l':
281 case 'L':
282 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
283 t->std = V4L2_STD_SECAM_L;
284 break;
285 }
286 }
287
259 return 0; 288 return 0;
260} 289}
261 290
262/* ---------------------------------------------------------------------- */ 291/* ---------------------------------------------------------------------- */
263 292
293/* static var Used only in tuner_attach and tuner_probe */
294static unsigned default_mode_mask;
295
296/* During client attach, set_type is called by adapter's attach_inform callback.
297 set_type must then be completed by tuner_attach.
298 */
264static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) 299static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
265{ 300{
266 struct tuner *t; 301 struct tuner *t;
267 302
268 /* by default, first I2C card is both tv and radio tuner */ 303 client_template.adapter = adap;
269 if (this_adap == 0) { 304 client_template.addr = addr;
270 first_tuner = addr;
271 tv_tuner = addr;
272 radio_tuner = addr;
273 }
274 this_adap++;
275
276 client_template.adapter = adap;
277 client_template.addr = addr;
278 305
279 t = kmalloc(sizeof(struct tuner),GFP_KERNEL); 306 t = kmalloc(sizeof(struct tuner), GFP_KERNEL);
280 if (NULL == t) 307 if (NULL == t)
281 return -ENOMEM; 308 return -ENOMEM;
282 memset(t,0,sizeof(struct tuner)); 309 memset(t, 0, sizeof(struct tuner));
283 memcpy(&t->i2c,&client_template,sizeof(struct i2c_client)); 310 memcpy(&t->i2c, &client_template, sizeof(struct i2c_client));
284 i2c_set_clientdata(&t->i2c, t); 311 i2c_set_clientdata(&t->i2c, t);
285 t->type = UNSET; 312 t->type = UNSET;
286 t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */ 313 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
287 t->audmode = V4L2_TUNER_MODE_STEREO; 314 t->audmode = V4L2_TUNER_MODE_STEREO;
315 t->mode_mask = T_UNINITIALIZED;
316
317
318 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
319
320 /* TEA5767 autodetection code - only for addr = 0xc0 */
321 if (addr == 0x60) {
322 if (tea5767_autodetection(&t->i2c) != EINVAL) {
323 t->type = TUNER_TEA5767;
324 t->mode_mask = T_RADIO;
325 t->mode = T_STANDBY;
326 t->freq = 87.5 * 16; /* Sets freq to FM range */
327 default_mode_mask &= ~T_RADIO;
328
329 i2c_attach_client (&t->i2c);
330 set_type(&t->i2c,t->type, t->mode_mask);
331 return 0;
332 }
333 }
288 334
289 i2c_attach_client(&t->i2c); 335 /* Initializes only the first adapter found */
290 tuner_info("chip found @ 0x%x (%s)\n", 336 if (default_mode_mask != T_UNINITIALIZED) {
291 addr << 1, adap->name); 337 tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask);
338 t->mode_mask = default_mode_mask;
339 t->freq = 400 * 16; /* Sets freq to VHF High */
340 default_mode_mask = T_UNINITIALIZED;
341 }
292 342
293 set_type(&t->i2c, t->type); 343 /* Should be just before return */
344 i2c_attach_client (&t->i2c);
345 set_type (&t->i2c,t->type, t->mode_mask);
294 return 0; 346 return 0;
295} 347}
296 348
@@ -300,11 +352,8 @@ static int tuner_probe(struct i2c_adapter *adap)
300 normal_i2c[0] = addr; 352 normal_i2c[0] = addr;
301 normal_i2c[1] = I2C_CLIENT_END; 353 normal_i2c[1] = I2C_CLIENT_END;
302 } 354 }
303 this_adap = 0;
304 355
305 first_tuner = 0; 356 default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
306 tv_tuner = 0;
307 radio_tuner = 0;
308 357
309 if (adap->class & I2C_CLASS_TV_ANALOG) 358 if (adap->class & I2C_CLASS_TV_ANALOG)
310 return i2c_probe(adap, &addr_data, tuner_attach); 359 return i2c_probe(adap, &addr_data, tuner_attach);
@@ -316,9 +365,10 @@ static int tuner_detach(struct i2c_client *client)
316 struct tuner *t = i2c_get_clientdata(client); 365 struct tuner *t = i2c_get_clientdata(client);
317 int err; 366 int err;
318 367
319 err=i2c_detach_client(&t->i2c); 368 err = i2c_detach_client(&t->i2c);
320 if (err) { 369 if (err) {
321 tuner_warn ("Client deregistration failed, client not detached.\n"); 370 tuner_warn
371 ("Client deregistration failed, client not detached.\n");
322 return err; 372 return err;
323 } 373 }
324 374
@@ -326,37 +376,65 @@ static int tuner_detach(struct i2c_client *client)
326 return 0; 376 return 0;
327} 377}
328 378
329#define SWITCH_V4L2 if (!t->using_v4l2 && tuner_debug) \ 379/*
330 tuner_info("switching to v4l2\n"); \ 380 * Switch tuner to other mode. If tuner support both tv and radio,
331 t->using_v4l2 = 1; 381 * set another frequency to some value (This is needed for some pal
332#define CHECK_V4L2 if (t->using_v4l2) { if (tuner_debug) \ 382 * tuners to avoid locking). Otherwise, just put second tuner in
333 tuner_info("ignore v4l1 call\n"); \ 383 * standby mode.
334 return 0; } 384 */
385
386static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
387{
388 if (mode != t->mode) {
389
390 t->mode = mode;
391 if (check_mode(t, cmd) == EINVAL) {
392 t->mode = T_STANDBY;
393 if (V4L2_TUNER_RADIO == mode) {
394 set_tv_freq(client, 400 * 16);
395 } else {
396 set_radio_freq(client, 87.5 * 16000);
397 }
398 return EINVAL;
399 }
400 }
401 return 0;
402}
403
404#define switch_v4l2() if (!t->using_v4l2) \
405 tuner_dbg("switching to v4l2\n"); \
406 t->using_v4l2 = 1;
407
408static inline int check_v4l2(struct tuner *t)
409{
410 if (t->using_v4l2) {
411 tuner_dbg ("ignore v4l1 call\n");
412 return EINVAL;
413 }
414 return 0;
415}
335 416
336static int 417static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
337tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
338{ 418{
339 struct tuner *t = i2c_get_clientdata(client); 419 struct tuner *t = i2c_get_clientdata(client);
340 unsigned int *iarg = (int*)arg; 420 unsigned int *iarg = (int *)arg;
341 421
342 switch (cmd) { 422 switch (cmd) {
343 /* --- configuration --- */ 423 /* --- configuration --- */
344 case TUNER_SET_TYPE:
345 set_type(client,*iarg);
346 break;
347 case TUNER_SET_TYPE_ADDR: 424 case TUNER_SET_TYPE_ADDR:
348 set_addr(client,(struct tuner_addr *)arg); 425 tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x\n",
426 ((struct tuner_setup *)arg)->type,
427 ((struct tuner_setup *)arg)->addr,
428 ((struct tuner_setup *)arg)->mode_mask);
429
430 set_addr(client, (struct tuner_setup *)arg);
349 break; 431 break;
350 case AUDC_SET_RADIO: 432 case AUDC_SET_RADIO:
351 t->mode = V4L2_TUNER_RADIO; 433 set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO");
352 CHECK_ADDR(tv_tuner,"AUDC_SET_RADIO","TV");
353
354 if (V4L2_TUNER_RADIO != t->mode) {
355 set_tv_freq(client,400 * 16);
356 }
357 break; 434 break;
358 case AUDC_CONFIG_PINNACLE: 435 case AUDC_CONFIG_PINNACLE:
359 CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE","TV"); 436 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
437 return 0;
360 switch (*iarg) { 438 switch (*iarg) {
361 case 2: 439 case 2:
362 tuner_dbg("pinnacle pal\n"); 440 tuner_dbg("pinnacle pal\n");
@@ -368,219 +446,238 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
368 break; 446 break;
369 } 447 }
370 break; 448 break;
449 case TDA9887_SET_CONFIG:
450 break;
371 /* --- v4l ioctls --- */ 451 /* --- v4l ioctls --- */
372 /* take care: bttv does userspace copying, we'll get a 452 /* take care: bttv does userspace copying, we'll get a
373 kernel pointer here... */ 453 kernel pointer here... */
374 case VIDIOCSCHAN: 454 case VIDIOCSCHAN:
375 { 455 {
376 static const v4l2_std_id map[] = { 456 static const v4l2_std_id map[] = {
377 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL, 457 [VIDEO_MODE_PAL] = V4L2_STD_PAL,
378 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M, 458 [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
379 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM, 459 [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
380 [ 4 /* bttv */ ] = V4L2_STD_PAL_M, 460 [4 /* bttv */ ] = V4L2_STD_PAL_M,
381 [ 5 /* bttv */ ] = V4L2_STD_PAL_N, 461 [5 /* bttv */ ] = V4L2_STD_PAL_N,
382 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, 462 [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
383 }; 463 };
384 struct video_channel *vc = arg; 464 struct video_channel *vc = arg;
385 465
386 CHECK_V4L2; 466 if (check_v4l2(t) == EINVAL)
387 t->mode = V4L2_TUNER_ANALOG_TV; 467 return 0;
388 CHECK_ADDR(tv_tuner,"VIDIOCSCHAN","TV"); 468
389 469 if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL)
390 if (vc->norm < ARRAY_SIZE(map)) 470 return 0;
391 t->std = map[vc->norm]; 471
392 tuner_fixup_std(t); 472 if (vc->norm < ARRAY_SIZE(map))
393 if (t->freq) 473 t->std = map[vc->norm];
394 set_tv_freq(client,t->freq); 474 tuner_fixup_std(t);
395 return 0; 475 if (t->freq)
396 } 476 set_tv_freq(client, t->freq);
477 return 0;
478 }
397 case VIDIOCSFREQ: 479 case VIDIOCSFREQ:
398 { 480 {
399 unsigned long *v = arg; 481 unsigned long *v = arg;
400 482
401 CHECK_MODE("VIDIOCSFREQ"); 483 if (check_mode(t, "VIDIOCSFREQ") == EINVAL)
402 CHECK_V4L2; 484 return 0;
403 set_freq(client,*v); 485 if (check_v4l2(t) == EINVAL)
404 return 0; 486 return 0;
405 } 487
488 set_freq(client, *v);
489 return 0;
490 }
406 case VIDIOCGTUNER: 491 case VIDIOCGTUNER:
407 { 492 {
408 struct video_tuner *vt = arg; 493 struct video_tuner *vt = arg;
409 494
410 CHECK_ADDR(radio_tuner,"VIDIOCGTUNER","radio"); 495 if (check_mode(t, "VIDIOCGTUNER") == EINVAL)
411 CHECK_V4L2; 496 return 0;
412 if (V4L2_TUNER_RADIO == t->mode) { 497 if (check_v4l2(t) == EINVAL)
413 if (t->has_signal) 498 return 0;
414 vt->signal = t->has_signal(client); 499
415 if (t->is_stereo) { 500 if (V4L2_TUNER_RADIO == t->mode) {
416 if (t->is_stereo(client)) 501 if (t->has_signal)
417 vt->flags |= VIDEO_TUNER_STEREO_ON; 502 vt->signal = t->has_signal(client);
418 else 503 if (t->is_stereo) {
419 vt->flags &= ~VIDEO_TUNER_STEREO_ON; 504 if (t->is_stereo(client))
420 } 505 vt->flags |=
421 vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */ 506 VIDEO_TUNER_STEREO_ON;
507 else
508 vt->flags &=
509 ~VIDEO_TUNER_STEREO_ON;
510 }
511 vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
422 512
423 vt->rangelow = radio_range[0] * 16000; 513 vt->rangelow = radio_range[0] * 16000;
424 vt->rangehigh = radio_range[1] * 16000; 514 vt->rangehigh = radio_range[1] * 16000;
425 515
426 } else { 516 } else {
427 vt->rangelow = tv_range[0] * 16; 517 vt->rangelow = tv_range[0] * 16;
428 vt->rangehigh = tv_range[1] * 16; 518 vt->rangehigh = tv_range[1] * 16;
429 } 519 }
430 520
431 return 0; 521 return 0;
432 } 522 }
433 case VIDIOCGAUDIO: 523 case VIDIOCGAUDIO:
434 { 524 {
435 struct video_audio *va = arg; 525 struct video_audio *va = arg;
436 526
437 CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO","radio"); 527 if (check_mode(t, "VIDIOCGAUDIO") == EINVAL)
438 CHECK_V4L2; 528 return 0;
439 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo) 529 if (check_v4l2(t) == EINVAL)
440 va->mode = t->is_stereo(client) 530 return 0;
441 ? VIDEO_SOUND_STEREO 531
442 : VIDEO_SOUND_MONO; 532 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
443 return 0; 533 va->mode = t->is_stereo(client)
444 } 534 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
535 return 0;
536 }
445 537
446 case VIDIOC_S_STD: 538 case VIDIOC_S_STD:
447 { 539 {
448 v4l2_std_id *id = arg; 540 v4l2_std_id *id = arg;
449 541
450 SWITCH_V4L2; 542 if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
451 t->mode = V4L2_TUNER_ANALOG_TV; 543 == EINVAL)
452 CHECK_ADDR(tv_tuner,"VIDIOC_S_STD","TV"); 544 return 0;
453 545
454 t->std = *id; 546 switch_v4l2();
455 tuner_fixup_std(t); 547
456 if (t->freq) 548 t->std = *id;
457 set_freq(client,t->freq); 549 tuner_fixup_std(t);
458 break; 550 if (t->freq)
459 } 551 set_freq(client, t->freq);
552 break;
553 }
460 case VIDIOC_S_FREQUENCY: 554 case VIDIOC_S_FREQUENCY:
461 { 555 {
462 struct v4l2_frequency *f = arg; 556 struct v4l2_frequency *f = arg;
463 557
464 CHECK_MODE("VIDIOC_S_FREQUENCY"); 558 t->freq = f->frequency;
465 SWITCH_V4L2; 559 switch_v4l2();
466 if (V4L2_TUNER_RADIO == f->type && 560 if (V4L2_TUNER_RADIO == f->type &&
467 V4L2_TUNER_RADIO != t->mode) 561 V4L2_TUNER_RADIO != t->mode) {
468 set_tv_freq(client,400*16); 562 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
469 t->mode = f->type; 563 == EINVAL)
470 set_freq(client,f->frequency); 564 return 0;
471 break; 565 }
472 } 566 set_freq(client,t->freq);
473 case VIDIOC_G_FREQUENCY:
474 {
475 struct v4l2_frequency *f = arg;
476 567
477 CHECK_MODE("VIDIOC_G_FREQUENCY"); 568 break;
478 SWITCH_V4L2; 569 }
479 f->type = t->mode; 570 case VIDIOC_G_FREQUENCY:
480 f->frequency = t->freq; 571 {
481 break; 572 struct v4l2_frequency *f = arg;
482 } 573
574 if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL)
575 return 0;
576 switch_v4l2();
577 f->type = t->mode;
578 f->frequency = t->freq;
579 break;
580 }
483 case VIDIOC_G_TUNER: 581 case VIDIOC_G_TUNER:
484 { 582 {
485 struct v4l2_tuner *tuner = arg; 583 struct v4l2_tuner *tuner = arg;
486 584
487 CHECK_MODE("VIDIOC_G_TUNER"); 585 if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL)
488 SWITCH_V4L2; 586 return 0;
489 if (V4L2_TUNER_RADIO == t->mode) { 587 switch_v4l2();
490 if (t->has_signal) 588
491 tuner -> signal = t->has_signal(client); 589 if (V4L2_TUNER_RADIO == t->mode) {
492 if (t->is_stereo) { 590
493 if (t->is_stereo(client)) { 591 if (t->has_signal)
494 tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; 592 tuner->signal = t->has_signal(client);
495 } else { 593
496 tuner -> rxsubchans = V4L2_TUNER_SUB_MONO; 594 if (t->is_stereo) {
595 if (t->is_stereo(client)) {
596 tuner->rxsubchans =
597 V4L2_TUNER_SUB_STEREO |
598 V4L2_TUNER_SUB_MONO;
599 } else {
600 tuner->rxsubchans =
601 V4L2_TUNER_SUB_MONO;
602 }
497 } 603 }
604
605 tuner->capability |=
606 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
607
608 tuner->audmode = t->audmode;
609
610 tuner->rangelow = radio_range[0] * 16000;
611 tuner->rangehigh = radio_range[1] * 16000;
612 } else {
613 tuner->rangelow = tv_range[0] * 16;
614 tuner->rangehigh = tv_range[1] * 16;
498 } 615 }
499 tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 616 break;
500 tuner->audmode = t->audmode; 617 }
501 618 case VIDIOC_S_TUNER:
502 tuner->rangelow = radio_range[0] * 16000; 619 {
503 tuner->rangehigh = radio_range[1] * 16000; 620 struct v4l2_tuner *tuner = arg;
504 } else { 621
505 tuner->rangelow = tv_range[0] * 16; 622 if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL)
506 tuner->rangehigh = tv_range[1] * 16; 623 return 0;
624
625 switch_v4l2();
626
627 if (V4L2_TUNER_RADIO == t->mode) {
628 t->audmode = tuner->audmode;
629 set_radio_freq(client, t->freq);
630 }
631 break;
507 } 632 }
508 break;
509 }
510 case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */
511 {
512 struct v4l2_tuner *tuner = arg;
513
514 CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio");
515 SWITCH_V4L2;
516
517 /* To switch the audio mode, applications initialize the
518 index and audmode fields and the reserved array and
519 call the VIDIOC_S_TUNER ioctl. */
520 /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO,
521 V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2,
522 V4L2_TUNER_MODE_SAP */
523
524 if (tuner->audmode == V4L2_TUNER_MODE_MONO)
525 t->audmode = V4L2_TUNER_MODE_MONO;
526 else
527 t->audmode = V4L2_TUNER_MODE_STEREO;
528
529 set_radio_freq(client, t->freq);
530 break;
531 }
532 case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */
533 break;
534 default: 633 default:
535 tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); 634 tuner_dbg("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
536 /* nothing */
537 break; 635 break;
538 } 636 }
539 637
540 return 0; 638 return 0;
541} 639}
542 640
543static int tuner_suspend(struct device * dev, u32 state, u32 level) 641static int tuner_suspend(struct device *dev, u32 state, u32 level)
544{ 642{
545 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 643 struct i2c_client *c = container_of (dev, struct i2c_client, dev);
546 struct tuner *t = i2c_get_clientdata(c); 644 struct tuner *t = i2c_get_clientdata (c);
547 645
548 tuner_dbg("suspend\n"); 646 tuner_dbg ("suspend\n");
549 /* FIXME: power down ??? */ 647 /* FIXME: power down ??? */
550 return 0; 648 return 0;
551} 649}
552 650
553static int tuner_resume(struct device * dev, u32 level) 651static int tuner_resume(struct device *dev, u32 level)
554{ 652{
555 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 653 struct i2c_client *c = container_of (dev, struct i2c_client, dev);
556 struct tuner *t = i2c_get_clientdata(c); 654 struct tuner *t = i2c_get_clientdata (c);
557 655
558 tuner_dbg("resume\n"); 656 tuner_dbg ("resume\n");
559 if (t->freq) 657 if (t->freq)
560 set_freq(c,t->freq); 658 set_freq(c, t->freq);
561 return 0; 659 return 0;
562} 660}
563 661
564/* ----------------------------------------------------------------------- */ 662/* ----------------------------------------------------------------------- */
565 663
566static struct i2c_driver driver = { 664static struct i2c_driver driver = {
567 .owner = THIS_MODULE, 665 .owner = THIS_MODULE,
568 .name = "tuner", 666 .name = "tuner",
569 .id = I2C_DRIVERID_TUNER, 667 .id = I2C_DRIVERID_TUNER,
570 .flags = I2C_DF_NOTIFY, 668 .flags = I2C_DF_NOTIFY,
571 .attach_adapter = tuner_probe, 669 .attach_adapter = tuner_probe,
572 .detach_client = tuner_detach, 670 .detach_client = tuner_detach,
573 .command = tuner_command, 671 .command = tuner_command,
574 .driver = { 672 .driver = {
575 .suspend = tuner_suspend, 673 .suspend = tuner_suspend,
576 .resume = tuner_resume, 674 .resume = tuner_resume,
577 }, 675 },
578}; 676};
579static struct i2c_client client_template = 677static struct i2c_client client_template = {
580{
581 I2C_DEVNAME("(tuner unset)"), 678 I2C_DEVNAME("(tuner unset)"),
582 .flags = I2C_CLIENT_ALLOW_USE, 679 .flags = I2C_CLIENT_ALLOW_USE,
583 .driver = &driver, 680 .driver = &driver,
584}; 681};
585 682
586static int __init tuner_init_module(void) 683static int __init tuner_init_module(void)
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index c39ed6226ee0..a3f8e83f5314 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $ 2 * $Id: tuner-simple.c,v 1.39 2005/07/07 01:49:30 mkrufky Exp $
3 * 3 *
4 * i2c tv tuner chip device driver 4 * i2c tv tuner chip device driver
5 * controls all those simple 4-control-bytes style tuners. 5 * controls all those simple 4-control-bytes style tuners.
@@ -54,6 +54,27 @@
54#define PHILIPS_MF_SET_PAL_L 0x03 // France 54#define PHILIPS_MF_SET_PAL_L 0x03 // France
55#define PHILIPS_MF_SET_PAL_L2 0x02 // L' 55#define PHILIPS_MF_SET_PAL_L2 0x02 // L'
56 56
57/* Control byte */
58
59#define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */
60#define TUNER_RATIO_SELECT_50 0x00
61#define TUNER_RATIO_SELECT_32 0x02
62#define TUNER_RATIO_SELECT_166 0x04
63#define TUNER_RATIO_SELECT_62 0x06
64
65#define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */
66
67/* Status byte */
68
69#define TUNER_POR 0x80
70#define TUNER_FL 0x40
71#define TUNER_MODE 0x38
72#define TUNER_AFC 0x07
73#define TUNER_SIGNAL 0x07
74#define TUNER_STEREO 0x10
75
76#define TUNER_PLL_LOCKED 0x40
77#define TUNER_STEREO_MK3 0x04
57 78
58/* ---------------------------------------------------------------------- */ 79/* ---------------------------------------------------------------------- */
59 80
@@ -211,21 +232,17 @@ static struct tunertype tuners[] = {
211 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 232 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
212 { "Philips FQ1236A MK4", Philips, NTSC, 233 { "Philips FQ1236A MK4", Philips, NTSC,
213 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 234 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
214 235 { "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC,
215 /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
216 { "Ymec TVision TVF-8531MF", Philips, NTSC,
217 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 236 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
218 { "Ymec TVision TVF-5533MF", Philips, NTSC, 237 { "Ymec TVision TVF-5533MF", Philips, NTSC,
219 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 238 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
239
220 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 240 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
221 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 241 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
222 /* Should work for TNF9533-D/IF, TNF9533-B/DF */ 242 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
223 { "Tena TNF9533-D/IF", Philips, PAL,
224 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, 243 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
225 244 { "Philips TEA5767HN FM Radio", Philips, RADIO,
226 /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */ 245 /* see tea5767.c for details */},
227 { TEA5767_TUNER_NAME, Philips, RADIO,
228 -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
229 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 246 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
230 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 247 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
231}; 248};
@@ -244,15 +261,6 @@ static int tuner_getstatus(struct i2c_client *c)
244 return byte; 261 return byte;
245} 262}
246 263
247#define TUNER_POR 0x80
248#define TUNER_FL 0x40
249#define TUNER_MODE 0x38
250#define TUNER_AFC 0x07
251
252#define TUNER_STEREO 0x10 /* radio mode */
253#define TUNER_STEREO_MK3 0x04 /* radio mode */
254#define TUNER_SIGNAL 0x07 /* radio mode */
255
256static int tuner_signal(struct i2c_client *c) 264static int tuner_signal(struct i2c_client *c)
257{ 265{
258 return (tuner_getstatus(c) & TUNER_SIGNAL) << 13; 266 return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
@@ -278,22 +286,6 @@ static int tuner_stereo(struct i2c_client *c)
278 return stereo; 286 return stereo;
279} 287}
280 288
281#if 0 /* unused */
282static int tuner_islocked (struct i2c_client *c)
283{
284 return (tuner_getstatus (c) & TUNER_FL);
285}
286
287static int tuner_afcstatus (struct i2c_client *c)
288{
289 return (tuner_getstatus (c) & TUNER_AFC) - 2;
290}
291
292static int tuner_mode (struct i2c_client *c)
293{
294 return (tuner_getstatus (c) & TUNER_MODE) >> 3;
295}
296#endif
297 289
298/* ---------------------------------------------------------------------- */ 290/* ---------------------------------------------------------------------- */
299 291
@@ -376,7 +368,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
376 368
377 case TUNER_MICROTUNE_4042FI5: 369 case TUNER_MICROTUNE_4042FI5:
378 /* Set the charge pump for fast tuning */ 370 /* Set the charge pump for fast tuning */
379 tun->config |= 0x40; 371 tun->config |= TUNER_CHARGE_PUMP;
380 break; 372 break;
381 } 373 }
382 374
@@ -425,14 +417,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
425 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc); 417 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
426 break; 418 break;
427 } 419 }
428 /* bit 6 is PLL locked indicator */ 420 if (status_byte & TUNER_PLL_LOCKED)
429 if (status_byte & 0x40)
430 break; 421 break;
431 udelay(10); 422 udelay(10);
432 } 423 }
433 424
434 /* Set the charge pump for optimized phase noise figure */ 425 /* Set the charge pump for optimized phase noise figure */
435 tun->config &= ~0x40; 426 tun->config &= ~TUNER_CHARGE_PUMP;
436 buffer[0] = (div>>8) & 0x7f; 427 buffer[0] = (div>>8) & 0x7f;
437 buffer[1] = div & 0xff; 428 buffer[1] = div & 0xff;
438 buffer[2] = tun->config; 429 buffer[2] = tun->config;
@@ -453,26 +444,22 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
453 unsigned div; 444 unsigned div;
454 int rc; 445 int rc;
455 446
456 tun=&tuners[t->type]; 447 tun = &tuners[t->type];
457 div = (freq / 1000) + (int)(16*10.7); 448 div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
458 buffer[2] = tun->config; 449 buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
459 450
460 switch (t->type) { 451 switch (t->type) {
461 case TUNER_TENA_9533_DI: 452 case TUNER_TENA_9533_DI:
462 case TUNER_YMEC_TVF_5533MF: 453 case TUNER_YMEC_TVF_5533MF:
463 /*These values are empirically determinated */ 454 tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
464 div = (freq * 122) / 16000 - 20; 455 return;
465 buffer[2] = 0x88; /* could be also 0x80 */
466 buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
467 break;
468 case TUNER_PHILIPS_FM1216ME_MK3: 456 case TUNER_PHILIPS_FM1216ME_MK3:
469 case TUNER_PHILIPS_FM1236_MK3: 457 case TUNER_PHILIPS_FM1236_MK3:
470 case TUNER_PHILIPS_FMD1216ME_MK3: 458 case TUNER_PHILIPS_FMD1216ME_MK3:
471 buffer[3] = 0x19; 459 buffer[3] = 0x19;
472 break; 460 break;
473 case TUNER_PHILIPS_FM1256_IH3: 461 case TUNER_PHILIPS_FM1256_IH3:
474 div = (20 * freq) / 16000 + 333 * 2; 462 div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
475 buffer[2] = 0x80;
476 buffer[3] = 0x19; 463 buffer[3] = 0x19;
477 break; 464 break;
478 case TUNER_LG_PAL_FM: 465 case TUNER_LG_PAL_FM:
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 4794c5632360..d8c0a5563289 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -1,5 +1,5 @@
1 1
2/* $Id: tuner.h,v 1.33 2005/06/21 14:58:08 mkrufky Exp $ 2/* $Id: tuner.h,v 1.42 2005/07/06 09:42:19 mchehab Exp $
3 * 3 *
4 tuner.h - definition for different tuners 4 tuner.h - definition for different tuners
5 5
@@ -26,8 +26,6 @@
26 26
27#include <linux/videodev2.h> 27#include <linux/videodev2.h>
28 28
29#include "id.h"
30
31#define ADDR_UNSET (255) 29#define ADDR_UNSET (255)
32 30
33#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ 31#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
@@ -111,8 +109,6 @@
111#define TUNER_TEA5767 62 /* Only FM Radio Tuner */ 109#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
112#define TUNER_PHILIPS_FMD1216ME_MK3 63 110#define TUNER_PHILIPS_FMD1216ME_MK3 63
113 111
114#define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio"
115
116#define NOTUNER 0 112#define NOTUNER 0
117#define PAL 1 /* PAL_BG */ 113#define PAL 1 /* PAL_BG */
118#define PAL_I 2 114#define PAL_I 2
@@ -135,19 +131,8 @@
135#define TCL 11 131#define TCL 11
136#define THOMSON 12 132#define THOMSON 12
137 133
138enum v4l_radio_tuner { 134#define TUNER_SET_TYPE_ADDR _IOW('T',3,int)
139 TEA5767_LOW_LO_32768 = 0, 135#define TDA9887_SET_CONFIG _IOW('t',5,int)
140 TEA5767_HIGH_LO_32768 = 1,
141 TEA5767_LOW_LO_13MHz = 2,
142 TEA5767_HIGH_LO_13MHz = 3,
143};
144
145
146#define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */
147#define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */
148#define TUNER_SET_TYPE_ADDR _IOW('T',3,int) /* set tuner type and I2C addr */
149
150#define TDA9887_SET_CONFIG _IOW('t',5,int)
151 136
152/* tv card specific */ 137/* tv card specific */
153# define TDA9887_PRESENT (1<<0) 138# define TDA9887_PRESENT (1<<0)
@@ -169,25 +154,34 @@ enum v4l_radio_tuner {
169#define I2C_ADDR_TDA8290 0x4b 154#define I2C_ADDR_TDA8290 0x4b
170#define I2C_ADDR_TDA8275 0x61 155#define I2C_ADDR_TDA8275 0x61
171 156
172struct tuner_addr { 157enum tuner_mode {
173 enum v4l2_tuner_type v4l2_tuner; 158 T_UNINITIALIZED = 0,
174 unsigned int type; 159 T_RADIO = 1 << V4L2_TUNER_RADIO,
160 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV,
161 T_DIGITAL_TV = 1 << V4L2_TUNER_DIGITAL_TV,
162 T_STANDBY = 1 << 31
163};
164
165struct tuner_setup {
175 unsigned short addr; 166 unsigned short addr;
167 unsigned int type;
168 unsigned int mode_mask;
176}; 169};
177 170
178struct tuner { 171struct tuner {
179 /* device */ 172 /* device */
180 struct i2c_client i2c; 173 struct i2c_client i2c;
181 174
182 /* state + config */
183 unsigned int initialized;
184 unsigned int type; /* chip type */ 175 unsigned int type; /* chip type */
176
177 unsigned int mode;
178 unsigned int mode_mask; /* Combination of allowable modes */
179
185 unsigned int freq; /* keep track of the current settings */ 180 unsigned int freq; /* keep track of the current settings */
181 unsigned int audmode;
186 v4l2_std_id std; 182 v4l2_std_id std;
187 int using_v4l2;
188 183
189 enum v4l2_tuner_type mode; 184 int using_v4l2;
190 unsigned int input;
191 185
192 /* used by MT2032 */ 186 /* used by MT2032 */
193 unsigned int xogc; 187 unsigned int xogc;
@@ -197,15 +191,11 @@ struct tuner {
197 unsigned char i2c_easy_mode[2]; 191 unsigned char i2c_easy_mode[2];
198 unsigned char i2c_set_freq[8]; 192 unsigned char i2c_set_freq[8];
199 193
200 /* used to keep track of audmode */
201 unsigned int audmode;
202
203 /* function ptrs */ 194 /* function ptrs */
204 void (*tv_freq)(struct i2c_client *c, unsigned int freq); 195 void (*tv_freq)(struct i2c_client *c, unsigned int freq);
205 void (*radio_freq)(struct i2c_client *c, unsigned int freq); 196 void (*radio_freq)(struct i2c_client *c, unsigned int freq);
206 int (*has_signal)(struct i2c_client *c); 197 int (*has_signal)(struct i2c_client *c);
207 int (*is_stereo)(struct i2c_client *c); 198 int (*is_stereo)(struct i2c_client *c);
208 int (*set_tuner)(struct i2c_client *c, struct v4l2_tuner *v);
209}; 199};
210 200
211extern unsigned int tuner_debug; 201extern unsigned int tuner_debug;
@@ -215,6 +205,7 @@ extern int microtune_init(struct i2c_client *c);
215extern int tda8290_init(struct i2c_client *c); 205extern int tda8290_init(struct i2c_client *c);
216extern int tea5767_tuner_init(struct i2c_client *c); 206extern int tea5767_tuner_init(struct i2c_client *c);
217extern int default_tuner_init(struct i2c_client *c); 207extern int default_tuner_init(struct i2c_client *c);
208extern int tea5767_autodetection(struct i2c_client *c);
218 209
219#define tuner_warn(fmt, arg...) \ 210#define tuner_warn(fmt, arg...) \
220 dev_printk(KERN_WARNING , &t->i2c.dev , fmt , ## arg) 211 dev_printk(KERN_WARNING , &t->i2c.dev , fmt , ## arg)