aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-maxiradio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-maxiradio.c')
-rw-r--r--drivers/media/radio/radio-maxiradio.c80
1 files changed, 40 insertions, 40 deletions
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index f0bf47bcb64c..fe2552569690 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -1,15 +1,15 @@
1/* 1/*
2 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux 2 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux
3 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net> 3 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net>
4 * 4 *
5 * Based in the radio Maestro PCI driver. Actually it uses the same chip 5 * Based in the radio Maestro PCI driver. Actually it uses the same chip
6 * for radio but different pci controller. 6 * for radio but different pci controller.
7 * 7 *
8 * I didn't have any specs I reversed engineered the protocol from 8 * I didn't have any specs I reversed engineered the protocol from
9 * the windows driver (radio.dll). 9 * the windows driver (radio.dll).
10 * 10 *
11 * The card uses the TEA5757 chip that includes a search function but it 11 * The card uses the TEA5757 chip that includes a search function but it
12 * is useless as I haven't found any way to read back the frequency. If 12 * is useless as I haven't found any way to read back the frequency. If
13 * anybody does please mail me. 13 * anybody does please mail me.
14 * 14 *
15 * For the pdf file see: 15 * For the pdf file see:
@@ -24,7 +24,7 @@
24 * - tiding up 24 * - tiding up
25 * - removed support for multiple devices as it didn't work anyway 25 * - removed support for multiple devices as it didn't work anyway
26 * 26 *
27 * BUGS: 27 * BUGS:
28 * - card unmutes if you change frequency 28 * - card unmutes if you change frequency
29 * 29 *
30 */ 30 */
@@ -80,7 +80,7 @@ static struct file_operations maxiradio_fops = {
80 .owner = THIS_MODULE, 80 .owner = THIS_MODULE,
81 .open = video_exclusive_open, 81 .open = video_exclusive_open,
82 .release = video_exclusive_release, 82 .release = video_exclusive_release,
83 .ioctl = radio_ioctl, 83 .ioctl = radio_ioctl,
84 .compat_ioctl = v4l_compat_ioctl32, 84 .compat_ioctl = v4l_compat_ioctl32,
85 .llseek = no_llseek, 85 .llseek = no_llseek,
86}; 86};
@@ -97,11 +97,11 @@ static struct radio_device
97{ 97{
98 __u16 io, /* base of radio io */ 98 __u16 io, /* base of radio io */
99 muted, /* VIDEO_AUDIO_MUTE */ 99 muted, /* VIDEO_AUDIO_MUTE */
100 stereo, /* VIDEO_TUNER_STEREO_ON */ 100 stereo, /* VIDEO_TUNER_STEREO_ON */
101 tuned; /* signal strength (0 or 0xffff) */ 101 tuned; /* signal strength (0 or 0xffff) */
102 102
103 unsigned long freq; 103 unsigned long freq;
104 104
105 struct mutex lock; 105 struct mutex lock;
106} radio_unit = {0, 0, 0, 0, }; 106} radio_unit = {0, 0, 0, 0, };
107 107
@@ -114,7 +114,7 @@ static void outbit(unsigned long bit, __u16 io)
114 outb( power|wren|data|clk ,io); udelay(4); 114 outb( power|wren|data|clk ,io); udelay(4);
115 outb( power|wren|data ,io); udelay(4); 115 outb( power|wren|data ,io); udelay(4);
116 } 116 }
117 else 117 else
118 { 118 {
119 outb( power|wren ,io); udelay(4); 119 outb( power|wren ,io); udelay(4);
120 outb( power|wren|clk ,io); udelay(4); 120 outb( power|wren|clk ,io); udelay(4);
@@ -132,12 +132,12 @@ static void set_freq(__u16 io, __u32 data)
132{ 132{
133 unsigned long int si; 133 unsigned long int si;
134 int bl; 134 int bl;
135 135
136 /* TEA5757 shift register bits (see pdf) */ 136 /* TEA5757 shift register bits (see pdf) */
137 137
138 outbit(0,io); // 24 search 138 outbit(0,io); // 24 search
139 outbit(1,io); // 23 search up/down 139 outbit(1,io); // 23 search up/down
140 140
141 outbit(0,io); // 22 stereo/mono 141 outbit(0,io); // 22 stereo/mono
142 142
143 outbit(0,io); // 21 band 143 outbit(0,io); // 21 band
@@ -145,24 +145,24 @@ static void set_freq(__u16 io, __u32 data)
145 145
146 outbit(0,io); // 19 port ? 146 outbit(0,io); // 19 port ?
147 outbit(0,io); // 18 port ? 147 outbit(0,io); // 18 port ?
148 148
149 outbit(0,io); // 17 search level 149 outbit(0,io); // 17 search level
150 outbit(0,io); // 16 search level 150 outbit(0,io); // 16 search level
151 151
152 si = 0x8000; 152 si = 0x8000;
153 for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; } 153 for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; }
154 154
155 outb(power,io); 155 outb(power,io);
156} 156}
157 157
158static int get_stereo(__u16 io) 158static int get_stereo(__u16 io)
159{ 159{
160 outb(power,io); udelay(4); 160 outb(power,io); udelay(4);
161 return !(inb(io) & mo_st); 161 return !(inb(io) & mo_st);
162} 162}
163 163
164static int get_tune(__u16 io) 164static int get_tune(__u16 io)
165{ 165{
166 outb(power+clk,io); udelay(4); 166 outb(power+clk,io); udelay(4);
167 return !(inb(io) & mo_st); 167 return !(inb(io) & mo_st);
168} 168}
@@ -177,7 +177,7 @@ static inline int radio_function(struct inode *inode, struct file *file,
177 switch(cmd) { 177 switch(cmd) {
178 case VIDIOCGCAP: { 178 case VIDIOCGCAP: {
179 struct video_capability *v = arg; 179 struct video_capability *v = arg;
180 180
181 memset(v,0,sizeof(*v)); 181 memset(v,0,sizeof(*v));
182 strcpy(v->name, "Maxi Radio FM2000 radio"); 182 strcpy(v->name, "Maxi Radio FM2000 radio");
183 v->type=VID_TYPE_TUNER; 183 v->type=VID_TYPE_TUNER;
@@ -186,22 +186,22 @@ static inline int radio_function(struct inode *inode, struct file *file,
186 } 186 }
187 case VIDIOCGTUNER: { 187 case VIDIOCGTUNER: {
188 struct video_tuner *v = arg; 188 struct video_tuner *v = arg;
189 189
190 if(v->tuner) 190 if(v->tuner)
191 return -EINVAL; 191 return -EINVAL;
192 192
193 card->stereo = 0xffff * get_stereo(card->io); 193 card->stereo = 0xffff * get_stereo(card->io);
194 card->tuned = 0xffff * get_tune(card->io); 194 card->tuned = 0xffff * get_tune(card->io);
195 195
196 v->flags = VIDEO_TUNER_LOW | card->stereo; 196 v->flags = VIDEO_TUNER_LOW | card->stereo;
197 v->signal = card->tuned; 197 v->signal = card->tuned;
198 198
199 strcpy(v->name, "FM"); 199 strcpy(v->name, "FM");
200 200
201 v->rangelow = FREQ_LO; 201 v->rangelow = FREQ_LO;
202 v->rangehigh = FREQ_HI; 202 v->rangehigh = FREQ_HI;
203 v->mode = VIDEO_MODE_AUTO; 203 v->mode = VIDEO_MODE_AUTO;
204 204
205 return 0; 205 return 0;
206 } 206 }
207 case VIDIOCSTUNER: { 207 case VIDIOCSTUNER: {
@@ -212,13 +212,13 @@ static inline int radio_function(struct inode *inode, struct file *file,
212 } 212 }
213 case VIDIOCGFREQ: { 213 case VIDIOCGFREQ: {
214 unsigned long *freq = arg; 214 unsigned long *freq = arg;
215 215
216 *freq = card->freq; 216 *freq = card->freq;
217 return 0; 217 return 0;
218 } 218 }
219 case VIDIOCSFREQ: { 219 case VIDIOCSFREQ: {
220 unsigned long *freq = arg; 220 unsigned long *freq = arg;
221 221
222 if (*freq < FREQ_LO || *freq > FREQ_HI) 222 if (*freq < FREQ_LO || *freq > FREQ_HI)
223 return -EINVAL; 223 return -EINVAL;
224 card->freq = *freq; 224 card->freq = *freq;
@@ -226,18 +226,18 @@ static inline int radio_function(struct inode *inode, struct file *file,
226 msleep(125); 226 msleep(125);
227 return 0; 227 return 0;
228 } 228 }
229 case VIDIOCGAUDIO: { 229 case VIDIOCGAUDIO: {
230 struct video_audio *v = arg; 230 struct video_audio *v = arg;
231 memset(v,0,sizeof(*v)); 231 memset(v,0,sizeof(*v));
232 strcpy(v->name, "Radio"); 232 strcpy(v->name, "Radio");
233 v->flags=VIDEO_AUDIO_MUTABLE | card->muted; 233 v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
234 v->mode=VIDEO_SOUND_STEREO; 234 v->mode=VIDEO_SOUND_STEREO;
235 return 0; 235 return 0;
236 } 236 }
237 237
238 case VIDIOCSAUDIO: { 238 case VIDIOCSAUDIO: {
239 struct video_audio *v = arg; 239 struct video_audio *v = arg;
240 240
241 if(v->audio) 241 if(v->audio)
242 return -EINVAL; 242 return -EINVAL;
243 card->muted = v->flags & VIDEO_AUDIO_MUTE; 243 card->muted = v->flags & VIDEO_AUDIO_MUTE;
@@ -249,13 +249,13 @@ static inline int radio_function(struct inode *inode, struct file *file,
249 } 249 }
250 case VIDIOCGUNIT: { 250 case VIDIOCGUNIT: {
251 struct video_unit *v = arg; 251 struct video_unit *v = arg;
252 252
253 v->video=VIDEO_NO_UNIT; 253 v->video=VIDEO_NO_UNIT;
254 v->vbi=VIDEO_NO_UNIT; 254 v->vbi=VIDEO_NO_UNIT;
255 v->radio=dev->minor; 255 v->radio=dev->minor;
256 v->audio=0; 256 v->audio=0;
257 v->teletext=VIDEO_NO_UNIT; 257 v->teletext=VIDEO_NO_UNIT;
258 return 0; 258 return 0;
259 } 259 }
260 default: return -ENOIOCTLCMD; 260 default: return -ENOIOCTLCMD;
261 } 261 }
@@ -267,7 +267,7 @@ static int radio_ioctl(struct inode *inode, struct file *file,
267 struct video_device *dev = video_devdata(file); 267 struct video_device *dev = video_devdata(file);
268 struct radio_device *card=dev->priv; 268 struct radio_device *card=dev->priv;
269 int ret; 269 int ret;
270 270
271 mutex_lock(&card->lock); 271 mutex_lock(&card->lock);
272 ret = video_usercopy(inode, file, cmd, arg, radio_function); 272 ret = video_usercopy(inode, file, cmd, arg, radio_function);
273 mutex_unlock(&card->lock); 273 mutex_unlock(&card->lock);
@@ -282,21 +282,21 @@ MODULE_LICENSE("GPL");
282static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 282static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
283{ 283{
284 if(!request_region(pci_resource_start(pdev, 0), 284 if(!request_region(pci_resource_start(pdev, 0),
285 pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { 285 pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) {
286 printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); 286 printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n");
287 goto err_out; 287 goto err_out;
288 } 288 }
289 289
290 if (pci_enable_device(pdev)) 290 if (pci_enable_device(pdev))
291 goto err_out_free_region; 291 goto err_out_free_region;
292 292
293 radio_unit.io = pci_resource_start(pdev, 0); 293 radio_unit.io = pci_resource_start(pdev, 0);
294 mutex_init(&radio_unit.lock); 294 mutex_init(&radio_unit.lock);
295 maxiradio_radio.priv = &radio_unit; 295 maxiradio_radio.priv = &radio_unit;
296 296
297 if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { 297 if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
298 printk("radio-maxiradio: can't register device!"); 298 printk("radio-maxiradio: can't register device!");
299 goto err_out_free_region; 299 goto err_out_free_region;
300 } 300 }
301 301
302 printk(KERN_INFO "radio-maxiradio: version " 302 printk(KERN_INFO "radio-maxiradio: version "