diff options
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/Kconfig | 125 | ||||
-rw-r--r-- | drivers/media/radio/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/radio/radio-aimslab.c | 440 | ||||
-rw-r--r-- | drivers/media/radio/radio-aztech.c | 372 | ||||
-rw-r--r-- | drivers/media/radio/radio-gemtek.c | 494 | ||||
-rw-r--r-- | drivers/media/radio/radio-isa.c | 340 | ||||
-rw-r--r-- | drivers/media/radio/radio-isa.h | 105 | ||||
-rw-r--r-- | drivers/media/radio/radio-keene.c | 427 | ||||
-rw-r--r-- | drivers/media/radio/radio-maxiradio.c | 379 | ||||
-rw-r--r-- | drivers/media/radio/radio-rtrack2.c | 332 | ||||
-rw-r--r-- | drivers/media/radio/radio-sf16fmr2.c | 61 | ||||
-rw-r--r-- | drivers/media/radio/radio-tea5764.c | 19 | ||||
-rw-r--r-- | drivers/media/radio/radio-terratec.c | 365 | ||||
-rw-r--r-- | drivers/media/radio/radio-trust.c | 388 | ||||
-rw-r--r-- | drivers/media/radio/radio-typhoon.c | 366 | ||||
-rw-r--r-- | drivers/media/radio/radio-zoltrix.c | 442 | ||||
-rw-r--r-- | drivers/media/radio/saa7706h.c | 13 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-i2c.c | 28 | ||||
-rw-r--r-- | drivers/media/radio/si4713-i2c.c | 15 | ||||
-rw-r--r-- | drivers/media/radio/tef6862.c | 14 |
20 files changed, 1740 insertions, 2987 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index e954781c90b..8db2d7f4b52 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -43,7 +43,7 @@ config USB_DSBR config RADIO_MAXIRADIO tristate "Guillemot MAXI Radio FM 2000 radio" - depends on VIDEO_V4L2 && PCI + depends on VIDEO_V4L2 && PCI && SND ---help--- Choose Y here if you have this radio card. This card may also be found as Gemtek PCI FM. @@ -80,6 +80,16 @@ config RADIO_SI4713 To compile this driver as a module, choose M here: the module will be called radio-si4713. +config USB_KEENE + tristate "Keene FM Transmitter USB support" + depends on USB && VIDEO_V4L2 + ---help--- + Say Y here if you want to connect this type of FM transmitter + to your computer's USB port. + + To compile this driver as a module, choose M here: the + module will be called radio-keene. + config RADIO_TEA5764 tristate "TEA5764 I2C FM radio support" depends on I2C && VIDEO_V4L2 @@ -167,6 +177,10 @@ menuconfig V4L_RADIO_ISA_DRIVERS if V4L_RADIO_ISA_DRIVERS +config RADIO_ISA + depends on ISA + tristate + config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" depends on ISA && VIDEO_V4L2 @@ -174,20 +188,13 @@ config RADIO_CADET Choose Y here if you have one of these AM/FM radio cards, and then fill in the port address below. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. - - Further documentation on this driver can be found on the WWW at - <http://linux.blackhawke.net/cadet/>. - To compile this driver as a module, choose M here: the module will be called radio-cadet. config RADIO_RTRACK tristate "AIMSlab RadioTrack (aka RadioReveal) support" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -201,11 +208,7 @@ config RADIO_RTRACK You must also pass the module a suitable io parameter, 0x248 has been reported to be used by these cards. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. More information is - contained in the file + More information is contained in the file <file:Documentation/video4linux/radiotrack.txt>. To compile this driver as a module, choose M here: the @@ -214,7 +217,7 @@ config RADIO_RTRACK config RADIO_RTRACK_PORT hex "RadioTrack i/o port (0x20f or 0x30f)" depends on RADIO_RTRACK=y - default "20f" + default "30f" help Enter either 0x30f or 0x20f here. The card default is 0x30f, if you haven't changed the jumper setting on the card. @@ -222,14 +225,14 @@ config RADIO_RTRACK_PORT config RADIO_RTRACK2 tristate "AIMSlab RadioTrack II support" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. + Note: this driver hasn't been tested since a long time due to lack + of hardware. If you have this hardware, then please contact the + linux-media mailinglist. To compile this driver as a module, choose M here: the module will be called radio-rtrack2. @@ -245,15 +248,11 @@ config RADIO_RTRACK2_PORT config RADIO_AZTECH tristate "Aztech/Packard Bell Radio" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. - To compile this driver as a module, choose M here: the module will be called radio-aztech. @@ -269,6 +268,7 @@ config RADIO_AZTECH_PORT config RADIO_GEMTEK tristate "GemTek Radio card (or compatible) support" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- Choose Y here if you have this FM radio card, and then fill in the I/O port address and settings below. The following cards either have @@ -278,23 +278,21 @@ config RADIO_GEMTEK - Typhoon Radio card (some models) - Hama Radio card - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. - To compile this driver as a module, choose M here: the module will be called radio-gemtek. config RADIO_GEMTEK_PORT - hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0c24c or 0x28c)" + hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c)" depends on RADIO_GEMTEK=y default "34c" help - Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is - 0x34c, if you haven't changed the jumper setting on the card. On - Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O + Enter either 0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c here. The + card default is 0x34c, if you haven't changed the jumper setting + on the card. + + On Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O port is 0x20c, 0x248 or 0x28c. + If automatic I/O port probing is enabled this port will be used only in case of automatic probing failure, ie. as a fallback. @@ -318,11 +316,6 @@ config RADIO_MIROPCM20 sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this is required for the radio-miropcm20. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. - To compile this driver as a module, choose M here: the module will be called radio-miropcm20. @@ -332,11 +325,6 @@ config RADIO_SF16FMI ---help--- Choose Y here if you have one of these FM radio cards. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. - To compile this driver as a module, choose M here: the module will be called radio-sf16fmi. @@ -346,50 +334,35 @@ config RADIO_SF16FMR2 ---help--- Choose Y here if you have one of these FM radio cards. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found on the WWW at - <http://roadrunner.swansea.uk.linux.org/v4l.shtml>. - To compile this driver as a module, choose M here: the module will be called radio-sf16fmr2. config RADIO_TERRATEC tristate "TerraTec ActiveRadio ISA Standalone" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- - Choose Y here if you have this FM radio card, and then fill in the - port address below. (TODO) + Choose Y here if you have this FM radio card. - Note: This driver is in its early stages. Right now volume and - frequency control and muting works at least for me, but - unfortunately I have not found anybody who wants to use this card - with Linux. So if it is this what YOU are trying to do right now, - PLEASE DROP ME A NOTE!! Rolf Offermanns <rolf@offermanns.de>. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. + Note: this driver hasn't been tested since a long time due to lack + of hardware. If you have this hardware, then please contact the + linux-media mailinglist. To compile this driver as a module, choose M here: the module will be called radio-terratec. -config RADIO_TERRATEC_PORT - hex "Terratec i/o port (normally 0x590)" - depends on RADIO_TERRATEC=y - default "590" - help - Fill in the I/O port of your TerraTec FM radio card. If unsure, go - with the default. - config RADIO_TRUST tristate "Trust FM radio card" depends on ISA && VIDEO_V4L2 + select RADIO_ISA help This is a driver for the Trust FM radio cards. Say Y if you have such a card and want to use it under Linux. + Note: this driver hasn't been tested since a long time due to lack + of hardware. If you have this hardware, then please contact the + linux-media mailinglist. + To compile this driver as a module, choose M here: the module will be called radio-trust. @@ -404,14 +377,14 @@ config RADIO_TRUST_PORT config RADIO_TYPHOON tristate "Typhoon Radio (a.k.a. EcoRadio)" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address and the frequency used for muting below. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. + Note: this driver hasn't been tested since a long time due to lack + of hardware. If you have this hardware, then please contact the + linux-media mailinglist. To compile this driver as a module, choose M here: the module will be called radio-typhoon. @@ -438,14 +411,14 @@ config RADIO_TYPHOON_MUTEFREQ config RADIO_ZOLTRIX tristate "Zoltrix Radio" depends on ISA && VIDEO_V4L2 + select RADIO_ISA ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. + Note: this driver hasn't been tested since a long time due to lack + of hardware. If you have this hardware, then please contact the + linux-media mailinglist. To compile this driver as a module, choose M here: the module will be called radio-zoltrix. diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 390daf94d84..ca8c7d134b9 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -2,6 +2,7 @@ # Makefile for the kernel character device drivers. # +obj-$(CONFIG_RADIO_ISA) += radio-isa.o obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o @@ -20,6 +21,7 @@ obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_RADIO_SI470X) += si470x/ obj-$(CONFIG_USB_MR800) += radio-mr800.o +obj-$(CONFIG_USB_KEENE) += radio-keene.o obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o obj-$(CONFIG_RADIO_TEF6862) += tef6862.o diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 1c3f8440a55..98e0c8c2031 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -1,16 +1,13 @@ -/* radiotrack (radioreveal) driver for Linux radio support - * (c) 1997 M. Kirkwood +/* + * AimsLab RadioTrack (aka RadioVeveal) driver + * + * Copyright 1997 M. Kirkwood + * + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> * - * History: - * 1999-02-24 Russell Kroll <rkroll@exploits.org> - * Fine tuning/VIDEO_TUNER_LOW - * Frequency range expanded to start at 87 MHz - * - * TODO: Allow for more than one of these foolish entities :-) - * * Notes on the hardware (reverse engineered from other peoples' * reverse engineering of AIMS' code :-) * @@ -26,6 +23,7 @@ * wait(a_wee_while); * out(port, stop_changing_the_volume); * + * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. */ #include <linux/module.h> /* Modules */ @@ -34,401 +32,179 @@ #include <linux/delay.h> /* msleep */ #include <linux/videodev2.h> /* kernel radio structs */ #include <linux/io.h> /* outb, outb_p */ +#include <linux/slab.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-ctrls.h> +#include "radio-isa.h" -MODULE_AUTHOR("M.Kirkwood"); +MODULE_AUTHOR("M. Kirkwood"); MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.0.3"); +MODULE_VERSION("1.0.0"); #ifndef CONFIG_RADIO_RTRACK_PORT #define CONFIG_RADIO_RTRACK_PORT -1 #endif -static int io = CONFIG_RADIO_RTRACK_PORT; -static int radio_nr = -1; +#define RTRACK_MAX 2 -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)"); -module_param(radio_nr, int, 0); +static int io[RTRACK_MAX] = { [0] = CONFIG_RADIO_RTRACK_PORT, + [1 ... (RTRACK_MAX - 1)] = -1 }; +static int radio_nr[RTRACK_MAX] = { [0 ... (RTRACK_MAX - 1)] = -1 }; -struct rtrack -{ - struct v4l2_device v4l2_dev; - struct video_device vdev; - int port; +module_param_array(io, int, NULL, 0444); +MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)"); +module_param_array(radio_nr, int, NULL, 0444); +MODULE_PARM_DESC(radio_nr, "Radio device numbers"); + +struct rtrack { + struct radio_isa_card isa; int curvol; - unsigned long curfreq; - int muted; - int io; - struct mutex lock; }; -static struct rtrack rtrack_card; - -/* local things */ - -static void rt_decvol(struct rtrack *rt) -{ - outb(0x58, rt->io); /* volume down + sigstr + on */ - msleep(100); - outb(0xd8, rt->io); /* volume steady + sigstr + on */ -} - -static void rt_incvol(struct rtrack *rt) -{ - outb(0x98, rt->io); /* volume up + sigstr + on */ - msleep(100); - outb(0xd8, rt->io); /* volume steady + sigstr + on */ -} - -static void rt_mute(struct rtrack *rt) -{ - rt->muted = 1; - mutex_lock(&rt->lock); - outb(0xd0, rt->io); /* volume steady, off */ - mutex_unlock(&rt->lock); -} - -static int rt_setvol(struct rtrack *rt, int vol) +static struct radio_isa_card *rtrack_alloc(void) { - int i; - - mutex_lock(&rt->lock); - - if (vol == rt->curvol) { /* requested volume = current */ - if (rt->muted) { /* user is unmuting the card */ - rt->muted = 0; - outb(0xd8, rt->io); /* enable card */ - } - mutex_unlock(&rt->lock); - return 0; - } - - if (vol == 0) { /* volume = 0 means mute the card */ - outb(0x48, rt->io); /* volume down but still "on" */ - msleep(2000); /* make sure it's totally down */ - outb(0xd0, rt->io); /* volume steady, off */ - rt->curvol = 0; /* track the volume state! */ - mutex_unlock(&rt->lock); - return 0; - } + struct rtrack *rt = kzalloc(sizeof(struct rtrack), GFP_KERNEL); - rt->muted = 0; - if (vol > rt->curvol) - for (i = rt->curvol; i < vol; i++) - rt_incvol(rt); - else - for (i = rt->curvol; i > vol; i--) - rt_decvol(rt); - - rt->curvol = vol; - mutex_unlock(&rt->lock); - return 0; + if (rt) + rt->curvol = 0xff; + return rt ? &rt->isa : NULL; } -/* the 128+64 on these outb's is to keep the volume stable while tuning - * without them, the volume _will_ creep up with each frequency change - * and bit 4 (+16) is to keep the signal strength meter enabled +/* The 128+64 on these outb's is to keep the volume stable while tuning. + * Without them, the volume _will_ creep up with each frequency change + * and bit 4 (+16) is to keep the signal strength meter enabled. */ -static void send_0_byte(struct rtrack *rt) +static void send_0_byte(struct radio_isa_card *isa, int on) { - if (rt->curvol == 0 || rt->muted) { - outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */ - outb_p(128+64+16+2+1, rt->io); /* clock */ - } - else { - outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */ - outb_p(128+64+16+8+2+1, rt->io); /* clock */ - } + outb_p(128+64+16+on+1, isa->io); /* wr-enable + data low */ + outb_p(128+64+16+on+2+1, isa->io); /* clock */ msleep(1); } -static void send_1_byte(struct rtrack *rt) +static void send_1_byte(struct radio_isa_card *isa, int on) { - if (rt->curvol == 0 || rt->muted) { - outb_p(128+64+16+4 +1, rt->io); /* wr-enable+data high */ - outb_p(128+64+16+4+2+1, rt->io); /* clock */ - } - else { - outb_p(128+64+16+8+4 +1, rt->io); /* on+wr-enable+data high */ - outb_p(128+64+16+8+4+2+1, rt->io); /* clock */ - } - + outb_p(128+64+16+on+4+1, isa->io); /* wr-enable+data high */ + outb_p(128+64+16+on+4+2+1, isa->io); /* clock */ msleep(1); } -static int rt_setfreq(struct rtrack *rt, unsigned long freq) +static int rtrack_s_frequency(struct radio_isa_card *isa, u32 freq) { + int on = v4l2_ctrl_g_ctrl(isa->mute) ? 0 : 8; int i; - mutex_lock(&rt->lock); /* Stop other ops interfering */ - - rt->curfreq = freq; - - /* now uses VIDEO_TUNER_LOW for fine tuning */ - freq += 171200; /* Add 10.7 MHz IF */ freq /= 800; /* Convert to 50 kHz units */ - send_0_byte(rt); /* 0: LSB of frequency */ + send_0_byte(isa, on); /* 0: LSB of frequency */ for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ if (freq & (1 << i)) - send_1_byte(rt); + send_1_byte(isa, on); else - send_0_byte(rt); - - send_0_byte(rt); /* 14: test bit - always 0 */ - send_0_byte(rt); /* 15: test bit - always 0 */ - - send_0_byte(rt); /* 16: band data 0 - always 0 */ - send_0_byte(rt); /* 17: band data 1 - always 0 */ - send_0_byte(rt); /* 18: band data 2 - always 0 */ - send_0_byte(rt); /* 19: time base - always 0 */ - - send_0_byte(rt); /* 20: spacing (0 = 25 kHz) */ - send_1_byte(rt); /* 21: spacing (1 = 25 kHz) */ - send_0_byte(rt); /* 22: spacing (0 = 25 kHz) */ - send_1_byte(rt); /* 23: AM/FM (FM = 1, always) */ - - if (rt->curvol == 0 || rt->muted) - outb(0xd0, rt->io); /* volume steady + sigstr */ - else - outb(0xd8, rt->io); /* volume steady + sigstr + on */ - - mutex_unlock(&rt->lock); - - return 0; -} - -static int rt_getsigstr(struct rtrack *rt) -{ - int sig = 1; - - mutex_lock(&rt->lock); - if (inb(rt->io) & 2) /* bit set = no signal present */ - sig = 0; - mutex_unlock(&rt->lock); - return sig; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *v) -{ - strlcpy(v->driver, "radio-aimslab", sizeof(v->driver)); - strlcpy(v->card, "RadioTrack", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - struct rtrack *rt = video_drvdata(file); + send_0_byte(isa, on); - if (v->index > 0) - return -EINVAL; + send_0_byte(isa, on); /* 14: test bit - always 0 */ + send_0_byte(isa, on); /* 15: test bit - always 0 */ - strlcpy(v->name, "FM", sizeof(v->name)); - v->type = V4L2_TUNER_RADIO; - v->rangelow = 87 * 16000; - v->rangehigh = 108 * 16000; - v->rxsubchans = V4L2_TUNER_SUB_MONO; - v->capability = V4L2_TUNER_CAP_LOW; - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xffff * rt_getsigstr(rt); - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - return v->index ? -EINVAL : 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct rtrack *rt = video_drvdata(file); - - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) - return -EINVAL; - rt_setfreq(rt, f->frequency); - return 0; -} + send_0_byte(isa, on); /* 16: band data 0 - always 0 */ + send_0_byte(isa, on); /* 17: band data 1 - always 0 */ + send_0_byte(isa, on); /* 18: band data 2 - always 0 */ + send_0_byte(isa, on); /* 19: time base - always 0 */ -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct rtrack *rt = video_drvdata(file); + send_0_byte(isa, on); /* 20: spacing (0 = 25 kHz) */ + send_1_byte(isa, on); /* 21: spacing (1 = 25 kHz) */ + send_0_byte(isa, on); /* 22: spacing (0 = 25 kHz) */ + send_1_byte(isa, on); /* 23: AM/FM (FM = 1, always) */ - if (f->tuner != 0) - return -EINVAL; - f->type = V4L2_TUNER_RADIO; - f->frequency = rt->curfreq; + outb(0xd0 + on, isa->io); /* volume steady + sigstr */ return 0; } -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) +static u32 rtrack_g_signal(struct radio_isa_card *isa) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff); - } - return -EINVAL; + /* bit set = no signal present */ + return 0xffff * !(inb(isa->io) & 2); } -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) +static int rtrack_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) { - struct rtrack *rt = video_drvdata(file); + struct rtrack *rt = container_of(isa, struct rtrack, isa); + int curvol = rt->curvol; - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = rt->muted; - return 0; - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = rt->curvol; + if (mute) { + outb(0xd0, isa->io); /* volume steady + sigstr + off */ return 0; } - return -EINVAL; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct rtrack *rt = video_drvdata(file); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) - rt_mute(rt); - else - rt_setvol(rt, rt->curvol); - return 0; - case V4L2_CID_AUDIO_VOLUME: - rt_setvol(rt, ctrl->value); - return 0; + if (vol == 0) { /* volume = 0 means mute the card */ + outb(0x48, isa->io); /* volume down but still "on" */ + msleep(curvol * 3); /* make sure it's totally down */ + } else if (curvol < vol) { + outb(0x98, isa->io); /* volume up + sigstr + on */ + for (; curvol < vol; curvol++) + udelay(3000); + } else if (curvol > vol) { + outb(0x58, isa->io); /* volume down + sigstr + on */ + for (; curvol > vol; curvol--) + udelay(3000); } - return -EINVAL; -} - -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; + outb(0xd8, isa->io); /* volume steady + sigstr + on */ + rt->curvol = vol; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +/* Mute card - prevents noisy bootups */ +static int rtrack_initialize(struct radio_isa_card *isa) { - return i ? -EINVAL : 0; -} - -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + /* this ensures that the volume is all the way up */ + outb(0x90, isa->io); /* volume up but still "on" */ + msleep(3000); /* make sure it's totally up */ + outb(0xc0, isa->io); /* steady volume, mute card */ return 0; } -static int vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - return a->index ? -EINVAL : 0; -} - -static const struct v4l2_file_operations rtrack_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = video_ioctl2, +static const struct radio_isa_ops rtrack_ops = { + .alloc = rtrack_alloc, + .init = rtrack_initialize, + .s_mute_volume = rtrack_s_mute_volume, + .s_frequency = rtrack_s_frequency, + .g_signal = rtrack_g_signal, }; -static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, +static const int rtrack_ioports[] = { 0x20f, 0x30f }; + +static struct radio_isa_driver rtrack_driver = { + .driver = { + .match = radio_isa_match, + .probe = radio_isa_probe, + .remove = radio_isa_remove, + .driver = { + .name = "radio-aimslab", + }, + }, + .io_params = io, + .radio_nr_params = radio_nr, + .io_ports = rtrack_ioports, + .num_of_io_ports = ARRAY_SIZE(rtrack_ioports), + .region_size = 2, + .card = "AIMSlab RadioTrack/RadioReveal", + .ops = &rtrack_ops, + .has_stereo = true, + .max_volume = 0xff, }; static int __init rtrack_init(void) { - struct rtrack *rt = &rtrack_card; - struct v4l2_device *v4l2_dev = &rt->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); - rt->io = io; - - if (rt->io == -1) { - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); - return -EINVAL; - } - - if (!request_region(rt->io, 2, "rtrack")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); - return -EBUSY; - } - - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(rt->io, 2); - v4l2_err(v4l2_dev, "could not register v4l2_device\n"); - return res; - } - - strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); - rt->vdev.v4l2_dev = v4l2_dev; - rt->vdev.fops = &rtrack_fops; - rt->vdev.ioctl_ops = &rtrack_ioctl_ops; - rt->vdev.release = video_device_release_empty; - video_set_drvdata(&rt->vdev, rt); - - /* Set up the I/O locking */ - - mutex_init(&rt->lock); - - /* mute card - prevents noisy bootups */ - - /* this ensures that the volume is all the way down */ - outb(0x48, rt->io); /* volume down but still "on" */ - msleep(2000); /* make sure it's totally down */ - outb(0xc0, rt->io); /* steady volume, mute card */ - - if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(&rt->v4l2_dev); - release_region(rt->io, 2); - return -EINVAL; - } - v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); - - return 0; + return isa_register_driver(&rtrack_driver.driver, RTRACK_MAX); } static void __exit rtrack_exit(void) { - struct rtrack *rt = &rtrack_card; - - video_unregister_device(&rt->vdev); - v4l2_device_unregister(&rt->v4l2_dev); - release_region(rt->io, 2); + isa_unregister_driver(&rtrack_driver.driver); } module_init(rtrack_init); module_exit(rtrack_exit); - diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index eed7b084073..177bcbd7a7c 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -1,5 +1,7 @@ -/* radio-aztech.c - Aztech radio card driver for Linux 2.2 +/* + * radio-aztech.c - Aztech radio card driver * + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl> * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> * Adapted to support the Video for Linux API by * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: @@ -10,19 +12,7 @@ * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) * William McGrath (wmcgrath@twilight.vtc.vsc.edu) * - * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/ - * along with more information on the card itself. - * - * History: - * 1999-02-24 Russell Kroll <rkroll@exploits.org> - * Fine tuning/VIDEO_TUNER_LOW - * Range expanded to 87-108 MHz (from 87.9-107.8) - * - * Notable changes from the original source: - * - includes stripped down to the essentials - * - for loops used as delays replaced with udelay() - * - #defines removed, changed to static values - * - tuning structure changed - no more character arrays, other changes + * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. */ #include <linux/module.h> /* Modules */ @@ -31,126 +21,72 @@ #include <linux/delay.h> /* udelay */ #include <linux/videodev2.h> /* kernel radio structs */ #include <linux/io.h> /* outb, outb_p */ +#include <linux/slab.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-ctrls.h> +#include "radio-isa.h" MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); MODULE_DESCRIPTION("A driver for the Aztech radio card."); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.0.3"); +MODULE_VERSION("1.0.0"); /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ - #ifndef CONFIG_RADIO_AZTECH_PORT #define CONFIG_RADIO_AZTECH_PORT -1 #endif -static int io = CONFIG_RADIO_AZTECH_PORT; -static int radio_nr = -1; -static int radio_wait_time = 1000; +#define AZTECH_MAX 2 -module_param(io, int, 0); -module_param(radio_nr, int, 0); -MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)"); +static int io[AZTECH_MAX] = { [0] = CONFIG_RADIO_AZTECH_PORT, + [1 ... (AZTECH_MAX - 1)] = -1 }; +static int radio_nr[AZTECH_MAX] = { [0 ... (AZTECH_MAX - 1)] = -1 }; +static const int radio_wait_time = 1000; -struct aztech -{ - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; +module_param_array(io, int, NULL, 0444); +MODULE_PARM_DESC(io, |