* [PATCH 0/2] tea575x: Move from sound to media
@ 2013-07-28 20:01 Ondrej Zary
2013-07-28 20:01 ` [PATCH 1/2] tea575x: Move header " Ondrej Zary
2013-07-29 14:53 ` [alsa-devel] [PATCH 0/2] tea575x: Move " Takashi Iwai
0 siblings, 2 replies; 6+ messages in thread
From: Ondrej Zary @ 2013-07-28 20:01 UTC (permalink / raw)
To: Hans Verkuil; +Cc: alsa-devel, linux-media
Hello,
TEA575x is neither a sound device nor an i2c device. Let's finally move it
from sound/i2c/other to drivers/media/radio.
Tested with snd-es1968, snd-fm801 and radio-sf16fmr2.
--
Ondrej Zary
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] tea575x: Move header from sound to media
2013-07-28 20:01 [PATCH 0/2] tea575x: Move from sound to media Ondrej Zary
@ 2013-07-28 20:01 ` Ondrej Zary
2013-07-28 20:01 ` [PATCH 2/2] tea575x: Move " Ondrej Zary
2013-07-29 7:56 ` [PATCH 1/2] tea575x: Move header " Hans Verkuil
2013-07-29 14:53 ` [alsa-devel] [PATCH 0/2] tea575x: Move " Takashi Iwai
1 sibling, 2 replies; 6+ messages in thread
From: Ondrej Zary @ 2013-07-28 20:01 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media, alsa-devel
Move include/sound/tea575x-tuner.h to include/media/tea575x.h and update files that include it.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
drivers/media/radio/radio-maxiradio.c | 2 +-
drivers/media/radio/radio-sf16fmr2.c | 2 +-
drivers/media/radio/radio-shark.c | 2 +-
include/media/tea575x.h | 79 +++++++++++++++++++++++++++++++++
include/sound/tea575x-tuner.h | 79 ---------------------------------
sound/i2c/other/tea575x-tuner.c | 2 +-
sound/pci/es1968.c | 2 +-
sound/pci/fm801.c | 2 +-
8 files changed, 85 insertions(+), 85 deletions(-)
create mode 100644 include/media/tea575x.h
delete mode 100644 include/sound/tea575x-tuner.h
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 1d1c9e1..5236035 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -42,7 +42,7 @@
#include <linux/videodev2.h>
#include <linux/io.h>
#include <linux/slab.h>
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 9c09904..f1e3714 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -14,7 +14,7 @@
#include <linux/io.h> /* outb, outb_p */
#include <linux/isa.h>
#include <linux/pnp.h>
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
MODULE_AUTHOR("Ondrej Zary");
MODULE_DESCRIPTION("MediaForte SF16-FMR2 and SF16-FMD2 FM radio card driver");
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c
index 8fa18ab..b914772 100644
--- a/drivers/media/radio/radio-shark.c
+++ b/drivers/media/radio/radio-shark.c
@@ -33,7 +33,7 @@
#include <linux/usb.h>
#include <linux/workqueue.h>
#include <media/v4l2-device.h>
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
#if defined(CONFIG_LEDS_CLASS) || \
(defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE))
diff --git a/include/media/tea575x.h b/include/media/tea575x.h
new file mode 100644
index 0000000..2d4fa59
--- /dev/null
+++ b/include/media/tea575x.h
@@ -0,0 +1,79 @@
+#ifndef __SOUND_TEA575X_TUNER_H
+#define __SOUND_TEA575X_TUNER_H
+
+/*
+ * ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
+ *
+ * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+
+#define TEA575X_FMIF 10700
+#define TEA575X_AMIF 450
+
+#define TEA575X_DATA (1 << 0)
+#define TEA575X_CLK (1 << 1)
+#define TEA575X_WREN (1 << 2)
+#define TEA575X_MOST (1 << 3)
+
+struct snd_tea575x;
+
+struct snd_tea575x_ops {
+ /* Drivers using snd_tea575x must either define read_ and write_val */
+ void (*write_val)(struct snd_tea575x *tea, u32 val);
+ u32 (*read_val)(struct snd_tea575x *tea);
+ /* Or define the 3 pin functions */
+ void (*set_pins)(struct snd_tea575x *tea, u8 pins);
+ u8 (*get_pins)(struct snd_tea575x *tea);
+ void (*set_direction)(struct snd_tea575x *tea, bool output);
+};
+
+struct snd_tea575x {
+ struct v4l2_device *v4l2_dev;
+ struct v4l2_file_operations fops;
+ struct video_device vd; /* video device */
+ int radio_nr; /* radio_nr */
+ bool tea5759; /* 5759 chip is present */
+ bool has_am; /* Device can tune to AM freqs */
+ bool cannot_read_data; /* Device cannot read the data pin */
+ bool cannot_mute; /* Device cannot mute */
+ bool mute; /* Device is muted? */
+ bool stereo; /* receiving stereo */
+ bool tuned; /* tuned to a station */
+ unsigned int val; /* hw value */
+ u32 band; /* 0: FM, 1: FM-Japan, 2: AM */
+ u32 freq; /* frequency */
+ struct mutex mutex;
+ struct snd_tea575x_ops *ops;
+ void *private_data;
+ u8 card[32];
+ u8 bus_info[32];
+ struct v4l2_ctrl_handler ctrl_handler;
+ int (*ext_init)(struct snd_tea575x *tea);
+};
+
+int snd_tea575x_hw_init(struct snd_tea575x *tea);
+int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner);
+void snd_tea575x_exit(struct snd_tea575x *tea);
+void snd_tea575x_set_freq(struct snd_tea575x *tea);
+
+#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
deleted file mode 100644
index 2d4fa59..0000000
--- a/include/sound/tea575x-tuner.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef __SOUND_TEA575X_TUNER_H
-#define __SOUND_TEA575X_TUNER_H
-
-/*
- * ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
- *
- * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/videodev2.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-device.h>
-
-#define TEA575X_FMIF 10700
-#define TEA575X_AMIF 450
-
-#define TEA575X_DATA (1 << 0)
-#define TEA575X_CLK (1 << 1)
-#define TEA575X_WREN (1 << 2)
-#define TEA575X_MOST (1 << 3)
-
-struct snd_tea575x;
-
-struct snd_tea575x_ops {
- /* Drivers using snd_tea575x must either define read_ and write_val */
- void (*write_val)(struct snd_tea575x *tea, u32 val);
- u32 (*read_val)(struct snd_tea575x *tea);
- /* Or define the 3 pin functions */
- void (*set_pins)(struct snd_tea575x *tea, u8 pins);
- u8 (*get_pins)(struct snd_tea575x *tea);
- void (*set_direction)(struct snd_tea575x *tea, bool output);
-};
-
-struct snd_tea575x {
- struct v4l2_device *v4l2_dev;
- struct v4l2_file_operations fops;
- struct video_device vd; /* video device */
- int radio_nr; /* radio_nr */
- bool tea5759; /* 5759 chip is present */
- bool has_am; /* Device can tune to AM freqs */
- bool cannot_read_data; /* Device cannot read the data pin */
- bool cannot_mute; /* Device cannot mute */
- bool mute; /* Device is muted? */
- bool stereo; /* receiving stereo */
- bool tuned; /* tuned to a station */
- unsigned int val; /* hw value */
- u32 band; /* 0: FM, 1: FM-Japan, 2: AM */
- u32 freq; /* frequency */
- struct mutex mutex;
- struct snd_tea575x_ops *ops;
- void *private_data;
- u8 card[32];
- u8 bus_info[32];
- struct v4l2_ctrl_handler ctrl_handler;
- int (*ext_init)(struct snd_tea575x *tea);
-};
-
-int snd_tea575x_hw_init(struct snd_tea575x *tea);
-int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner);
-void snd_tea575x_exit(struct snd_tea575x *tea);
-void snd_tea575x_set_freq(struct snd_tea575x *tea);
-
-#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 46ec4dff..cef0698 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -31,7 +31,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 5e2ec96..b0e3d92 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -113,7 +113,7 @@
#include <sound/initval.h>
#ifdef CONFIG_SND_ES1968_RADIO
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
#endif
#define CARD_NAME "ESS Maestro1/2"
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 706c5b6..45bc8a9 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -37,7 +37,7 @@
#include <asm/io.h>
#ifdef CONFIG_SND_FM801_TEA575X_BOOL
-#include <sound/tea575x-tuner.h>
+#include <media/tea575x.h>
#endif
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
--
Ondrej Zary
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] tea575x: Move from sound to media
2013-07-28 20:01 ` [PATCH 1/2] tea575x: Move header " Ondrej Zary
@ 2013-07-28 20:01 ` Ondrej Zary
2013-07-29 7:58 ` Hans Verkuil
2013-07-29 7:56 ` [PATCH 1/2] tea575x: Move header " Hans Verkuil
1 sibling, 1 reply; 6+ messages in thread
From: Ondrej Zary @ 2013-07-28 20:01 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media, alsa-devel
Move tea575x from sound/i2c/other to drivers/media/radio
Includes Kconfig changes by Hans Verkuil.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
drivers/media/radio/Kconfig | 12 +-
drivers/media/radio/Makefile | 1 +
drivers/media/radio/tea575x.c | 584 +++++++++++++++++++++++++++++++++++++++
sound/i2c/other/Makefile | 2 -
sound/i2c/other/tea575x-tuner.c | 584 ---------------------------------------
sound/pci/Kconfig | 9 +-
6 files changed, 598 insertions(+), 594 deletions(-)
create mode 100644 drivers/media/radio/tea575x.c
delete mode 100644 sound/i2c/other/tea575x-tuner.c
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index d529ba7..39882dd 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -12,6 +12,9 @@ menuconfig RADIO_ADAPTERS
if RADIO_ADAPTERS && VIDEO_V4L2
+config RADIO_TEA575X
+ tristate
+
config RADIO_SI470X
bool "Silicon Labs Si470x FM Radio Receiver support"
depends on VIDEO_V4L2
@@ -61,7 +64,8 @@ config USB_DSBR
config RADIO_MAXIRADIO
tristate "Guillemot MAXI Radio FM 2000 radio"
- depends on VIDEO_V4L2 && PCI && SND
+ depends on VIDEO_V4L2 && PCI
+ select RADIO_TEA575X
---help---
Choose Y here if you have this radio card. This card may also be
found as Gemtek PCI FM.
@@ -76,7 +80,8 @@ config RADIO_MAXIRADIO
config RADIO_SHARK
tristate "Griffin radioSHARK USB radio receiver"
- depends on USB && SND
+ depends on USB
+ select RADIO_TEA575X
---help---
Choose Y here if you have this radio receiver.
@@ -393,7 +398,8 @@ config RADIO_SF16FMI
config RADIO_SF16FMR2
tristate "SF16-FMR2/SF16-FMD2 Radio"
- depends on ISA && VIDEO_V4L2 && SND
+ depends on ISA && VIDEO_V4L2
+ select RADIO_TEA575X
---help---
Choose Y here if you have one of these FM radio cards.
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 0dcdb32..3b64560 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
obj-$(CONFIG_RADIO_WL128X) += wl128x/
+obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
shark2-objs := radio-shark2.o radio-tea5777.o
diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c
new file mode 100644
index 0000000..cef0698
--- /dev/null
+++ b/drivers/media/radio/tea575x.c
@@ -0,0 +1,584 @@
+/*
+ * ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
+ *
+ * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/tea575x.h>
+
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
+MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
+MODULE_LICENSE("GPL");
+
+/*
+ * definitions
+ */
+
+#define TEA575X_BIT_SEARCH (1<<24) /* 1 = search action, 0 = tuned */
+#define TEA575X_BIT_UPDOWN (1<<23) /* 0 = search down, 1 = search up */
+#define TEA575X_BIT_MONO (1<<22) /* 0 = stereo, 1 = mono */
+#define TEA575X_BIT_BAND_MASK (3<<20)
+#define TEA575X_BIT_BAND_FM (0<<20)
+#define TEA575X_BIT_BAND_MW (1<<20)
+#define TEA575X_BIT_BAND_LW (2<<20)
+#define TEA575X_BIT_BAND_SW (3<<20)
+#define TEA575X_BIT_PORT_0 (1<<19) /* user bit */
+#define TEA575X_BIT_PORT_1 (1<<18) /* user bit */
+#define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */
+#define TEA575X_BIT_SEARCH_5_28 (0<<16) /* FM >5uV, AM >28uV */
+#define TEA575X_BIT_SEARCH_10_40 (1<<16) /* FM >10uV, AM > 40uV */
+#define TEA575X_BIT_SEARCH_30_63 (2<<16) /* FM >30uV, AM > 63uV */
+#define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */
+#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
+#define TEA575X_BIT_FREQ_MASK 0x7fff
+
+enum { BAND_FM, BAND_FM_JAPAN, BAND_AM };
+
+static const struct v4l2_frequency_band bands[] = {
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 87500 * 16,
+ .rangehigh = 108000 * 16,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 76000 * 16,
+ .rangehigh = 91000 * 16,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 1,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 530 * 16,
+ .rangehigh = 1710 * 16,
+ .modulation = V4L2_BAND_MODULATION_AM,
+ },
+};
+
+/*
+ * lowlevel part
+ */
+
+static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
+{
+ u16 l;
+ u8 data;
+
+ if (tea->ops->write_val)
+ return tea->ops->write_val(tea, val);
+
+ tea->ops->set_direction(tea, 1);
+ udelay(16);
+
+ for (l = 25; l > 0; l--) {
+ data = (val >> 24) & TEA575X_DATA;
+ val <<= 1; /* shift data */
+ tea->ops->set_pins(tea, data | TEA575X_WREN);
+ udelay(2);
+ tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
+ udelay(2);
+ tea->ops->set_pins(tea, data | TEA575X_WREN);
+ udelay(2);
+ }
+
+ if (!tea->mute)
+ tea->ops->set_pins(tea, 0);
+}
+
+static u32 snd_tea575x_read(struct snd_tea575x *tea)
+{
+ u16 l, rdata;
+ u32 data = 0;
+
+ if (tea->ops->read_val)
+ return tea->ops->read_val(tea);
+
+ tea->ops->set_direction(tea, 0);
+ tea->ops->set_pins(tea, 0);
+ udelay(16);
+
+ for (l = 24; l--;) {
+ tea->ops->set_pins(tea, TEA575X_CLK);
+ udelay(2);
+ if (!l)
+ tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
+ tea->ops->set_pins(tea, 0);
+ udelay(2);
+ data <<= 1; /* shift data */
+ rdata = tea->ops->get_pins(tea);
+ if (!l)
+ tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
+ if (rdata & TEA575X_DATA)
+ data++;
+ udelay(2);
+ }
+
+ if (tea->mute)
+ tea->ops->set_pins(tea, TEA575X_WREN);
+
+ return data;
+}
+
+static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val)
+{
+ u32 freq = val & TEA575X_BIT_FREQ_MASK;
+
+ if (freq == 0)
+ return freq;
+
+ switch (tea->band) {
+ case BAND_FM:
+ /* freq *= 12.5 */
+ freq *= 125;
+ freq /= 10;
+ /* crystal fixup */
+ freq -= TEA575X_FMIF;
+ break;
+ case BAND_FM_JAPAN:
+ /* freq *= 12.5 */
+ freq *= 125;
+ freq /= 10;
+ /* crystal fixup */
+ freq += TEA575X_FMIF;
+ break;
+ case BAND_AM:
+ /* crystal fixup */
+ freq -= TEA575X_AMIF;
+ break;
+ }
+
+ return clamp(freq * 16, bands[tea->band].rangelow,
+ bands[tea->band].rangehigh); /* from kHz */
+}
+
+static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
+{
+ return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea));
+}
+
+void snd_tea575x_set_freq(struct snd_tea575x *tea)
+{
+ u32 freq = tea->freq / 16; /* to kHz */
+ u32 band = 0;
+
+ switch (tea->band) {
+ case BAND_FM:
+ band = TEA575X_BIT_BAND_FM;
+ /* crystal fixup */
+ freq += TEA575X_FMIF;
+ /* freq /= 12.5 */
+ freq *= 10;
+ freq /= 125;
+ break;
+ case BAND_FM_JAPAN:
+ band = TEA575X_BIT_BAND_FM;
+ /* crystal fixup */
+ freq -= TEA575X_FMIF;
+ /* freq /= 12.5 */
+ freq *= 10;
+ freq /= 125;
+ break;
+ case BAND_AM:
+ band = TEA575X_BIT_BAND_MW;
+ /* crystal fixup */
+ freq += TEA575X_AMIF;
+ break;
+ }
+
+ tea->val &= ~(TEA575X_BIT_FREQ_MASK | TEA575X_BIT_BAND_MASK);
+ tea->val |= band;
+ tea->val |= freq & TEA575X_BIT_FREQ_MASK;
+ snd_tea575x_write(tea, tea->val);
+ tea->freq = snd_tea575x_val_to_freq(tea, tea->val);
+}
+
+/*
+ * Linux Video interface
+ */
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+ strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
+ strlcpy(v->card, tea->card, sizeof(v->card));
+ strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
+ strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
+ v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ if (!tea->cannot_read_data)
+ v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
+ v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int vidioc_enum_freq_bands(struct file *file, void *priv,
+ struct v4l2_frequency_band *band)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+ int index;
+
+ if (band->tuner != 0)
+ return -EINVAL;
+
+ switch (band->index) {
+ case 0:
+ if (tea->tea5759)
+ index = BAND_FM_JAPAN;
+ else
+ index = BAND_FM;
+ break;
+ case 1:
+ if (tea->has_am) {
+ index = BAND_AM;
+ break;
+ }
+ /* Fall through */
+ default:
+ return -EINVAL;
+ }
+
+ *band = bands[index];
+ if (!tea->cannot_read_data)
+ band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
+
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+ struct v4l2_frequency_band band_fm = { 0, };
+
+ if (v->index > 0)
+ return -EINVAL;
+
+ snd_tea575x_read(tea);
+ vidioc_enum_freq_bands(file, priv, &band_fm);
+
+ memset(v, 0, sizeof(*v));
+ strlcpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
+ v->type = V4L2_TUNER_RADIO;
+ v->capability = band_fm.capability;
+ v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow;
+ v->rangehigh = band_fm.rangehigh;
+ v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+ v->audmode = (tea->val & TEA575X_BIT_MONO) ?
+ V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
+ v->signal = tea->tuned ? 0xffff : 0;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *v)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+ u32 orig_val = tea->val;
+
+ if (v->index)
+ return -EINVAL;
+ tea->val &= ~TEA575X_BIT_MONO;
+ if (v->audmode == V4L2_TUNER_MODE_MONO)
+ tea->val |= TEA575X_BIT_MONO;
+ /* Only apply changes if currently tuning FM */
+ if (tea->band != BAND_AM && tea->val != orig_val)
+ snd_tea575x_set_freq(tea);
+
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+ if (f->tuner != 0)
+ return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = tea->freq;
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ const struct v4l2_frequency *f)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
+ if (tea->has_am && f->frequency < (20000 * 16))
+ tea->band = BAND_AM;
+ else if (tea->tea5759)
+ tea->band = BAND_FM_JAPAN;
+ else
+ tea->band = BAND_FM;
+
+ tea->freq = clamp_t(u32, f->frequency, bands[tea->band].rangelow,
+ bands[tea->band].rangehigh);
+ snd_tea575x_set_freq(tea);
+ return 0;
+}
+
+static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
+ const struct v4l2_hw_freq_seek *a)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+ unsigned long timeout;
+ int i, spacing;
+
+ if (tea->cannot_read_data)
+ return -ENOTTY;
+ if (a->tuner || a->wrap_around)
+ return -EINVAL;
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
+ if (a->rangelow || a->rangehigh) {
+ for (i = 0; i < ARRAY_SIZE(bands); i++) {
+ if ((i == BAND_FM && tea->tea5759) ||
+ (i == BAND_FM_JAPAN && !tea->tea5759) ||
+ (i == BAND_AM && !tea->has_am))
+ continue;
+ if (bands[i].rangelow == a->rangelow &&
+ bands[i].rangehigh == a->rangehigh)
+ break;
+ }
+ if (i == ARRAY_SIZE(bands))
+ return -EINVAL; /* No matching band found */
+ if (i != tea->band) {
+ tea->band = i;
+ tea->freq = clamp(tea->freq, bands[i].rangelow,
+ bands[i].rangehigh);
+ snd_tea575x_set_freq(tea);
+ }
+ }
+
+ spacing = (tea->band == BAND_AM) ? 5 : 50; /* kHz */
+
+ /* clear the frequency, HW will fill it in */
+ tea->val &= ~TEA575X_BIT_FREQ_MASK;
+ tea->val |= TEA575X_BIT_SEARCH;
+ if (a->seek_upward)
+ tea->val |= TEA575X_BIT_UPDOWN;
+ else
+ tea->val &= ~TEA575X_BIT_UPDOWN;
+ snd_tea575x_write(tea, tea->val);
+ timeout = jiffies + msecs_to_jiffies(10000);
+ for (;;) {
+ if (time_after(jiffies, timeout))
+ break;
+ if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
+ /* some signal arrived, stop search */
+ tea->val &= ~TEA575X_BIT_SEARCH;
+ snd_tea575x_set_freq(tea);
+ return -ERESTARTSYS;
+ }
+ if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
+ u32 freq;
+
+ /* Found a frequency, wait until it can be read */
+ for (i = 0; i < 100; i++) {
+ msleep(10);
+ freq = snd_tea575x_get_freq(tea);
+ if (freq) /* available */
+ break;
+ }
+ if (freq == 0) /* shouldn't happen */
+ break;
+ /*
+ * if we moved by less than the spacing, or in the
+ * wrong direction, continue seeking
+ */
+ if (abs(tea->freq - freq) < 16 * spacing ||
+ (a->seek_upward && freq < tea->freq) ||
+ (!a->seek_upward && freq > tea->freq)) {
+ snd_tea575x_write(tea, tea->val);
+ continue;
+ }
+ tea->freq = freq;
+ tea->val &= ~TEA575X_BIT_SEARCH;
+ return 0;
+ }
+ }
+ tea->val &= ~TEA575X_BIT_SEARCH;
+ snd_tea575x_set_freq(tea);
+ return -ENODATA;
+}
+
+static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ tea->mute = ctrl->val;
+ snd_tea575x_set_freq(tea);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static const struct v4l2_file_operations tea575x_fops = {
+ .unlocked_ioctl = video_ioctl2,
+ .open = v4l2_fh_open,
+ .release = v4l2_fh_release,
+ .poll = v4l2_ctrl_poll,
+};
+
+static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
+ .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static const struct video_device tea575x_radio = {
+ .ioctl_ops = &tea575x_ioctl_ops,
+ .release = video_device_release_empty,
+};
+
+static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
+ .s_ctrl = tea575x_s_ctrl,
+};
+
+
+int snd_tea575x_hw_init(struct snd_tea575x *tea)
+{
+ tea->mute = true;
+
+ /* Not all devices can or know how to read the data back.
+ Such devices can set cannot_read_data to true. */
+ if (!tea->cannot_read_data) {
+ snd_tea575x_write(tea, 0x55AA);
+ if (snd_tea575x_read(tea) != 0x55AA)
+ return -ENODEV;
+ }
+
+ tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28;
+ tea->freq = 90500 * 16; /* 90.5Mhz default */
+ snd_tea575x_set_freq(tea);
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_tea575x_hw_init);
+
+int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
+{
+ int retval = snd_tea575x_hw_init(tea);
+
+ if (retval)
+ return retval;
+
+ tea->vd = tea575x_radio;
+ video_set_drvdata(&tea->vd, tea);
+ mutex_init(&tea->mutex);
+ strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
+ tea->vd.lock = &tea->mutex;
+ tea->vd.v4l2_dev = tea->v4l2_dev;
+ tea->fops = tea575x_fops;
+ tea->fops.owner = owner;
+ tea->vd.fops = &tea->fops;
+ set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
+ /* disable hw_freq_seek if we can't use it */
+ if (tea->cannot_read_data)
+ v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
+
+ if (!tea->cannot_mute) {
+ tea->vd.ctrl_handler = &tea->ctrl_handler;
+ v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
+ v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+ retval = tea->ctrl_handler.error;
+ if (retval) {
+ v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
+ v4l2_ctrl_handler_free(&tea->ctrl_handler);
+ return retval;
+ }
+
+ if (tea->ext_init) {
+ retval = tea->ext_init(tea);
+ if (retval) {
+ v4l2_ctrl_handler_free(&tea->ctrl_handler);
+ return retval;
+ }
+ }
+
+ v4l2_ctrl_handler_setup(&tea->ctrl_handler);
+ }
+
+ retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
+ if (retval) {
+ v4l2_err(tea->v4l2_dev, "can't register video device!\n");
+ v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
+ return retval;
+ }
+
+ return 0;
+}
+
+void snd_tea575x_exit(struct snd_tea575x *tea)
+{
+ video_unregister_device(&tea->vd);
+ v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
+}
+
+static int __init alsa_tea575x_module_init(void)
+{
+ return 0;
+}
+
+static void __exit alsa_tea575x_module_exit(void)
+{
+}
+
+module_init(alsa_tea575x_module_init)
+module_exit(alsa_tea575x_module_exit)
+
+EXPORT_SYMBOL(snd_tea575x_init);
+EXPORT_SYMBOL(snd_tea575x_exit);
+EXPORT_SYMBOL(snd_tea575x_set_freq);
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index c95d8f1..5526b03 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -8,10 +8,8 @@ snd-ak4117-objs := ak4117.o
snd-ak4113-objs := ak4113.o
snd-ak4xxx-adda-objs := ak4xxx-adda.o
snd-pt2258-objs := pt2258.o
-snd-tea575x-tuner-objs := tea575x-tuner.o
# Module Dependency
obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
-obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
deleted file mode 100644
index cef0698..0000000
--- a/sound/i2c/other/tea575x-tuner.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
- *
- * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-#include <media/tea575x.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
-MODULE_LICENSE("GPL");
-
-/*
- * definitions
- */
-
-#define TEA575X_BIT_SEARCH (1<<24) /* 1 = search action, 0 = tuned */
-#define TEA575X_BIT_UPDOWN (1<<23) /* 0 = search down, 1 = search up */
-#define TEA575X_BIT_MONO (1<<22) /* 0 = stereo, 1 = mono */
-#define TEA575X_BIT_BAND_MASK (3<<20)
-#define TEA575X_BIT_BAND_FM (0<<20)
-#define TEA575X_BIT_BAND_MW (1<<20)
-#define TEA575X_BIT_BAND_LW (2<<20)
-#define TEA575X_BIT_BAND_SW (3<<20)
-#define TEA575X_BIT_PORT_0 (1<<19) /* user bit */
-#define TEA575X_BIT_PORT_1 (1<<18) /* user bit */
-#define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */
-#define TEA575X_BIT_SEARCH_5_28 (0<<16) /* FM >5uV, AM >28uV */
-#define TEA575X_BIT_SEARCH_10_40 (1<<16) /* FM >10uV, AM > 40uV */
-#define TEA575X_BIT_SEARCH_30_63 (2<<16) /* FM >30uV, AM > 63uV */
-#define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */
-#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
-#define TEA575X_BIT_FREQ_MASK 0x7fff
-
-enum { BAND_FM, BAND_FM_JAPAN, BAND_AM };
-
-static const struct v4l2_frequency_band bands[] = {
- {
- .type = V4L2_TUNER_RADIO,
- .index = 0,
- .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 87500 * 16,
- .rangehigh = 108000 * 16,
- .modulation = V4L2_BAND_MODULATION_FM,
- },
- {
- .type = V4L2_TUNER_RADIO,
- .index = 0,
- .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 76000 * 16,
- .rangehigh = 91000 * 16,
- .modulation = V4L2_BAND_MODULATION_FM,
- },
- {
- .type = V4L2_TUNER_RADIO,
- .index = 1,
- .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 530 * 16,
- .rangehigh = 1710 * 16,
- .modulation = V4L2_BAND_MODULATION_AM,
- },
-};
-
-/*
- * lowlevel part
- */
-
-static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
-{
- u16 l;
- u8 data;
-
- if (tea->ops->write_val)
- return tea->ops->write_val(tea, val);
-
- tea->ops->set_direction(tea, 1);
- udelay(16);
-
- for (l = 25; l > 0; l--) {
- data = (val >> 24) & TEA575X_DATA;
- val <<= 1; /* shift data */
- tea->ops->set_pins(tea, data | TEA575X_WREN);
- udelay(2);
- tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
- udelay(2);
- tea->ops->set_pins(tea, data | TEA575X_WREN);
- udelay(2);
- }
-
- if (!tea->mute)
- tea->ops->set_pins(tea, 0);
-}
-
-static u32 snd_tea575x_read(struct snd_tea575x *tea)
-{
- u16 l, rdata;
- u32 data = 0;
-
- if (tea->ops->read_val)
- return tea->ops->read_val(tea);
-
- tea->ops->set_direction(tea, 0);
- tea->ops->set_pins(tea, 0);
- udelay(16);
-
- for (l = 24; l--;) {
- tea->ops->set_pins(tea, TEA575X_CLK);
- udelay(2);
- if (!l)
- tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
- tea->ops->set_pins(tea, 0);
- udelay(2);
- data <<= 1; /* shift data */
- rdata = tea->ops->get_pins(tea);
- if (!l)
- tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
- if (rdata & TEA575X_DATA)
- data++;
- udelay(2);
- }
-
- if (tea->mute)
- tea->ops->set_pins(tea, TEA575X_WREN);
-
- return data;
-}
-
-static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val)
-{
- u32 freq = val & TEA575X_BIT_FREQ_MASK;
-
- if (freq == 0)
- return freq;
-
- switch (tea->band) {
- case BAND_FM:
- /* freq *= 12.5 */
- freq *= 125;
- freq /= 10;
- /* crystal fixup */
- freq -= TEA575X_FMIF;
- break;
- case BAND_FM_JAPAN:
- /* freq *= 12.5 */
- freq *= 125;
- freq /= 10;
- /* crystal fixup */
- freq += TEA575X_FMIF;
- break;
- case BAND_AM:
- /* crystal fixup */
- freq -= TEA575X_AMIF;
- break;
- }
-
- return clamp(freq * 16, bands[tea->band].rangelow,
- bands[tea->band].rangehigh); /* from kHz */
-}
-
-static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
-{
- return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea));
-}
-
-void snd_tea575x_set_freq(struct snd_tea575x *tea)
-{
- u32 freq = tea->freq / 16; /* to kHz */
- u32 band = 0;
-
- switch (tea->band) {
- case BAND_FM:
- band = TEA575X_BIT_BAND_FM;
- /* crystal fixup */
- freq += TEA575X_FMIF;
- /* freq /= 12.5 */
- freq *= 10;
- freq /= 125;
- break;
- case BAND_FM_JAPAN:
- band = TEA575X_BIT_BAND_FM;
- /* crystal fixup */
- freq -= TEA575X_FMIF;
- /* freq /= 12.5 */
- freq *= 10;
- freq /= 125;
- break;
- case BAND_AM:
- band = TEA575X_BIT_BAND_MW;
- /* crystal fixup */
- freq += TEA575X_AMIF;
- break;
- }
-
- tea->val &= ~(TEA575X_BIT_FREQ_MASK | TEA575X_BIT_BAND_MASK);
- tea->val |= band;
- tea->val |= freq & TEA575X_BIT_FREQ_MASK;
- snd_tea575x_write(tea, tea->val);
- tea->freq = snd_tea575x_val_to_freq(tea, tea->val);
-}
-
-/*
- * Linux Video interface
- */
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *v)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
- strlcpy(v->card, tea->card, sizeof(v->card));
- strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
- strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
- v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
- if (!tea->cannot_read_data)
- v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
- v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int vidioc_enum_freq_bands(struct file *file, void *priv,
- struct v4l2_frequency_band *band)
-{
- struct snd_tea575x *tea = video_drvdata(file);
- int index;
-
- if (band->tuner != 0)
- return -EINVAL;
-
- switch (band->index) {
- case 0:
- if (tea->tea5759)
- index = BAND_FM_JAPAN;
- else
- index = BAND_FM;
- break;
- case 1:
- if (tea->has_am) {
- index = BAND_AM;
- break;
- }
- /* Fall through */
- default:
- return -EINVAL;
- }
-
- *band = bands[index];
- if (!tea->cannot_read_data)
- band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- struct snd_tea575x *tea = video_drvdata(file);
- struct v4l2_frequency_band band_fm = { 0, };
-
- if (v->index > 0)
- return -EINVAL;
-
- snd_tea575x_read(tea);
- vidioc_enum_freq_bands(file, priv, &band_fm);
-
- memset(v, 0, sizeof(*v));
- strlcpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
- v->type = V4L2_TUNER_RADIO;
- v->capability = band_fm.capability;
- v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow;
- v->rangehigh = band_fm.rangehigh;
- v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
- v->audmode = (tea->val & TEA575X_BIT_MONO) ?
- V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
- v->signal = tea->tuned ? 0xffff : 0;
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *v)
-{
- struct snd_tea575x *tea = video_drvdata(file);
- u32 orig_val = tea->val;
-
- if (v->index)
- return -EINVAL;
- tea->val &= ~TEA575X_BIT_MONO;
- if (v->audmode == V4L2_TUNER_MODE_MONO)
- tea->val |= TEA575X_BIT_MONO;
- /* Only apply changes if currently tuning FM */
- if (tea->band != BAND_AM && tea->val != orig_val)
- snd_tea575x_set_freq(tea);
-
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- if (f->tuner != 0)
- return -EINVAL;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = tea->freq;
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *f)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
-
- if (tea->has_am && f->frequency < (20000 * 16))
- tea->band = BAND_AM;
- else if (tea->tea5759)
- tea->band = BAND_FM_JAPAN;
- else
- tea->band = BAND_FM;
-
- tea->freq = clamp_t(u32, f->frequency, bands[tea->band].rangelow,
- bands[tea->band].rangehigh);
- snd_tea575x_set_freq(tea);
- return 0;
-}
-
-static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
- const struct v4l2_hw_freq_seek *a)
-{
- struct snd_tea575x *tea = video_drvdata(file);
- unsigned long timeout;
- int i, spacing;
-
- if (tea->cannot_read_data)
- return -ENOTTY;
- if (a->tuner || a->wrap_around)
- return -EINVAL;
-
- if (file->f_flags & O_NONBLOCK)
- return -EWOULDBLOCK;
-
- if (a->rangelow || a->rangehigh) {
- for (i = 0; i < ARRAY_SIZE(bands); i++) {
- if ((i == BAND_FM && tea->tea5759) ||
- (i == BAND_FM_JAPAN && !tea->tea5759) ||
- (i == BAND_AM && !tea->has_am))
- continue;
- if (bands[i].rangelow == a->rangelow &&
- bands[i].rangehigh == a->rangehigh)
- break;
- }
- if (i == ARRAY_SIZE(bands))
- return -EINVAL; /* No matching band found */
- if (i != tea->band) {
- tea->band = i;
- tea->freq = clamp(tea->freq, bands[i].rangelow,
- bands[i].rangehigh);
- snd_tea575x_set_freq(tea);
- }
- }
-
- spacing = (tea->band == BAND_AM) ? 5 : 50; /* kHz */
-
- /* clear the frequency, HW will fill it in */
- tea->val &= ~TEA575X_BIT_FREQ_MASK;
- tea->val |= TEA575X_BIT_SEARCH;
- if (a->seek_upward)
- tea->val |= TEA575X_BIT_UPDOWN;
- else
- tea->val &= ~TEA575X_BIT_UPDOWN;
- snd_tea575x_write(tea, tea->val);
- timeout = jiffies + msecs_to_jiffies(10000);
- for (;;) {
- if (time_after(jiffies, timeout))
- break;
- if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
- /* some signal arrived, stop search */
- tea->val &= ~TEA575X_BIT_SEARCH;
- snd_tea575x_set_freq(tea);
- return -ERESTARTSYS;
- }
- if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
- u32 freq;
-
- /* Found a frequency, wait until it can be read */
- for (i = 0; i < 100; i++) {
- msleep(10);
- freq = snd_tea575x_get_freq(tea);
- if (freq) /* available */
- break;
- }
- if (freq == 0) /* shouldn't happen */
- break;
- /*
- * if we moved by less than the spacing, or in the
- * wrong direction, continue seeking
- */
- if (abs(tea->freq - freq) < 16 * spacing ||
- (a->seek_upward && freq < tea->freq) ||
- (!a->seek_upward && freq > tea->freq)) {
- snd_tea575x_write(tea, tea->val);
- continue;
- }
- tea->freq = freq;
- tea->val &= ~TEA575X_BIT_SEARCH;
- return 0;
- }
- }
- tea->val &= ~TEA575X_BIT_SEARCH;
- snd_tea575x_set_freq(tea);
- return -ENODATA;
-}
-
-static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- tea->mute = ctrl->val;
- snd_tea575x_set_freq(tea);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static const struct v4l2_file_operations tea575x_fops = {
- .unlocked_ioctl = video_ioctl2,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .poll = v4l2_ctrl_poll,
-};
-
-static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
- .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct video_device tea575x_radio = {
- .ioctl_ops = &tea575x_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
- .s_ctrl = tea575x_s_ctrl,
-};
-
-
-int snd_tea575x_hw_init(struct snd_tea575x *tea)
-{
- tea->mute = true;
-
- /* Not all devices can or know how to read the data back.
- Such devices can set cannot_read_data to true. */
- if (!tea->cannot_read_data) {
- snd_tea575x_write(tea, 0x55AA);
- if (snd_tea575x_read(tea) != 0x55AA)
- return -ENODEV;
- }
-
- tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28;
- tea->freq = 90500 * 16; /* 90.5Mhz default */
- snd_tea575x_set_freq(tea);
-
- return 0;
-}
-EXPORT_SYMBOL(snd_tea575x_hw_init);
-
-int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
-{
- int retval = snd_tea575x_hw_init(tea);
-
- if (retval)
- return retval;
-
- tea->vd = tea575x_radio;
- video_set_drvdata(&tea->vd, tea);
- mutex_init(&tea->mutex);
- strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
- tea->vd.lock = &tea->mutex;
- tea->vd.v4l2_dev = tea->v4l2_dev;
- tea->fops = tea575x_fops;
- tea->fops.owner = owner;
- tea->vd.fops = &tea->fops;
- set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
- /* disable hw_freq_seek if we can't use it */
- if (tea->cannot_read_data)
- v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
-
- if (!tea->cannot_mute) {
- tea->vd.ctrl_handler = &tea->ctrl_handler;
- v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
- v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
- retval = tea->ctrl_handler.error;
- if (retval) {
- v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
- v4l2_ctrl_handler_free(&tea->ctrl_handler);
- return retval;
- }
-
- if (tea->ext_init) {
- retval = tea->ext_init(tea);
- if (retval) {
- v4l2_ctrl_handler_free(&tea->ctrl_handler);
- return retval;
- }
- }
-
- v4l2_ctrl_handler_setup(&tea->ctrl_handler);
- }
-
- retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
- if (retval) {
- v4l2_err(tea->v4l2_dev, "can't register video device!\n");
- v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
- return retval;
- }
-
- return 0;
-}
-
-void snd_tea575x_exit(struct snd_tea575x *tea)
-{
- video_unregister_device(&tea->vd);
- v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
-}
-
-static int __init alsa_tea575x_module_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_tea575x_module_exit(void)
-{
-}
-
-module_init(alsa_tea575x_module_init)
-module_exit(alsa_tea575x_module_exit)
-
-EXPORT_SYMBOL(snd_tea575x_init);
-EXPORT_SYMBOL(snd_tea575x_exit);
-EXPORT_SYMBOL(snd_tea575x_set_freq);
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index fe6fa93..9df80ef 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,10 +1,5 @@
# ALSA PCI drivers
-config SND_TEA575X
- tristate
- depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
- default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
-
menuconfig SND_PCI
bool "PCI sound devices"
depends on PCI
@@ -542,7 +537,9 @@ config SND_ES1968_INPUT
config SND_ES1968_RADIO
bool "Enable TEA5757 radio tuner support for es1968"
depends on SND_ES1968
+ depends on MEDIA_RADIO_SUPPORT
depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
+ select RADIO_TEA575X
help
Say Y here to include support for TEA5757 radio tuner integrated on
some MediaForte cards (e.g. SF64-PCE2).
@@ -562,7 +559,9 @@ config SND_FM801
config SND_FM801_TEA575X_BOOL
bool "ForteMedia FM801 + TEA5757 tuner"
depends on SND_FM801
+ depends on MEDIA_RADIO_SUPPORT
depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
+ select RADIO_TEA575X
help
Say Y here to include support for soundcards based on the ForteMedia
FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
--
Ondrej Zary
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] tea575x: Move header from sound to media
2013-07-28 20:01 ` [PATCH 1/2] tea575x: Move header " Ondrej Zary
2013-07-28 20:01 ` [PATCH 2/2] tea575x: Move " Ondrej Zary
@ 2013-07-29 7:56 ` Hans Verkuil
1 sibling, 0 replies; 6+ messages in thread
From: Hans Verkuil @ 2013-07-29 7:56 UTC (permalink / raw)
To: Ondrej Zary; +Cc: linux-media, alsa-devel
Hi Ondrej!
On 07/28/2013 10:01 PM, Ondrej Zary wrote:
> Move include/sound/tea575x-tuner.h to include/media/tea575x.h and update files that include it.
>
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
If this can be acked by an alsa maintainer, then I can merge it into the media tree.
Regards,
Hans
> ---
> drivers/media/radio/radio-maxiradio.c | 2 +-
> drivers/media/radio/radio-sf16fmr2.c | 2 +-
> drivers/media/radio/radio-shark.c | 2 +-
> include/media/tea575x.h | 79 +++++++++++++++++++++++++++++++++
> include/sound/tea575x-tuner.h | 79 ---------------------------------
> sound/i2c/other/tea575x-tuner.c | 2 +-
> sound/pci/es1968.c | 2 +-
> sound/pci/fm801.c | 2 +-
> 8 files changed, 85 insertions(+), 85 deletions(-)
> create mode 100644 include/media/tea575x.h
> delete mode 100644 include/sound/tea575x-tuner.h
>
> diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
> index 1d1c9e1..5236035 100644
> --- a/drivers/media/radio/radio-maxiradio.c
> +++ b/drivers/media/radio/radio-maxiradio.c
> @@ -42,7 +42,7 @@
> #include <linux/videodev2.h>
> #include <linux/io.h>
> #include <linux/slab.h>
> -#include <sound/tea575x-tuner.h>
> +#include <media/tea575x.h>
> #include <media/v4l2-device.h>
> #include <media/v4l2-ioctl.h>
> #include <media/v4l2-fh.h>
> diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
> index 9c09904..f1e3714 100644
> --- a/drivers/media/radio/radio-sf16fmr2.c
> +++ b/drivers/media/radio/radio-sf16fmr2.c
> @@ -14,7 +14,7 @@
> #include <linux/io.h> /* outb, outb_p */
> #include <linux/isa.h>
> #include <linux/pnp.h>
> -#include <sound/tea575x-tuner.h>
> +#include <media/tea575x.h>
>
> MODULE_AUTHOR("Ondrej Zary");
> MODULE_DESCRIPTION("MediaForte SF16-FMR2 and SF16-FMD2 FM radio card driver");
> diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c
> index 8fa18ab..b914772 100644
> --- a/drivers/media/radio/radio-shark.c
> +++ b/drivers/media/radio/radio-shark.c
> @@ -33,7 +33,7 @@
> #include <linux/usb.h>
> #include <linux/workqueue.h>
> #include <media/v4l2-device.h>
> -#include <sound/tea575x-tuner.h>
> +#include <media/tea575x.h>
>
> #if defined(CONFIG_LEDS_CLASS) || \
> (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE))
> diff --git a/include/media/tea575x.h b/include/media/tea575x.h
> new file mode 100644
> index 0000000..2d4fa59
> --- /dev/null
> +++ b/include/media/tea575x.h
> @@ -0,0 +1,79 @@
> +#ifndef __SOUND_TEA575X_TUNER_H
> +#define __SOUND_TEA575X_TUNER_H
> +
> +/*
> + * ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
> + *
> + * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#include <linux/videodev2.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-dev.h>
> +#include <media/v4l2-device.h>
> +
> +#define TEA575X_FMIF 10700
> +#define TEA575X_AMIF 450
> +
> +#define TEA575X_DATA (1 << 0)
> +#define TEA575X_CLK (1 << 1)
> +#define TEA575X_WREN (1 << 2)
> +#define TEA575X_MOST (1 << 3)
> +
> +struct snd_tea575x;
> +
> +struct snd_tea575x_ops {
> + /* Drivers using snd_tea575x must either define read_ and write_val */
> + void (*write_val)(struct snd_tea575x *tea, u32 val);
> + u32 (*read_val)(struct snd_tea575x *tea);
> + /* Or define the 3 pin functions */
> + void (*set_pins)(struct snd_tea575x *tea, u8 pins);
> + u8 (*get_pins)(struct snd_tea575x *tea);
> + void (*set_direction)(struct snd_tea575x *tea, bool output);
> +};
> +
> +struct snd_tea575x {
> + struct v4l2_device *v4l2_dev;
> + struct v4l2_file_operations fops;
> + struct video_device vd; /* video device */
> + int radio_nr; /* radio_nr */
> + bool tea5759; /* 5759 chip is present */
> + bool has_am; /* Device can tune to AM freqs */
> + bool cannot_read_data; /* Device cannot read the data pin */
> + bool cannot_mute; /* Device cannot mute */
> + bool mute; /* Device is muted? */
> + bool stereo; /* receiving stereo */
> + bool tuned; /* tuned to a station */
> + unsigned int val; /* hw value */
> + u32 band; /* 0: FM, 1: FM-Japan, 2: AM */
> + u32 freq; /* frequency */
> + struct mutex mutex;
> + struct snd_tea575x_ops *ops;
> + void *private_data;
> + u8 card[32];
> + u8 bus_info[32];
> + struct v4l2_ctrl_handler ctrl_handler;
> + int (*ext_init)(struct snd_tea575x *tea);
> +};
> +
> +int snd_tea575x_hw_init(struct snd_tea575x *tea);
> +int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner);
> +void snd_tea575x_exit(struct snd_tea575x *tea);
> +void snd_tea575x_set_freq(struct snd_tea575x *tea);
> +
> +#endif /* __SOUND_TEA575X_TUNER_H */
> diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
> deleted file mode 100644
> index 2d4fa59..0000000
> --- a/include/sound/tea575x-tuner.h
> +++ /dev/null
> @@ -1,79 +0,0 @@
> -#ifndef __SOUND_TEA575X_TUNER_H
> -#define __SOUND_TEA575X_TUNER_H
> -
> -/*
> - * ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
> - *
> - * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> - *
> - */
> -
> -#include <linux/videodev2.h>
> -#include <media/v4l2-ctrls.h>
> -#include <media/v4l2-dev.h>
> -#include <media/v4l2-device.h>
> -
> -#define TEA575X_FMIF 10700
> -#define TEA575X_AMIF 450
> -
> -#define TEA575X_DATA (1 << 0)
> -#define TEA575X_CLK (1 << 1)
> -#define TEA575X_WREN (1 << 2)
> -#define TEA575X_MOST (1 << 3)
> -
> -struct snd_tea575x;
> -
> -struct snd_tea575x_ops {
> - /* Drivers using snd_tea575x must either define read_ and write_val */
> - void (*write_val)(struct snd_tea575x *tea, u32 val);
> - u32 (*read_val)(struct snd_tea575x *tea);
> - /* Or define the 3 pin functions */
> - void (*set_pins)(struct snd_tea575x *tea, u8 pins);
> - u8 (*get_pins)(struct snd_tea575x *tea);
> - void (*set_direction)(struct snd_tea575x *tea, bool output);
> -};
> -
> -struct snd_tea575x {
> - struct v4l2_device *v4l2_dev;
> - struct v4l2_file_operations fops;
> - struct video_device vd; /* video device */
> - int radio_nr; /* radio_nr */
> - bool tea5759; /* 5759 chip is present */
> - bool has_am; /* Device can tune to AM freqs */
> - bool cannot_read_data; /* Device cannot read the data pin */
> - bool cannot_mute; /* Device cannot mute */
> - bool mute; /* Device is muted? */
> - bool stereo; /* receiving stereo */
> - bool tuned; /* tuned to a station */
> - unsigned int val; /* hw value */
> - u32 band; /* 0: FM, 1: FM-Japan, 2: AM */
> - u32 freq; /* frequency */
> - struct mutex mutex;
> - struct snd_tea575x_ops *ops;
> - void *private_data;
> - u8 card[32];
> - u8 bus_info[32];
> - struct v4l2_ctrl_handler ctrl_handler;
> - int (*ext_init)(struct snd_tea575x *tea);
> -};
> -
> -int snd_tea575x_hw_init(struct snd_tea575x *tea);
> -int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner);
> -void snd_tea575x_exit(struct snd_tea575x *tea);
> -void snd_tea575x_set_freq(struct snd_tea575x *tea);
> -
> -#endif /* __SOUND_TEA575X_TUNER_H */
> diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
> index 46ec4dff..cef0698 100644
> --- a/sound/i2c/other/tea575x-tuner.c
> +++ b/sound/i2c/other/tea575x-tuner.c
> @@ -31,7 +31,7 @@
> #include <media/v4l2-fh.h>
> #include <media/v4l2-ioctl.h>
> #include <media/v4l2-event.h>
> -#include <sound/tea575x-tuner.h>
> +#include <media/tea575x.h>
>
> MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
> MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
> diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
> index 5e2ec96..b0e3d92 100644
> --- a/sound/pci/es1968.c
> +++ b/sound/pci/es1968.c
> @@ -113,7 +113,7 @@
> #include <sound/initval.h>
>
> #ifdef CONFIG_SND_ES1968_RADIO
> -#include <sound/tea575x-tuner.h>
> +#include <media/tea575x.h>
> #endif
>
> #define CARD_NAME "ESS Maestro1/2"
> diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
> index 706c5b6..45bc8a9 100644
> --- a/sound/pci/fm801.c
> +++ b/sound/pci/fm801.c
> @@ -37,7 +37,7 @@
> #include <asm/io.h>
>
> #ifdef CONFIG_SND_FM801_TEA575X_BOOL
> -#include <sound/tea575x-tuner.h>
> +#include <media/tea575x.h>
> #endif
>
> MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] tea575x: Move from sound to media
2013-07-28 20:01 ` [PATCH 2/2] tea575x: Move " Ondrej Zary
@ 2013-07-29 7:58 ` Hans Verkuil
0 siblings, 0 replies; 6+ messages in thread
From: Hans Verkuil @ 2013-07-29 7:58 UTC (permalink / raw)
To: Ondrej Zary; +Cc: linux-media, alsa-devel
Hi Ondrej!
On 07/28/2013 10:01 PM, Ondrej Zary wrote:
> Move tea575x from sound/i2c/other to drivers/media/radio
> Includes Kconfig changes by Hans Verkuil.
>
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
If this can be acked by an alsa maintainer, then I can merge it into the media tree.
I really like these changes: the Kconfig part is simplified and it makes much more
sense to have this driver in drivers/media.
Regards,
Hans
> ---
> drivers/media/radio/Kconfig | 12 +-
> drivers/media/radio/Makefile | 1 +
> drivers/media/radio/tea575x.c | 584 +++++++++++++++++++++++++++++++++++++++
> sound/i2c/other/Makefile | 2 -
> sound/i2c/other/tea575x-tuner.c | 584 ---------------------------------------
> sound/pci/Kconfig | 9 +-
> 6 files changed, 598 insertions(+), 594 deletions(-)
> create mode 100644 drivers/media/radio/tea575x.c
> delete mode 100644 sound/i2c/other/tea575x-tuner.c
>
> diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
> index d529ba7..39882dd 100644
> --- a/drivers/media/radio/Kconfig
> +++ b/drivers/media/radio/Kconfig
> @@ -12,6 +12,9 @@ menuconfig RADIO_ADAPTERS
>
> if RADIO_ADAPTERS && VIDEO_V4L2
>
> +config RADIO_TEA575X
> + tristate
> +
> config RADIO_SI470X
> bool "Silicon Labs Si470x FM Radio Receiver support"
> depends on VIDEO_V4L2
> @@ -61,7 +64,8 @@ config USB_DSBR
>
> config RADIO_MAXIRADIO
> tristate "Guillemot MAXI Radio FM 2000 radio"
> - depends on VIDEO_V4L2 && PCI && SND
> + depends on VIDEO_V4L2 && PCI
> + select RADIO_TEA575X
> ---help---
> Choose Y here if you have this radio card. This card may also be
> found as Gemtek PCI FM.
> @@ -76,7 +80,8 @@ config RADIO_MAXIRADIO
>
> config RADIO_SHARK
> tristate "Griffin radioSHARK USB radio receiver"
> - depends on USB && SND
> + depends on USB
> + select RADIO_TEA575X
> ---help---
> Choose Y here if you have this radio receiver.
>
> @@ -393,7 +398,8 @@ config RADIO_SF16FMI
>
> config RADIO_SF16FMR2
> tristate "SF16-FMR2/SF16-FMD2 Radio"
> - depends on ISA && VIDEO_V4L2 && SND
> + depends on ISA && VIDEO_V4L2
> + select RADIO_TEA575X
> ---help---
> Choose Y here if you have one of these FM radio cards.
>
> diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
> index 0dcdb32..3b64560 100644
> --- a/drivers/media/radio/Makefile
> +++ b/drivers/media/radio/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
> obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
> obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
> obj-$(CONFIG_RADIO_WL128X) += wl128x/
> +obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
>
> shark2-objs := radio-shark2.o radio-tea5777.o
>
> diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c
> new file mode 100644
> index 0000000..cef0698
> --- /dev/null
> +++ b/drivers/media/radio/tea575x.c
> @@ -0,0 +1,584 @@
> +/*
> + * ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
> + *
> + * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#include <asm/io.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/sched.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-dev.h>
> +#include <media/v4l2-fh.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-event.h>
> +#include <media/tea575x.h>
> +
> +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
> +MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
> +MODULE_LICENSE("GPL");
> +
> +/*
> + * definitions
> + */
> +
> +#define TEA575X_BIT_SEARCH (1<<24) /* 1 = search action, 0 = tuned */
> +#define TEA575X_BIT_UPDOWN (1<<23) /* 0 = search down, 1 = search up */
> +#define TEA575X_BIT_MONO (1<<22) /* 0 = stereo, 1 = mono */
> +#define TEA575X_BIT_BAND_MASK (3<<20)
> +#define TEA575X_BIT_BAND_FM (0<<20)
> +#define TEA575X_BIT_BAND_MW (1<<20)
> +#define TEA575X_BIT_BAND_LW (2<<20)
> +#define TEA575X_BIT_BAND_SW (3<<20)
> +#define TEA575X_BIT_PORT_0 (1<<19) /* user bit */
> +#define TEA575X_BIT_PORT_1 (1<<18) /* user bit */
> +#define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */
> +#define TEA575X_BIT_SEARCH_5_28 (0<<16) /* FM >5uV, AM >28uV */
> +#define TEA575X_BIT_SEARCH_10_40 (1<<16) /* FM >10uV, AM > 40uV */
> +#define TEA575X_BIT_SEARCH_30_63 (2<<16) /* FM >30uV, AM > 63uV */
> +#define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */
> +#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
> +#define TEA575X_BIT_FREQ_MASK 0x7fff
> +
> +enum { BAND_FM, BAND_FM_JAPAN, BAND_AM };
> +
> +static const struct v4l2_frequency_band bands[] = {
> + {
> + .type = V4L2_TUNER_RADIO,
> + .index = 0,
> + .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
> + V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 87500 * 16,
> + .rangehigh = 108000 * 16,
> + .modulation = V4L2_BAND_MODULATION_FM,
> + },
> + {
> + .type = V4L2_TUNER_RADIO,
> + .index = 0,
> + .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
> + V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 76000 * 16,
> + .rangehigh = 91000 * 16,
> + .modulation = V4L2_BAND_MODULATION_FM,
> + },
> + {
> + .type = V4L2_TUNER_RADIO,
> + .index = 1,
> + .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 530 * 16,
> + .rangehigh = 1710 * 16,
> + .modulation = V4L2_BAND_MODULATION_AM,
> + },
> +};
> +
> +/*
> + * lowlevel part
> + */
> +
> +static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
> +{
> + u16 l;
> + u8 data;
> +
> + if (tea->ops->write_val)
> + return tea->ops->write_val(tea, val);
> +
> + tea->ops->set_direction(tea, 1);
> + udelay(16);
> +
> + for (l = 25; l > 0; l--) {
> + data = (val >> 24) & TEA575X_DATA;
> + val <<= 1; /* shift data */
> + tea->ops->set_pins(tea, data | TEA575X_WREN);
> + udelay(2);
> + tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
> + udelay(2);
> + tea->ops->set_pins(tea, data | TEA575X_WREN);
> + udelay(2);
> + }
> +
> + if (!tea->mute)
> + tea->ops->set_pins(tea, 0);
> +}
> +
> +static u32 snd_tea575x_read(struct snd_tea575x *tea)
> +{
> + u16 l, rdata;
> + u32 data = 0;
> +
> + if (tea->ops->read_val)
> + return tea->ops->read_val(tea);
> +
> + tea->ops->set_direction(tea, 0);
> + tea->ops->set_pins(tea, 0);
> + udelay(16);
> +
> + for (l = 24; l--;) {
> + tea->ops->set_pins(tea, TEA575X_CLK);
> + udelay(2);
> + if (!l)
> + tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
> + tea->ops->set_pins(tea, 0);
> + udelay(2);
> + data <<= 1; /* shift data */
> + rdata = tea->ops->get_pins(tea);
> + if (!l)
> + tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
> + if (rdata & TEA575X_DATA)
> + data++;
> + udelay(2);
> + }
> +
> + if (tea->mute)
> + tea->ops->set_pins(tea, TEA575X_WREN);
> +
> + return data;
> +}
> +
> +static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val)
> +{
> + u32 freq = val & TEA575X_BIT_FREQ_MASK;
> +
> + if (freq == 0)
> + return freq;
> +
> + switch (tea->band) {
> + case BAND_FM:
> + /* freq *= 12.5 */
> + freq *= 125;
> + freq /= 10;
> + /* crystal fixup */
> + freq -= TEA575X_FMIF;
> + break;
> + case BAND_FM_JAPAN:
> + /* freq *= 12.5 */
> + freq *= 125;
> + freq /= 10;
> + /* crystal fixup */
> + freq += TEA575X_FMIF;
> + break;
> + case BAND_AM:
> + /* crystal fixup */
> + freq -= TEA575X_AMIF;
> + break;
> + }
> +
> + return clamp(freq * 16, bands[tea->band].rangelow,
> + bands[tea->band].rangehigh); /* from kHz */
> +}
> +
> +static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
> +{
> + return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea));
> +}
> +
> +void snd_tea575x_set_freq(struct snd_tea575x *tea)
> +{
> + u32 freq = tea->freq / 16; /* to kHz */
> + u32 band = 0;
> +
> + switch (tea->band) {
> + case BAND_FM:
> + band = TEA575X_BIT_BAND_FM;
> + /* crystal fixup */
> + freq += TEA575X_FMIF;
> + /* freq /= 12.5 */
> + freq *= 10;
> + freq /= 125;
> + break;
> + case BAND_FM_JAPAN:
> + band = TEA575X_BIT_BAND_FM;
> + /* crystal fixup */
> + freq -= TEA575X_FMIF;
> + /* freq /= 12.5 */
> + freq *= 10;
> + freq /= 125;
> + break;
> + case BAND_AM:
> + band = TEA575X_BIT_BAND_MW;
> + /* crystal fixup */
> + freq += TEA575X_AMIF;
> + break;
> + }
> +
> + tea->val &= ~(TEA575X_BIT_FREQ_MASK | TEA575X_BIT_BAND_MASK);
> + tea->val |= band;
> + tea->val |= freq & TEA575X_BIT_FREQ_MASK;
> + snd_tea575x_write(tea, tea->val);
> + tea->freq = snd_tea575x_val_to_freq(tea, tea->val);
> +}
> +
> +/*
> + * Linux Video interface
> + */
> +
> +static int vidioc_querycap(struct file *file, void *priv,
> + struct v4l2_capability *v)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> +
> + strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
> + strlcpy(v->card, tea->card, sizeof(v->card));
> + strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
> + strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
> + v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> + if (!tea->cannot_read_data)
> + v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
> + v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
> + return 0;
> +}
> +
> +static int vidioc_enum_freq_bands(struct file *file, void *priv,
> + struct v4l2_frequency_band *band)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> + int index;
> +
> + if (band->tuner != 0)
> + return -EINVAL;
> +
> + switch (band->index) {
> + case 0:
> + if (tea->tea5759)
> + index = BAND_FM_JAPAN;
> + else
> + index = BAND_FM;
> + break;
> + case 1:
> + if (tea->has_am) {
> + index = BAND_AM;
> + break;
> + }
> + /* Fall through */
> + default:
> + return -EINVAL;
> + }
> +
> + *band = bands[index];
> + if (!tea->cannot_read_data)
> + band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
> +
> + return 0;
> +}
> +
> +static int vidioc_g_tuner(struct file *file, void *priv,
> + struct v4l2_tuner *v)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> + struct v4l2_frequency_band band_fm = { 0, };
> +
> + if (v->index > 0)
> + return -EINVAL;
> +
> + snd_tea575x_read(tea);
> + vidioc_enum_freq_bands(file, priv, &band_fm);
> +
> + memset(v, 0, sizeof(*v));
> + strlcpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
> + v->type = V4L2_TUNER_RADIO;
> + v->capability = band_fm.capability;
> + v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow;
> + v->rangehigh = band_fm.rangehigh;
> + v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
> + v->audmode = (tea->val & TEA575X_BIT_MONO) ?
> + V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
> + v->signal = tea->tuned ? 0xffff : 0;
> + return 0;
> +}
> +
> +static int vidioc_s_tuner(struct file *file, void *priv,
> + const struct v4l2_tuner *v)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> + u32 orig_val = tea->val;
> +
> + if (v->index)
> + return -EINVAL;
> + tea->val &= ~TEA575X_BIT_MONO;
> + if (v->audmode == V4L2_TUNER_MODE_MONO)
> + tea->val |= TEA575X_BIT_MONO;
> + /* Only apply changes if currently tuning FM */
> + if (tea->band != BAND_AM && tea->val != orig_val)
> + snd_tea575x_set_freq(tea);
> +
> + return 0;
> +}
> +
> +static int vidioc_g_frequency(struct file *file, void *priv,
> + struct v4l2_frequency *f)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> +
> + if (f->tuner != 0)
> + return -EINVAL;
> + f->type = V4L2_TUNER_RADIO;
> + f->frequency = tea->freq;
> + return 0;
> +}
> +
> +static int vidioc_s_frequency(struct file *file, void *priv,
> + const struct v4l2_frequency *f)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> +
> + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
> + return -EINVAL;
> +
> + if (tea->has_am && f->frequency < (20000 * 16))
> + tea->band = BAND_AM;
> + else if (tea->tea5759)
> + tea->band = BAND_FM_JAPAN;
> + else
> + tea->band = BAND_FM;
> +
> + tea->freq = clamp_t(u32, f->frequency, bands[tea->band].rangelow,
> + bands[tea->band].rangehigh);
> + snd_tea575x_set_freq(tea);
> + return 0;
> +}
> +
> +static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
> + const struct v4l2_hw_freq_seek *a)
> +{
> + struct snd_tea575x *tea = video_drvdata(file);
> + unsigned long timeout;
> + int i, spacing;
> +
> + if (tea->cannot_read_data)
> + return -ENOTTY;
> + if (a->tuner || a->wrap_around)
> + return -EINVAL;
> +
> + if (file->f_flags & O_NONBLOCK)
> + return -EWOULDBLOCK;
> +
> + if (a->rangelow || a->rangehigh) {
> + for (i = 0; i < ARRAY_SIZE(bands); i++) {
> + if ((i == BAND_FM && tea->tea5759) ||
> + (i == BAND_FM_JAPAN && !tea->tea5759) ||
> + (i == BAND_AM && !tea->has_am))
> + continue;
> + if (bands[i].rangelow == a->rangelow &&
> + bands[i].rangehigh == a->rangehigh)
> + break;
> + }
> + if (i == ARRAY_SIZE(bands))
> + return -EINVAL; /* No matching band found */
> + if (i != tea->band) {
> + tea->band = i;
> + tea->freq = clamp(tea->freq, bands[i].rangelow,
> + bands[i].rangehigh);
> + snd_tea575x_set_freq(tea);
> + }
> + }
> +
> + spacing = (tea->band == BAND_AM) ? 5 : 50; /* kHz */
> +
> + /* clear the frequency, HW will fill it in */
> + tea->val &= ~TEA575X_BIT_FREQ_MASK;
> + tea->val |= TEA575X_BIT_SEARCH;
> + if (a->seek_upward)
> + tea->val |= TEA575X_BIT_UPDOWN;
> + else
> + tea->val &= ~TEA575X_BIT_UPDOWN;
> + snd_tea575x_write(tea, tea->val);
> + timeout = jiffies + msecs_to_jiffies(10000);
> + for (;;) {
> + if (time_after(jiffies, timeout))
> + break;
> + if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
> + /* some signal arrived, stop search */
> + tea->val &= ~TEA575X_BIT_SEARCH;
> + snd_tea575x_set_freq(tea);
> + return -ERESTARTSYS;
> + }
> + if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
> + u32 freq;
> +
> + /* Found a frequency, wait until it can be read */
> + for (i = 0; i < 100; i++) {
> + msleep(10);
> + freq = snd_tea575x_get_freq(tea);
> + if (freq) /* available */
> + break;
> + }
> + if (freq == 0) /* shouldn't happen */
> + break;
> + /*
> + * if we moved by less than the spacing, or in the
> + * wrong direction, continue seeking
> + */
> + if (abs(tea->freq - freq) < 16 * spacing ||
> + (a->seek_upward && freq < tea->freq) ||
> + (!a->seek_upward && freq > tea->freq)) {
> + snd_tea575x_write(tea, tea->val);
> + continue;
> + }
> + tea->freq = freq;
> + tea->val &= ~TEA575X_BIT_SEARCH;
> + return 0;
> + }
> + }
> + tea->val &= ~TEA575X_BIT_SEARCH;
> + snd_tea575x_set_freq(tea);
> + return -ENODATA;
> +}
> +
> +static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
> +
> + switch (ctrl->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + tea->mute = ctrl->val;
> + snd_tea575x_set_freq(tea);
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static const struct v4l2_file_operations tea575x_fops = {
> + .unlocked_ioctl = video_ioctl2,
> + .open = v4l2_fh_open,
> + .release = v4l2_fh_release,
> + .poll = v4l2_ctrl_poll,
> +};
> +
> +static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
> + .vidioc_querycap = vidioc_querycap,
> + .vidioc_g_tuner = vidioc_g_tuner,
> + .vidioc_s_tuner = vidioc_s_tuner,
> + .vidioc_g_frequency = vidioc_g_frequency,
> + .vidioc_s_frequency = vidioc_s_frequency,
> + .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
> + .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
> + .vidioc_log_status = v4l2_ctrl_log_status,
> + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> + .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> +};
> +
> +static const struct video_device tea575x_radio = {
> + .ioctl_ops = &tea575x_ioctl_ops,
> + .release = video_device_release_empty,
> +};
> +
> +static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
> + .s_ctrl = tea575x_s_ctrl,
> +};
> +
> +
> +int snd_tea575x_hw_init(struct snd_tea575x *tea)
> +{
> + tea->mute = true;
> +
> + /* Not all devices can or know how to read the data back.
> + Such devices can set cannot_read_data to true. */
> + if (!tea->cannot_read_data) {
> + snd_tea575x_write(tea, 0x55AA);
> + if (snd_tea575x_read(tea) != 0x55AA)
> + return -ENODEV;
> + }
> +
> + tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28;
> + tea->freq = 90500 * 16; /* 90.5Mhz default */
> + snd_tea575x_set_freq(tea);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(snd_tea575x_hw_init);
> +
> +int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
> +{
> + int retval = snd_tea575x_hw_init(tea);
> +
> + if (retval)
> + return retval;
> +
> + tea->vd = tea575x_radio;
> + video_set_drvdata(&tea->vd, tea);
> + mutex_init(&tea->mutex);
> + strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
> + tea->vd.lock = &tea->mutex;
> + tea->vd.v4l2_dev = tea->v4l2_dev;
> + tea->fops = tea575x_fops;
> + tea->fops.owner = owner;
> + tea->vd.fops = &tea->fops;
> + set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
> + /* disable hw_freq_seek if we can't use it */
> + if (tea->cannot_read_data)
> + v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
> +
> + if (!tea->cannot_mute) {
> + tea->vd.ctrl_handler = &tea->ctrl_handler;
> + v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
> + v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops,
> + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
> + retval = tea->ctrl_handler.error;
> + if (retval) {
> + v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
> + v4l2_ctrl_handler_free(&tea->ctrl_handler);
> + return retval;
> + }
> +
> + if (tea->ext_init) {
> + retval = tea->ext_init(tea);
> + if (retval) {
> + v4l2_ctrl_handler_free(&tea->ctrl_handler);
> + return retval;
> + }
> + }
> +
> + v4l2_ctrl_handler_setup(&tea->ctrl_handler);
> + }
> +
> + retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
> + if (retval) {
> + v4l2_err(tea->v4l2_dev, "can't register video device!\n");
> + v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
> + return retval;
> + }
> +
> + return 0;
> +}
> +
> +void snd_tea575x_exit(struct snd_tea575x *tea)
> +{
> + video_unregister_device(&tea->vd);
> + v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
> +}
> +
> +static int __init alsa_tea575x_module_init(void)
> +{
> + return 0;
> +}
> +
> +static void __exit alsa_tea575x_module_exit(void)
> +{
> +}
> +
> +module_init(alsa_tea575x_module_init)
> +module_exit(alsa_tea575x_module_exit)
> +
> +EXPORT_SYMBOL(snd_tea575x_init);
> +EXPORT_SYMBOL(snd_tea575x_exit);
> +EXPORT_SYMBOL(snd_tea575x_set_freq);
> diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
> index c95d8f1..5526b03 100644
> --- a/sound/i2c/other/Makefile
> +++ b/sound/i2c/other/Makefile
> @@ -8,10 +8,8 @@ snd-ak4117-objs := ak4117.o
> snd-ak4113-objs := ak4113.o
> snd-ak4xxx-adda-objs := ak4xxx-adda.o
> snd-pt2258-objs := pt2258.o
> -snd-tea575x-tuner-objs := tea575x-tuner.o
>
> # Module Dependency
> obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
> obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
> obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
> -obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
> diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
> deleted file mode 100644
> index cef0698..0000000
> --- a/sound/i2c/other/tea575x-tuner.c
> +++ /dev/null
> @@ -1,584 +0,0 @@
> -/*
> - * ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
> - *
> - * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
> - *
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> - *
> - */
> -
> -#include <asm/io.h>
> -#include <linux/delay.h>
> -#include <linux/module.h>
> -#include <linux/init.h>
> -#include <linux/slab.h>
> -#include <linux/sched.h>
> -#include <media/v4l2-device.h>
> -#include <media/v4l2-dev.h>
> -#include <media/v4l2-fh.h>
> -#include <media/v4l2-ioctl.h>
> -#include <media/v4l2-event.h>
> -#include <media/tea575x.h>
> -
> -MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
> -MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
> -MODULE_LICENSE("GPL");
> -
> -/*
> - * definitions
> - */
> -
> -#define TEA575X_BIT_SEARCH (1<<24) /* 1 = search action, 0 = tuned */
> -#define TEA575X_BIT_UPDOWN (1<<23) /* 0 = search down, 1 = search up */
> -#define TEA575X_BIT_MONO (1<<22) /* 0 = stereo, 1 = mono */
> -#define TEA575X_BIT_BAND_MASK (3<<20)
> -#define TEA575X_BIT_BAND_FM (0<<20)
> -#define TEA575X_BIT_BAND_MW (1<<20)
> -#define TEA575X_BIT_BAND_LW (2<<20)
> -#define TEA575X_BIT_BAND_SW (3<<20)
> -#define TEA575X_BIT_PORT_0 (1<<19) /* user bit */
> -#define TEA575X_BIT_PORT_1 (1<<18) /* user bit */
> -#define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */
> -#define TEA575X_BIT_SEARCH_5_28 (0<<16) /* FM >5uV, AM >28uV */
> -#define TEA575X_BIT_SEARCH_10_40 (1<<16) /* FM >10uV, AM > 40uV */
> -#define TEA575X_BIT_SEARCH_30_63 (2<<16) /* FM >30uV, AM > 63uV */
> -#define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */
> -#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
> -#define TEA575X_BIT_FREQ_MASK 0x7fff
> -
> -enum { BAND_FM, BAND_FM_JAPAN, BAND_AM };
> -
> -static const struct v4l2_frequency_band bands[] = {
> - {
> - .type = V4L2_TUNER_RADIO,
> - .index = 0,
> - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
> - V4L2_TUNER_CAP_FREQ_BANDS,
> - .rangelow = 87500 * 16,
> - .rangehigh = 108000 * 16,
> - .modulation = V4L2_BAND_MODULATION_FM,
> - },
> - {
> - .type = V4L2_TUNER_RADIO,
> - .index = 0,
> - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
> - V4L2_TUNER_CAP_FREQ_BANDS,
> - .rangelow = 76000 * 16,
> - .rangehigh = 91000 * 16,
> - .modulation = V4L2_BAND_MODULATION_FM,
> - },
> - {
> - .type = V4L2_TUNER_RADIO,
> - .index = 1,
> - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
> - .rangelow = 530 * 16,
> - .rangehigh = 1710 * 16,
> - .modulation = V4L2_BAND_MODULATION_AM,
> - },
> -};
> -
> -/*
> - * lowlevel part
> - */
> -
> -static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
> -{
> - u16 l;
> - u8 data;
> -
> - if (tea->ops->write_val)
> - return tea->ops->write_val(tea, val);
> -
> - tea->ops->set_direction(tea, 1);
> - udelay(16);
> -
> - for (l = 25; l > 0; l--) {
> - data = (val >> 24) & TEA575X_DATA;
> - val <<= 1; /* shift data */
> - tea->ops->set_pins(tea, data | TEA575X_WREN);
> - udelay(2);
> - tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
> - udelay(2);
> - tea->ops->set_pins(tea, data | TEA575X_WREN);
> - udelay(2);
> - }
> -
> - if (!tea->mute)
> - tea->ops->set_pins(tea, 0);
> -}
> -
> -static u32 snd_tea575x_read(struct snd_tea575x *tea)
> -{
> - u16 l, rdata;
> - u32 data = 0;
> -
> - if (tea->ops->read_val)
> - return tea->ops->read_val(tea);
> -
> - tea->ops->set_direction(tea, 0);
> - tea->ops->set_pins(tea, 0);
> - udelay(16);
> -
> - for (l = 24; l--;) {
> - tea->ops->set_pins(tea, TEA575X_CLK);
> - udelay(2);
> - if (!l)
> - tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
> - tea->ops->set_pins(tea, 0);
> - udelay(2);
> - data <<= 1; /* shift data */
> - rdata = tea->ops->get_pins(tea);
> - if (!l)
> - tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
> - if (rdata & TEA575X_DATA)
> - data++;
> - udelay(2);
> - }
> -
> - if (tea->mute)
> - tea->ops->set_pins(tea, TEA575X_WREN);
> -
> - return data;
> -}
> -
> -static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val)
> -{
> - u32 freq = val & TEA575X_BIT_FREQ_MASK;
> -
> - if (freq == 0)
> - return freq;
> -
> - switch (tea->band) {
> - case BAND_FM:
> - /* freq *= 12.5 */
> - freq *= 125;
> - freq /= 10;
> - /* crystal fixup */
> - freq -= TEA575X_FMIF;
> - break;
> - case BAND_FM_JAPAN:
> - /* freq *= 12.5 */
> - freq *= 125;
> - freq /= 10;
> - /* crystal fixup */
> - freq += TEA575X_FMIF;
> - break;
> - case BAND_AM:
> - /* crystal fixup */
> - freq -= TEA575X_AMIF;
> - break;
> - }
> -
> - return clamp(freq * 16, bands[tea->band].rangelow,
> - bands[tea->band].rangehigh); /* from kHz */
> -}
> -
> -static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
> -{
> - return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea));
> -}
> -
> -void snd_tea575x_set_freq(struct snd_tea575x *tea)
> -{
> - u32 freq = tea->freq / 16; /* to kHz */
> - u32 band = 0;
> -
> - switch (tea->band) {
> - case BAND_FM:
> - band = TEA575X_BIT_BAND_FM;
> - /* crystal fixup */
> - freq += TEA575X_FMIF;
> - /* freq /= 12.5 */
> - freq *= 10;
> - freq /= 125;
> - break;
> - case BAND_FM_JAPAN:
> - band = TEA575X_BIT_BAND_FM;
> - /* crystal fixup */
> - freq -= TEA575X_FMIF;
> - /* freq /= 12.5 */
> - freq *= 10;
> - freq /= 125;
> - break;
> - case BAND_AM:
> - band = TEA575X_BIT_BAND_MW;
> - /* crystal fixup */
> - freq += TEA575X_AMIF;
> - break;
> - }
> -
> - tea->val &= ~(TEA575X_BIT_FREQ_MASK | TEA575X_BIT_BAND_MASK);
> - tea->val |= band;
> - tea->val |= freq & TEA575X_BIT_FREQ_MASK;
> - snd_tea575x_write(tea, tea->val);
> - tea->freq = snd_tea575x_val_to_freq(tea, tea->val);
> -}
> -
> -/*
> - * Linux Video interface
> - */
> -
> -static int vidioc_querycap(struct file *file, void *priv,
> - struct v4l2_capability *v)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> -
> - strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
> - strlcpy(v->card, tea->card, sizeof(v->card));
> - strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
> - strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
> - v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> - if (!tea->cannot_read_data)
> - v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
> - v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
> - return 0;
> -}
> -
> -static int vidioc_enum_freq_bands(struct file *file, void *priv,
> - struct v4l2_frequency_band *band)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> - int index;
> -
> - if (band->tuner != 0)
> - return -EINVAL;
> -
> - switch (band->index) {
> - case 0:
> - if (tea->tea5759)
> - index = BAND_FM_JAPAN;
> - else
> - index = BAND_FM;
> - break;
> - case 1:
> - if (tea->has_am) {
> - index = BAND_AM;
> - break;
> - }
> - /* Fall through */
> - default:
> - return -EINVAL;
> - }
> -
> - *band = bands[index];
> - if (!tea->cannot_read_data)
> - band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
> -
> - return 0;
> -}
> -
> -static int vidioc_g_tuner(struct file *file, void *priv,
> - struct v4l2_tuner *v)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> - struct v4l2_frequency_band band_fm = { 0, };
> -
> - if (v->index > 0)
> - return -EINVAL;
> -
> - snd_tea575x_read(tea);
> - vidioc_enum_freq_bands(file, priv, &band_fm);
> -
> - memset(v, 0, sizeof(*v));
> - strlcpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
> - v->type = V4L2_TUNER_RADIO;
> - v->capability = band_fm.capability;
> - v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow;
> - v->rangehigh = band_fm.rangehigh;
> - v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
> - v->audmode = (tea->val & TEA575X_BIT_MONO) ?
> - V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
> - v->signal = tea->tuned ? 0xffff : 0;
> - return 0;
> -}
> -
> -static int vidioc_s_tuner(struct file *file, void *priv,
> - const struct v4l2_tuner *v)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> - u32 orig_val = tea->val;
> -
> - if (v->index)
> - return -EINVAL;
> - tea->val &= ~TEA575X_BIT_MONO;
> - if (v->audmode == V4L2_TUNER_MODE_MONO)
> - tea->val |= TEA575X_BIT_MONO;
> - /* Only apply changes if currently tuning FM */
> - if (tea->band != BAND_AM && tea->val != orig_val)
> - snd_tea575x_set_freq(tea);
> -
> - return 0;
> -}
> -
> -static int vidioc_g_frequency(struct file *file, void *priv,
> - struct v4l2_frequency *f)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> -
> - if (f->tuner != 0)
> - return -EINVAL;
> - f->type = V4L2_TUNER_RADIO;
> - f->frequency = tea->freq;
> - return 0;
> -}
> -
> -static int vidioc_s_frequency(struct file *file, void *priv,
> - const struct v4l2_frequency *f)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> -
> - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
> - return -EINVAL;
> -
> - if (tea->has_am && f->frequency < (20000 * 16))
> - tea->band = BAND_AM;
> - else if (tea->tea5759)
> - tea->band = BAND_FM_JAPAN;
> - else
> - tea->band = BAND_FM;
> -
> - tea->freq = clamp_t(u32, f->frequency, bands[tea->band].rangelow,
> - bands[tea->band].rangehigh);
> - snd_tea575x_set_freq(tea);
> - return 0;
> -}
> -
> -static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
> - const struct v4l2_hw_freq_seek *a)
> -{
> - struct snd_tea575x *tea = video_drvdata(file);
> - unsigned long timeout;
> - int i, spacing;
> -
> - if (tea->cannot_read_data)
> - return -ENOTTY;
> - if (a->tuner || a->wrap_around)
> - return -EINVAL;
> -
> - if (file->f_flags & O_NONBLOCK)
> - return -EWOULDBLOCK;
> -
> - if (a->rangelow || a->rangehigh) {
> - for (i = 0; i < ARRAY_SIZE(bands); i++) {
> - if ((i == BAND_FM && tea->tea5759) ||
> - (i == BAND_FM_JAPAN && !tea->tea5759) ||
> - (i == BAND_AM && !tea->has_am))
> - continue;
> - if (bands[i].rangelow == a->rangelow &&
> - bands[i].rangehigh == a->rangehigh)
> - break;
> - }
> - if (i == ARRAY_SIZE(bands))
> - return -EINVAL; /* No matching band found */
> - if (i != tea->band) {
> - tea->band = i;
> - tea->freq = clamp(tea->freq, bands[i].rangelow,
> - bands[i].rangehigh);
> - snd_tea575x_set_freq(tea);
> - }
> - }
> -
> - spacing = (tea->band == BAND_AM) ? 5 : 50; /* kHz */
> -
> - /* clear the frequency, HW will fill it in */
> - tea->val &= ~TEA575X_BIT_FREQ_MASK;
> - tea->val |= TEA575X_BIT_SEARCH;
> - if (a->seek_upward)
> - tea->val |= TEA575X_BIT_UPDOWN;
> - else
> - tea->val &= ~TEA575X_BIT_UPDOWN;
> - snd_tea575x_write(tea, tea->val);
> - timeout = jiffies + msecs_to_jiffies(10000);
> - for (;;) {
> - if (time_after(jiffies, timeout))
> - break;
> - if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
> - /* some signal arrived, stop search */
> - tea->val &= ~TEA575X_BIT_SEARCH;
> - snd_tea575x_set_freq(tea);
> - return -ERESTARTSYS;
> - }
> - if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
> - u32 freq;
> -
> - /* Found a frequency, wait until it can be read */
> - for (i = 0; i < 100; i++) {
> - msleep(10);
> - freq = snd_tea575x_get_freq(tea);
> - if (freq) /* available */
> - break;
> - }
> - if (freq == 0) /* shouldn't happen */
> - break;
> - /*
> - * if we moved by less than the spacing, or in the
> - * wrong direction, continue seeking
> - */
> - if (abs(tea->freq - freq) < 16 * spacing ||
> - (a->seek_upward && freq < tea->freq) ||
> - (!a->seek_upward && freq > tea->freq)) {
> - snd_tea575x_write(tea, tea->val);
> - continue;
> - }
> - tea->freq = freq;
> - tea->val &= ~TEA575X_BIT_SEARCH;
> - return 0;
> - }
> - }
> - tea->val &= ~TEA575X_BIT_SEARCH;
> - snd_tea575x_set_freq(tea);
> - return -ENODATA;
> -}
> -
> -static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
> -{
> - struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
> -
> - switch (ctrl->id) {
> - case V4L2_CID_AUDIO_MUTE:
> - tea->mute = ctrl->val;
> - snd_tea575x_set_freq(tea);
> - return 0;
> - }
> -
> - return -EINVAL;
> -}
> -
> -static const struct v4l2_file_operations tea575x_fops = {
> - .unlocked_ioctl = video_ioctl2,
> - .open = v4l2_fh_open,
> - .release = v4l2_fh_release,
> - .poll = v4l2_ctrl_poll,
> -};
> -
> -static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
> - .vidioc_querycap = vidioc_querycap,
> - .vidioc_g_tuner = vidioc_g_tuner,
> - .vidioc_s_tuner = vidioc_s_tuner,
> - .vidioc_g_frequency = vidioc_g_frequency,
> - .vidioc_s_frequency = vidioc_s_frequency,
> - .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
> - .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
> - .vidioc_log_status = v4l2_ctrl_log_status,
> - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> - .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> -};
> -
> -static const struct video_device tea575x_radio = {
> - .ioctl_ops = &tea575x_ioctl_ops,
> - .release = video_device_release_empty,
> -};
> -
> -static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
> - .s_ctrl = tea575x_s_ctrl,
> -};
> -
> -
> -int snd_tea575x_hw_init(struct snd_tea575x *tea)
> -{
> - tea->mute = true;
> -
> - /* Not all devices can or know how to read the data back.
> - Such devices can set cannot_read_data to true. */
> - if (!tea->cannot_read_data) {
> - snd_tea575x_write(tea, 0x55AA);
> - if (snd_tea575x_read(tea) != 0x55AA)
> - return -ENODEV;
> - }
> -
> - tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28;
> - tea->freq = 90500 * 16; /* 90.5Mhz default */
> - snd_tea575x_set_freq(tea);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(snd_tea575x_hw_init);
> -
> -int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
> -{
> - int retval = snd_tea575x_hw_init(tea);
> -
> - if (retval)
> - return retval;
> -
> - tea->vd = tea575x_radio;
> - video_set_drvdata(&tea->vd, tea);
> - mutex_init(&tea->mutex);
> - strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
> - tea->vd.lock = &tea->mutex;
> - tea->vd.v4l2_dev = tea->v4l2_dev;
> - tea->fops = tea575x_fops;
> - tea->fops.owner = owner;
> - tea->vd.fops = &tea->fops;
> - set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
> - /* disable hw_freq_seek if we can't use it */
> - if (tea->cannot_read_data)
> - v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
> -
> - if (!tea->cannot_mute) {
> - tea->vd.ctrl_handler = &tea->ctrl_handler;
> - v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
> - v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops,
> - V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
> - retval = tea->ctrl_handler.error;
> - if (retval) {
> - v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
> - v4l2_ctrl_handler_free(&tea->ctrl_handler);
> - return retval;
> - }
> -
> - if (tea->ext_init) {
> - retval = tea->ext_init(tea);
> - if (retval) {
> - v4l2_ctrl_handler_free(&tea->ctrl_handler);
> - return retval;
> - }
> - }
> -
> - v4l2_ctrl_handler_setup(&tea->ctrl_handler);
> - }
> -
> - retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
> - if (retval) {
> - v4l2_err(tea->v4l2_dev, "can't register video device!\n");
> - v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
> - return retval;
> - }
> -
> - return 0;
> -}
> -
> -void snd_tea575x_exit(struct snd_tea575x *tea)
> -{
> - video_unregister_device(&tea->vd);
> - v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
> -}
> -
> -static int __init alsa_tea575x_module_init(void)
> -{
> - return 0;
> -}
> -
> -static void __exit alsa_tea575x_module_exit(void)
> -{
> -}
> -
> -module_init(alsa_tea575x_module_init)
> -module_exit(alsa_tea575x_module_exit)
> -
> -EXPORT_SYMBOL(snd_tea575x_init);
> -EXPORT_SYMBOL(snd_tea575x_exit);
> -EXPORT_SYMBOL(snd_tea575x_set_freq);
> diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
> index fe6fa93..9df80ef 100644
> --- a/sound/pci/Kconfig
> +++ b/sound/pci/Kconfig
> @@ -1,10 +1,5 @@
> # ALSA PCI drivers
>
> -config SND_TEA575X
> - tristate
> - depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
> - default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
> -
> menuconfig SND_PCI
> bool "PCI sound devices"
> depends on PCI
> @@ -542,7 +537,9 @@ config SND_ES1968_INPUT
> config SND_ES1968_RADIO
> bool "Enable TEA5757 radio tuner support for es1968"
> depends on SND_ES1968
> + depends on MEDIA_RADIO_SUPPORT
> depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
> + select RADIO_TEA575X
> help
> Say Y here to include support for TEA5757 radio tuner integrated on
> some MediaForte cards (e.g. SF64-PCE2).
> @@ -562,7 +559,9 @@ config SND_FM801
> config SND_FM801_TEA575X_BOOL
> bool "ForteMedia FM801 + TEA5757 tuner"
> depends on SND_FM801
> + depends on MEDIA_RADIO_SUPPORT
> depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
> + select RADIO_TEA575X
> help
> Say Y here to include support for soundcards based on the ForteMedia
> FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [alsa-devel] [PATCH 0/2] tea575x: Move from sound to media
2013-07-28 20:01 [PATCH 0/2] tea575x: Move from sound to media Ondrej Zary
2013-07-28 20:01 ` [PATCH 1/2] tea575x: Move header " Ondrej Zary
@ 2013-07-29 14:53 ` Takashi Iwai
1 sibling, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2013-07-29 14:53 UTC (permalink / raw)
To: Ondrej Zary; +Cc: Hans Verkuil, alsa-devel, linux-media
At Sun, 28 Jul 2013 22:01:42 +0200,
Ondrej Zary wrote:
>
>
> Hello,
> TEA575x is neither a sound device nor an i2c device. Let's finally move it
> from sound/i2c/other to drivers/media/radio.
>
> Tested with snd-es1968, snd-fm801 and radio-sf16fmr2.
Good to resolve messes there now.
For both patches,
Acked-by: Takashi Iwai <tiwai@suse.de>
Feel free to move them into media git tree for 3.12 kernel.
thanks,
Takashi
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-07-29 14:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-28 20:01 [PATCH 0/2] tea575x: Move from sound to media Ondrej Zary
2013-07-28 20:01 ` [PATCH 1/2] tea575x: Move header " Ondrej Zary
2013-07-28 20:01 ` [PATCH 2/2] tea575x: Move " Ondrej Zary
2013-07-29 7:58 ` Hans Verkuil
2013-07-29 7:56 ` [PATCH 1/2] tea575x: Move header " Hans Verkuil
2013-07-29 14:53 ` [alsa-devel] [PATCH 0/2] tea575x: Move " Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).