aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/radio/Kconfig15
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-maestro.c452
3 files changed, 0 insertions, 468 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index ecdffa6aac66..851716a7da0e 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -166,21 +166,6 @@ config RADIO_MAXIRADIO
166 To compile this driver as a module, choose M here: the 166 To compile this driver as a module, choose M here: the
167 module will be called radio-maxiradio. 167 module will be called radio-maxiradio.
168 168
169config RADIO_MAESTRO
170 tristate "Maestro on board radio"
171 depends on VIDEO_V4L2 && PCI
172 ---help---
173 Say Y here to directly support the on-board radio tuner on the
174 Maestro 2 or 2E sound card.
175
176 In order to control your radio card, you will need to use programs
177 that are compatible with the Video For Linux API. Information on
178 this API and pointers to "v4l" programs may be found at
179 <file:Documentation/video4linux/API.html>.
180
181 To compile this driver as a module, choose M here: the
182 module will be called radio-maestro.
183
184config RADIO_MIROPCM20 169config RADIO_MIROPCM20
185 tristate "miroSOUND PCM20 radio" 170 tristate "miroSOUND PCM20 radio"
186 depends on ISA && VIDEO_V4L2 && SND 171 depends on ISA && VIDEO_V4L2 && SND
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 717656d2f749..d68907fc7925 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
16obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 16obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
17obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o 17obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
18obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o 18obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
19obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
20obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o 19obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
21obj-$(CONFIG_USB_DSBR) += dsbr100.o 20obj-$(CONFIG_USB_DSBR) += dsbr100.o
22obj-$(CONFIG_RADIO_SI470X) += si470x/ 21obj-$(CONFIG_RADIO_SI470X) += si470x/
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
deleted file mode 100644
index 6af61bfeb178..000000000000
--- a/drivers/media/radio/radio-maestro.c
+++ /dev/null
@@ -1,452 +0,0 @@
1/* Maestro PCI sound card radio driver for Linux support
2 * (c) 2000 A. Tlalka, atlka@pg.gda.pl
3 * Notes on the hardware
4 *
5 * + Frequency control is done digitally
6 * + No volume control - only mute/unmute - you have to use Aux line volume
7 * control on Maestro card to set the volume
8 * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
9 * frequency setting (>100ms) and only when the radio is unmuted.
10 * version 0.02
11 * + io port is automatically detected - only the first radio is used
12 * version 0.03
13 * + thread access locking additions
14 * version 0.04
15 * + code improvements
16 * + VIDEO_TUNER_LOW is permanent
17 *
18 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/ioport.h>
24#include <linux/delay.h>
25#include <linux/version.h> /* for KERNEL_VERSION MACRO */
26#include <linux/pci.h>
27#include <linux/videodev2.h>
28#include <linux/io.h>
29#include <linux/slab.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h>
32
33MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
34MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
35MODULE_LICENSE("GPL");
36
37static int radio_nr = -1;
38module_param(radio_nr, int, 0);
39
40#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
41#define DRIVER_VERSION "0.06"
42
43#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
44
45#define IO_MASK 4 /* mask register offset from GPIO_DATA
46 bits 1=unmask write to given bit */
47#define IO_DIR 8 /* direction register offset from GPIO_DATA
48 bits 0/1=read/write direction */
49
50#define GPIO6 0x0040 /* mask bits for GPIO lines */
51#define GPIO7 0x0080
52#define GPIO8 0x0100
53#define GPIO9 0x0200
54
55#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */
56#define STR_CLK GPIO7
57#define STR_WREN GPIO8
58#define STR_MOST GPIO9
59
60#define FREQ_LO 50*16000
61#define FREQ_HI 150*16000
62
63#define FREQ_IF 171200 /* 10.7*16000 */
64#define FREQ_STEP 200 /* 12.5*16 */
65
66#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
67 /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
68
69#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
70
71struct maestro {
72 struct v4l2_device v4l2_dev;
73 struct video_device vdev;
74 struct pci_dev *pdev;
75 struct mutex lock;
76
77 u16 io; /* base of Maestro card radio io (GPIO_DATA)*/
78 u16 muted; /* VIDEO_AUDIO_MUTE */
79 u16 stereo; /* VIDEO_TUNER_STEREO_ON */
80 u16 tuned; /* signal strength (0 or 0xffff) */
81};
82
83static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
84{
85 return container_of(v4l2_dev, struct maestro, v4l2_dev);
86}
87
88static u32 radio_bits_get(struct maestro *dev)
89{
90 u16 io = dev->io, l, rdata;
91 u32 data = 0;
92 u16 omask;
93
94 omask = inw(io + IO_MASK);
95 outw(~(STR_CLK | STR_WREN), io + IO_MASK);
96 outw(0, io);
97 udelay(16);
98
99 for (l = 24; l--;) {
100 outw(STR_CLK, io); /* HI state */
101 udelay(2);
102 if (!l)
103 dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
104 outw(0, io); /* LO state */
105 udelay(2);
106 data <<= 1; /* shift data */
107 rdata = inw(io);
108 if (!l)
109 dev->stereo = (rdata & STR_MOST) ? 0 : 1;
110 else if (rdata & STR_DATA)
111 data++;
112 udelay(2);
113 }
114
115 if (dev->muted)
116 outw(STR_WREN, io);
117
118 udelay(4);
119 outw(omask, io + IO_MASK);
120
121 return data & 0x3ffe;
122}
123
124static void radio_bits_set(struct maestro *dev, u32 data)
125{
126 u16 io = dev->io, l, bits;
127 u16 omask, odir;
128
129 omask = inw(io + IO_MASK);
130 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
131 outw(odir | STR_DATA, io + IO_DIR);
132 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
133 udelay(16);
134 for (l = 25; l; l--) {
135 bits = ((data >> 18) & STR_DATA) | STR_WREN;
136 data <<= 1; /* shift data */
137 outw(bits, io); /* start strobe */
138 udelay(2);
139 outw(bits | STR_CLK, io); /* HI level */
140 udelay(2);
141 outw(bits, io); /* LO level */
142 udelay(4);
143 }
144
145 if (!dev->muted)
146 outw(0, io);
147
148 udelay(4);
149 outw(omask, io + IO_MASK);
150 outw(odir, io + IO_DIR);
151 msleep(125);
152}
153
154static int vidioc_querycap(struct file *file, void *priv,
155 struct v4l2_capability *v)
156{
157 struct maestro *dev = video_drvdata(file);
158
159 strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
160 strlcpy(v->card, "Maestro Radio", sizeof(v->card));
161 snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
162 v->version = RADIO_VERSION;
163 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
164 return 0;
165}
166
167static int vidioc_g_tuner(struct file *file, void *priv,
168 struct v4l2_tuner *v)
169{
170 struct maestro *dev = video_drvdata(file);
171
172 if (v->index > 0)
173 return -EINVAL;
174
175 mutex_lock(&dev->lock);
176 radio_bits_get(dev);
177
178 strlcpy(v->name, "FM", sizeof(v->name));
179 v->type = V4L2_TUNER_RADIO;
180 v->rangelow = FREQ_LO;
181 v->rangehigh = FREQ_HI;
182 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
183 v->capability = V4L2_TUNER_CAP_LOW;
184 if (dev->stereo)
185 v->audmode = V4L2_TUNER_MODE_STEREO;
186 else
187 v->audmode = V4L2_TUNER_MODE_MONO;
188 v->signal = dev->tuned;
189 mutex_unlock(&dev->lock);
190 return 0;
191}
192
193static int vidioc_s_tuner(struct file *file, void *priv,
194 struct v4l2_tuner *v)
195{
196 return v->index ? -EINVAL : 0;
197}
198
199static int vidioc_s_frequency(struct file *file, void *priv,
200 struct v4l2_frequency *f)
201{
202 struct maestro *dev = video_drvdata(file);
203
204 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
205 return -EINVAL;
206 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
207 return -EINVAL;
208 mutex_lock(&dev->lock);
209 radio_bits_set(dev, FREQ2BITS(f->frequency));
210 mutex_unlock(&dev->lock);
211 return 0;
212}
213
214static int vidioc_g_frequency(struct file *file, void *priv,
215 struct v4l2_frequency *f)
216{
217 struct maestro *dev = video_drvdata(file);
218
219 if (f->tuner != 0)
220 return -EINVAL;
221 f->type = V4L2_TUNER_RADIO;
222 mutex_lock(&dev->lock);
223 f->frequency = BITS2FREQ(radio_bits_get(dev));
224 mutex_unlock(&dev->lock);
225 return 0;
226}
227
228static int vidioc_queryctrl(struct file *file, void *priv,
229 struct v4l2_queryctrl *qc)
230{
231 switch (qc->id) {
232 case V4L2_CID_AUDIO_MUTE:
233 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
234 }
235 return -EINVAL;
236}
237
238static int vidioc_g_ctrl(struct file *file, void *priv,
239 struct v4l2_control *ctrl)
240{
241 struct maestro *dev = video_drvdata(file);
242
243 switch (ctrl->id) {
244 case V4L2_CID_AUDIO_MUTE:
245 ctrl->value = dev->muted;
246 return 0;
247 }
248 return -EINVAL;
249}
250
251static int vidioc_s_ctrl(struct file *file, void *priv,
252 struct v4l2_control *ctrl)
253{
254 struct maestro *dev = video_drvdata(file);
255 u16 io = dev->io;
256 u16 omask;
257
258 switch (ctrl->id) {
259 case V4L2_CID_AUDIO_MUTE:
260 mutex_lock(&dev->lock);
261 omask = inw(io + IO_MASK);
262 outw(~STR_WREN, io + IO_MASK);
263 dev->muted = ctrl->value;
264 outw(dev->muted ? STR_WREN : 0, io);
265 udelay(4);
266 outw(omask, io + IO_MASK);
267 msleep(125);
268 mutex_unlock(&dev->lock);
269 return 0;
270 }
271 return -EINVAL;
272}
273
274static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
275{
276 *i = 0;
277 return 0;
278}
279
280static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
281{
282 return i ? -EINVAL : 0;
283}
284
285static int vidioc_g_audio(struct file *file, void *priv,
286 struct v4l2_audio *a)
287{
288 a->index = 0;
289 strlcpy(a->name, "Radio", sizeof(a->name));
290 a->capability = V4L2_AUDCAP_STEREO;
291 return 0;
292}
293
294static int vidioc_s_audio(struct file *file, void *priv,
295 struct v4l2_audio *a)
296{
297 return a->index ? -EINVAL : 0;
298}
299
300static const struct v4l2_file_operations maestro_fops = {
301 .owner = THIS_MODULE,
302 .unlocked_ioctl = video_ioctl2,
303};
304
305static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
306 .vidioc_querycap = vidioc_querycap,
307 .vidioc_g_tuner = vidioc_g_tuner,
308 .vidioc_s_tuner = vidioc_s_tuner,
309 .vidioc_g_audio = vidioc_g_audio,
310 .vidioc_s_audio = vidioc_s_audio,
311 .vidioc_g_input = vidioc_g_input,
312 .vidioc_s_input = vidioc_s_input,
313 .vidioc_g_frequency = vidioc_g_frequency,
314 .vidioc_s_frequency = vidioc_s_frequency,
315 .vidioc_queryctrl = vidioc_queryctrl,
316 .vidioc_g_ctrl = vidioc_g_ctrl,
317 .vidioc_s_ctrl = vidioc_s_ctrl,
318};
319
320static u16 __devinit radio_power_on(struct maestro *dev)
321{
322 register u16 io = dev->io;
323 register u32 ofreq;
324 u16 omask, odir;
325
326 omask = inw(io + IO_MASK);
327 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
328 outw(odir & ~STR_WREN, io + IO_DIR);
329 dev->muted = inw(io) & STR_WREN ? 0 : 1;
330 outw(odir, io + IO_DIR);
331 outw(~(STR_WREN | STR_CLK), io + IO_MASK);
332 outw(dev->muted ? 0 : STR_WREN, io);
333 udelay(16);
334 outw(omask, io + IO_MASK);
335 ofreq = radio_bits_get(dev);
336
337 if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
338 ofreq = FREQ2BITS(FREQ_LO);
339 radio_bits_set(dev, ofreq);
340
341 return (ofreq == radio_bits_get(dev));
342}
343
344static int __devinit maestro_probe(struct pci_dev *pdev,
345 const struct pci_device_id *ent)
346{
347 struct maestro *dev;
348 struct v4l2_device *v4l2_dev;
349 int retval;
350
351 retval = pci_enable_device(pdev);
352 if (retval) {
353 dev_err(&pdev->dev, "enabling pci device failed!\n");
354 goto err;
355 }
356
357 retval = -ENOMEM;
358
359 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
360 if (dev == NULL) {
361 dev_err(&pdev->dev, "not enough memory\n");
362 goto err;
363 }
364
365 v4l2_dev = &dev->v4l2_dev;
366 mutex_init(&dev->lock);
367 dev->pdev = pdev;
368
369 strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
370
371 retval = v4l2_device_register(&pdev->dev, v4l2_dev);
372 if (retval < 0) {
373 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
374 goto errfr;
375 }
376
377 dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
378
379 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
380 dev->vdev.v4l2_dev = v4l2_dev;
381 dev->vdev.fops = &maestro_fops;
382 dev->vdev.ioctl_ops = &maestro_ioctl_ops;
383 dev->vdev.release = video_device_release_empty;
384 video_set_drvdata(&dev->vdev, dev);
385
386 if (!radio_power_on(dev)) {
387 retval = -EIO;
388 goto errfr1;
389 }
390
391 retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
392 if (retval) {
393 v4l2_err(v4l2_dev, "can't register video device!\n");
394 goto errfr1;
395 }
396
397 v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
398
399 return 0;
400errfr1:
401 v4l2_device_unregister(v4l2_dev);
402errfr:
403 kfree(dev);
404err:
405 return retval;
406
407}
408
409static void __devexit maestro_remove(struct pci_dev *pdev)
410{
411 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
412 struct maestro *dev = to_maestro(v4l2_dev);
413
414 video_unregister_device(&dev->vdev);
415 v4l2_device_unregister(&dev->v4l2_dev);
416}
417
418static struct pci_device_id maestro_r_pci_tbl[] = {
419 { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
420 .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
421 .class_mask = 0xffff00 },
422 { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
423 .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
424 .class_mask = 0xffff00 },
425 { 0 }
426};
427MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
428
429static struct pci_driver maestro_r_driver = {
430 .name = "maestro_radio",
431 .id_table = maestro_r_pci_tbl,
432 .probe = maestro_probe,
433 .remove = __devexit_p(maestro_remove),
434};
435
436static int __init maestro_radio_init(void)
437{
438 int retval = pci_register_driver(&maestro_r_driver);
439
440 if (retval)
441 printk(KERN_ERR "error during registration pci driver\n");
442
443 return retval;
444}
445
446static void __exit maestro_radio_exit(void)
447{
448 pci_unregister_driver(&maestro_r_driver);
449}
450
451module_init(maestro_radio_init);
452module_exit(maestro_radio_exit);