2 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux
3 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net>
5 * Based in the radio Maestro PCI driver. Actually it uses the same chip
6 * for radio but different pci controller.
8 * I didn't have any specs I reversed engineered the protocol from
9 * the windows driver (radio.dll).
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
13 * anybody does please mail me.
15 * For the pdf file see:
16 * http://www.nxp.com/acrobat_download2/expired_datasheets/TEA5757_5759_3.pdf
21 * - better pci interface thanks to Francois Romieu <romieu@cogenit.fr>
23 * 0.75 Sun Feb 4 22:51:27 EET 2001
25 * - removed support for multiple devices as it didn't work anyway
28 * - card unmutes if you change frequency
30 * (c) 2006, 2007 by Mauro Carvalho Chehab <mchehab@infradead.org>:
31 * - Conversion to V4L2 API
32 * - Uses video_ioctl2 for parsing and to add debug support
36 #include <linux/module.h>
37 #include <linux/init.h>
38 #include <linux/ioport.h>
39 #include <linux/delay.h>
40 #include <linux/mutex.h>
41 #include <linux/pci.h>
42 #include <linux/videodev2.h>
44 #include <linux/slab.h>
45 #include <media/drv-intf/tea575x.h>
46 #include <media/v4l2-device.h>
47 #include <media/v4l2-ioctl.h>
48 #include <media/v4l2-fh.h>
49 #include <media/v4l2-ctrls.h>
50 #include <media/v4l2-event.h>
52 MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
53 MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000.");
54 MODULE_LICENSE("GPL");
55 MODULE_VERSION("1.0.0");
57 static int radio_nr
= -1;
58 module_param(radio_nr
, int, 0644);
59 MODULE_PARM_DESC(radio_nr
, "Radio device number");
61 /* TEA5757 pin mappings */
62 static const int clk
= 1, data
= 2, wren
= 4, mo_st
= 8, power
= 16;
64 static atomic_t maxiradio_instance
= ATOMIC_INIT(0);
66 #define PCI_VENDOR_ID_GUILLEMOT 0x5046
67 #define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001
71 struct snd_tea575x tea
;
72 struct v4l2_device v4l2_dev
;
75 u16 io
; /* base of radio io */
78 static inline struct maxiradio
*to_maxiradio(struct v4l2_device
*v4l2_dev
)
80 return container_of(v4l2_dev
, struct maxiradio
, v4l2_dev
);
83 static void maxiradio_tea575x_set_pins(struct snd_tea575x
*tea
, u8 pins
)
85 struct maxiradio
*dev
= tea
->private_data
;
88 bits
|= (pins
& TEA575X_DATA
) ? data
: 0;
89 bits
|= (pins
& TEA575X_CLK
) ? clk
: 0;
90 bits
|= (pins
& TEA575X_WREN
) ? wren
: 0;
96 /* Note: this card cannot read out the data of the shift registers,
97 only the mono/stereo pin works. */
98 static u8
maxiradio_tea575x_get_pins(struct snd_tea575x
*tea
)
100 struct maxiradio
*dev
= tea
->private_data
;
101 u8 bits
= inb(dev
->io
);
103 return ((bits
& data
) ? TEA575X_DATA
: 0) |
104 ((bits
& mo_st
) ? TEA575X_MOST
: 0);
107 static void maxiradio_tea575x_set_direction(struct snd_tea575x
*tea
, bool output
)
111 static const struct snd_tea575x_ops maxiradio_tea_ops
= {
112 .set_pins
= maxiradio_tea575x_set_pins
,
113 .get_pins
= maxiradio_tea575x_get_pins
,
114 .set_direction
= maxiradio_tea575x_set_direction
,
117 static int maxiradio_probe(struct pci_dev
*pdev
,
118 const struct pci_device_id
*ent
)
120 struct maxiradio
*dev
;
121 struct v4l2_device
*v4l2_dev
;
122 int retval
= -ENOMEM
;
124 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
126 dev_err(&pdev
->dev
, "not enough memory\n");
130 v4l2_dev
= &dev
->v4l2_dev
;
131 v4l2_device_set_name(v4l2_dev
, "maxiradio", &maxiradio_instance
);
133 retval
= v4l2_device_register(&pdev
->dev
, v4l2_dev
);
135 v4l2_err(v4l2_dev
, "Could not register v4l2_device\n");
138 dev
->tea
.private_data
= dev
;
139 dev
->tea
.ops
= &maxiradio_tea_ops
;
140 /* The data pin cannot be read. This may be a hardware limitation, or
141 we just don't know how to read it. */
142 dev
->tea
.cannot_read_data
= true;
143 dev
->tea
.v4l2_dev
= v4l2_dev
;
144 dev
->tea
.radio_nr
= radio_nr
;
145 strlcpy(dev
->tea
.card
, "Maxi Radio FM2000", sizeof(dev
->tea
.card
));
146 snprintf(dev
->tea
.bus_info
, sizeof(dev
->tea
.bus_info
),
147 "PCI:%s", pci_name(pdev
));
151 if (!request_region(pci_resource_start(pdev
, 0),
152 pci_resource_len(pdev
, 0), v4l2_dev
->name
)) {
153 dev_err(&pdev
->dev
, "can't reserve I/O ports\n");
157 if (pci_enable_device(pdev
))
158 goto err_out_free_region
;
160 dev
->io
= pci_resource_start(pdev
, 0);
161 if (snd_tea575x_init(&dev
->tea
, THIS_MODULE
)) {
162 printk(KERN_ERR
"radio-maxiradio: Unable to detect TEA575x tuner\n");
163 goto err_out_free_region
;
168 release_region(pci_resource_start(pdev
, 0), pci_resource_len(pdev
, 0));
170 v4l2_device_unregister(v4l2_dev
);
176 static void maxiradio_remove(struct pci_dev
*pdev
)
178 struct v4l2_device
*v4l2_dev
= dev_get_drvdata(&pdev
->dev
);
179 struct maxiradio
*dev
= to_maxiradio(v4l2_dev
);
181 snd_tea575x_exit(&dev
->tea
);
184 v4l2_device_unregister(v4l2_dev
);
185 release_region(pci_resource_start(pdev
, 0), pci_resource_len(pdev
, 0));
189 static struct pci_device_id maxiradio_pci_tbl
[] = {
190 { PCI_VENDOR_ID_GUILLEMOT
, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO
,
191 PCI_ANY_ID
, PCI_ANY_ID
, },
195 MODULE_DEVICE_TABLE(pci
, maxiradio_pci_tbl
);
197 static struct pci_driver maxiradio_driver
= {
198 .name
= "radio-maxiradio",
199 .id_table
= maxiradio_pci_tbl
,
200 .probe
= maxiradio_probe
,
201 .remove
= maxiradio_remove
,
204 module_pci_driver(maxiradio_driver
);