1 // SPDX-License-Identifier: GPL-2.0-only
3 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux
4 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net>
6 * Based in the radio Maestro PCI driver. Actually it uses the same chip
7 * for radio but different pci controller.
9 * I didn't have any specs I reversed engineered the protocol from
10 * the windows driver (radio.dll).
12 * The card uses the TEA5757 chip that includes a search function but it
13 * is useless as I haven't found any way to read back the frequency. If
14 * anybody does please mail me.
16 * For the pdf file see:
17 * http://www.nxp.com/acrobat_download2/expired_datasheets/TEA5757_5759_3.pdf
22 * - better pci interface thanks to Francois Romieu <romieu@cogenit.fr>
24 * 0.75 Sun Feb 4 22:51:27 EET 2001
26 * - removed support for multiple devices as it didn't work anyway
29 * - card unmutes if you change frequency
31 * (c) 2006, 2007 by Mauro Carvalho Chehab <mchehab@kernel.org>:
32 * - Conversion to V4L2 API
33 * - Uses video_ioctl2 for parsing and to add debug support
37 #include <linux/module.h>
38 #include <linux/init.h>
39 #include <linux/ioport.h>
40 #include <linux/delay.h>
41 #include <linux/mutex.h>
42 #include <linux/pci.h>
43 #include <linux/videodev2.h>
45 #include <linux/slab.h>
46 #include <media/drv-intf/tea575x.h>
47 #include <media/v4l2-device.h>
48 #include <media/v4l2-ioctl.h>
49 #include <media/v4l2-fh.h>
50 #include <media/v4l2-ctrls.h>
51 #include <media/v4l2-event.h>
53 MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
54 MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000.");
55 MODULE_LICENSE("GPL");
56 MODULE_VERSION("1.0.0");
58 static int radio_nr
= -1;
59 module_param(radio_nr
, int, 0644);
60 MODULE_PARM_DESC(radio_nr
, "Radio device number");
62 /* TEA5757 pin mappings */
63 static const int clk
= 1, data
= 2, wren
= 4, mo_st
= 8, power
= 16;
65 static atomic_t maxiradio_instance
= ATOMIC_INIT(0);
67 #define PCI_VENDOR_ID_GUILLEMOT 0x5046
68 #define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001
72 struct snd_tea575x tea
;
73 struct v4l2_device v4l2_dev
;
76 u16 io
; /* base of radio io */
79 static inline struct maxiradio
*to_maxiradio(struct v4l2_device
*v4l2_dev
)
81 return container_of(v4l2_dev
, struct maxiradio
, v4l2_dev
);
84 static void maxiradio_tea575x_set_pins(struct snd_tea575x
*tea
, u8 pins
)
86 struct maxiradio
*dev
= tea
->private_data
;
89 bits
|= (pins
& TEA575X_DATA
) ? data
: 0;
90 bits
|= (pins
& TEA575X_CLK
) ? clk
: 0;
91 bits
|= (pins
& TEA575X_WREN
) ? wren
: 0;
97 /* Note: this card cannot read out the data of the shift registers,
98 only the mono/stereo pin works. */
99 static u8
maxiradio_tea575x_get_pins(struct snd_tea575x
*tea
)
101 struct maxiradio
*dev
= tea
->private_data
;
102 u8 bits
= inb(dev
->io
);
104 return ((bits
& data
) ? TEA575X_DATA
: 0) |
105 ((bits
& mo_st
) ? TEA575X_MOST
: 0);
108 static void maxiradio_tea575x_set_direction(struct snd_tea575x
*tea
, bool output
)
112 static const struct snd_tea575x_ops maxiradio_tea_ops
= {
113 .set_pins
= maxiradio_tea575x_set_pins
,
114 .get_pins
= maxiradio_tea575x_get_pins
,
115 .set_direction
= maxiradio_tea575x_set_direction
,
118 static int maxiradio_probe(struct pci_dev
*pdev
,
119 const struct pci_device_id
*ent
)
121 struct maxiradio
*dev
;
122 struct v4l2_device
*v4l2_dev
;
123 int retval
= -ENOMEM
;
125 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
127 dev_err(&pdev
->dev
, "not enough memory\n");
131 v4l2_dev
= &dev
->v4l2_dev
;
132 v4l2_device_set_name(v4l2_dev
, "maxiradio", &maxiradio_instance
);
134 retval
= v4l2_device_register(&pdev
->dev
, v4l2_dev
);
136 v4l2_err(v4l2_dev
, "Could not register v4l2_device\n");
139 dev
->tea
.private_data
= dev
;
140 dev
->tea
.ops
= &maxiradio_tea_ops
;
141 /* The data pin cannot be read. This may be a hardware limitation, or
142 we just don't know how to read it. */
143 dev
->tea
.cannot_read_data
= true;
144 dev
->tea
.v4l2_dev
= v4l2_dev
;
145 dev
->tea
.radio_nr
= radio_nr
;
146 strscpy(dev
->tea
.card
, "Maxi Radio FM2000", sizeof(dev
->tea
.card
));
150 if (!request_region(pci_resource_start(pdev
, 0),
151 pci_resource_len(pdev
, 0), v4l2_dev
->name
)) {
152 dev_err(&pdev
->dev
, "can't reserve I/O ports\n");
156 if (pci_enable_device(pdev
))
157 goto err_out_free_region
;
159 dev
->io
= pci_resource_start(pdev
, 0);
160 if (snd_tea575x_init(&dev
->tea
, THIS_MODULE
)) {
161 printk(KERN_ERR
"radio-maxiradio: Unable to detect TEA575x tuner\n");
162 goto err_out_free_region
;
167 release_region(pci_resource_start(pdev
, 0), pci_resource_len(pdev
, 0));
169 v4l2_device_unregister(v4l2_dev
);
175 static void maxiradio_remove(struct pci_dev
*pdev
)
177 struct v4l2_device
*v4l2_dev
= pci_get_drvdata(pdev
);
178 struct maxiradio
*dev
= to_maxiradio(v4l2_dev
);
180 snd_tea575x_exit(&dev
->tea
);
183 v4l2_device_unregister(v4l2_dev
);
184 release_region(pci_resource_start(pdev
, 0), pci_resource_len(pdev
, 0));
188 static const struct pci_device_id maxiradio_pci_tbl
[] = {
189 { PCI_VENDOR_ID_GUILLEMOT
, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO
,
190 PCI_ANY_ID
, PCI_ANY_ID
, },
194 MODULE_DEVICE_TABLE(pci
, maxiradio_pci_tbl
);
196 static struct pci_driver maxiradio_driver
= {
197 .name
= "radio-maxiradio",
198 .id_table
= maxiradio_pci_tbl
,
199 .probe
= maxiradio_probe
,
200 .remove
= maxiradio_remove
,
203 module_pci_driver(maxiradio_driver
);