1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/sched.h>
4 #include <linux/string.h>
5 #include <linux/timer.h>
6 #include <linux/delay.h>
7 #include <linux/errno.h>
8 #include <linux/malloc.h>
10 #include <linux/i2c.h>
11 #include <linux/videodev.h>
15 static int debug
= 0; /* insmod parameter */
16 static int type
= 0; /* tuner type */
18 #define dprintk if (debug) printk
20 MODULE_PARM(debug
,"i");
21 MODULE_PARM(type
,"i");
25 struct i2c_bus
*bus
; /* where is our chip */
28 int type
; /* chip type */
29 int freq
; /* keep track of the current settings */
33 /* ---------------------------------------------------------------------- */
41 unsigned short thresh1
; /* frequency Range for UHF,VHF-L, VHF_H */
42 unsigned short thresh2
;
48 unsigned short IFPCoff
;
52 * The floats in the tuner struct are computed at compile time
53 * by gcc and cast back to integers. Thus we don't violate the
54 * "no float in kernel" rule.
56 static struct tunertype tuners
[] = {
57 {"Temic PAL", TEMIC
, PAL
,
58 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,0xc2,623},
59 {"Philips PAL_I", Philips
, PAL_I
,
60 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,0xc0,623},
61 {"Philips NTSC", Philips
, NTSC
,
62 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,0xc0,732},
63 {"Philips SECAM", Philips
, SECAM
,
64 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,0xc0,623},
65 {"NoTuner", NoTuner
, NOTUNER
,
66 0 ,0 ,0x00,0x00,0x00,0x00,0x00,000},
67 {"Philips PAL", Philips
, PAL
,
68 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,0xc0,623},
69 {"Temic NTSC", TEMIC
, NTSC
,
70 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,0xc2,732},
71 {"TEMIC PAL_I", TEMIC
, PAL_I
,
72 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,0xc2,623},
75 /* ---------------------------------------------------------------------- */
77 static int tuner_getstatus (struct tuner
*t
)
79 return i2c_read(t
->bus
,t
->addr
+1);
82 #define TUNER_POR 0x80
84 #define TUNER_AFC 0x07
86 static int tuner_islocked (struct tuner
*t
)
88 return (tuner_getstatus (t
) & TUNER_FL
);
91 static int tuner_afcstatus (struct tuner
*t
)
93 return (tuner_getstatus (t
) & TUNER_AFC
) - 2;
97 static void set_tv_freq(struct tuner
*t
, int freq
)
102 struct tunertype
*tun
=&tuners
[t
->type
];
104 if (freq
< tun
->thresh1
)
106 else if (freq
< tun
->thresh2
)
111 div
=freq
+ tun
->IFPCoff
;
114 LOCK_I2C_BUS(t
->bus
);
115 if (i2c_write(t
->bus
, t
->addr
, (div
>>8)&0x7f, div
&0xff, 1)<0) {
116 printk("tuner: i2c i/o error #1\n");
118 if (i2c_write(t
->bus
, t
->addr
, tun
->config
, config
, 1))
119 printk("tuner: i2c i/o error #2\n");
121 UNLOCK_I2C_BUS(t
->bus
);
124 static void set_radio_freq(struct tuner
*t
, int freq
)
129 struct tunertype
*tun
=&tuners
[type
];
132 div
=freq
+ (int)(16*10.7);
135 LOCK_I2C_BUS(t
->bus
);
136 if (i2c_write(t
->bus
, t
->addr
, (div
>>8)&0x7f, div
&0xff, 1)<0) {
137 printk("tuner: i2c i/o error #1\n");
139 if (i2c_write(t
->bus
, t
->addr
, tun
->config
, config
, 1))
140 printk("tuner: i2c i/o error #2\n");
143 UNLOCK_I2C_BUS(t
->bus
);
144 current
->state
= TASK_INTERRUPTIBLE
;
145 schedule_timeout(HZ
/10);
146 LOCK_I2C_BUS(t
->bus
);
148 if (tuner_islocked (t
))
149 printk ("tuner: PLL locked\n");
151 printk ("tuner: PLL not locked\n");
153 printk ("tuner: AFC: %d\n", tuner_afcstatus (t
));
155 UNLOCK_I2C_BUS(t
->bus
);
158 /* ---------------------------------------------------------------------- */
160 static int tuner_attach(struct i2c_device
*device
)
165 * For now we only try and attach these tuners to the BT848
166 * bus. This same module will however work different species
167 * of card using these chips. Just change the constraints
168 * (i2c doesn't have a totally clash free 'address' space)
171 if(device
->bus
->id
!=I2C_BUSID_BT848
)
174 device
->data
= t
= kmalloc(sizeof(struct tuner
),GFP_KERNEL
);
177 memset(t
,0,sizeof(struct tuner
));
178 strcpy(device
->name
,"tuner");
179 t
->bus
= device
->bus
;
180 t
->addr
= device
->addr
;
182 dprintk("tuner: type is %d (%s)\n",t
->type
,tuners
[t
->type
].name
);
188 static int tuner_detach(struct i2c_device
*device
)
190 struct tuner
*t
= (struct tuner
*)device
->data
;
196 static int tuner_command(struct i2c_device
*device
,
197 unsigned int cmd
, void *arg
)
199 struct tuner
*t
= (struct tuner
*)device
->data
;
200 int *iarg
= (int*)arg
;
206 dprintk("tuner: type set to %d (%s)\n",
207 t
->type
,tuners
[t
->type
].name
);
210 case TUNER_SET_TVFREQ
:
211 dprintk("tuner: tv freq set to %d.%02d\n",
212 (*iarg
)/16,(*iarg
)%16*100/16);
213 set_tv_freq(t
,*iarg
);
218 case TUNER_SET_RADIOFREQ
:
219 dprintk("tuner: radio freq set to %d.%02d\n",
220 (*iarg
)/16,(*iarg
)%16*100/16);
221 set_radio_freq(t
,*iarg
);
232 /* ----------------------------------------------------------------------- */
234 struct i2c_driver i2c_driver_tuner
=
237 I2C_DRIVERID_TUNER
, /* ID */
238 0xc0, 0xce, /* addr range */
248 int init_module(void)
250 int i2c_tuner_init(void)
253 i2c_register_driver(&i2c_driver_tuner
);
258 void cleanup_module(void)
260 i2c_unregister_driver(&i2c_driver_tuner
);
265 * Overrides for Emacs so that we follow Linus's tabbing style.
266 * ---------------------------------------------------------------------------