From f7519d8c8290765a9408a52db4ba4a368ff72ca5 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 20 Dec 2011 22:54:18 +0100 Subject: ARM: OMAP1: ams-delta: register latch dependent devices later In preparation to converting Amstrad Delta on-board latches to basic_mmio_gpio devices, registration of platform devices which depend on latches and will require initialization of their GPIO pins first, should be moved out of .machine_init down to late_initcall level, as the gpio-generic driver is not available until device_initcall time. The latch reset operation, which will be replaced with GPIO initialization, must also be moved to late_initcall for the same reason. Since there was already another, separate arch_initcall function for setting up one of those latch dependent devices, the on-board modem device, reuse that function, i.e., rename it to a name that matches the new purpose, extend with other device setup relocated from .machine_init, and move down to the late_initcall level. While being at it, add missing gpio_free() in case the modem platform device registration fails. Thanks to Tony Lindgren who suggested this approach instead of shifting up the gpio-generic driver initialization. In addition, defer registration of the Amstrad Delta ASoC and serio devices, done from their device driver files, until late_initcall time, as those drivers will depend on their GPIO pins already requested from the board late_init() function until updated to register their GPIO pins themselves. Signed-off-by: Janusz Krzysztofik Acked-by: Mark Brown Signed-off-by: Tony Lindgren --- sound/soc/omap/ams-delta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index ccb8a6aa1817..be81bc791b11 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -636,7 +636,7 @@ err: platform_device_put(ams_delta_audio_platform_device); return ret; } -module_init(ams_delta_module_init); +late_initcall(ams_delta_module_init); static void __exit ams_delta_module_exit(void) { -- cgit v1.2.1 From 210762268466634ddbfaddb48fdf5181ce4b5f2d Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 27 Aug 2011 18:53:03 +0200 Subject: firewire: move fw_device reference counting from drivers to core fw_unit device drivers invariably need to talk to the fw_unit's parent (an fw_device) and grandparent (an fw_card). firewire-core already maintains an fw_card reference for the entire lifetime of an fw_device. Likewise, let firewire-core maintain an fw_device reference for the entire lifetime of an fw_unit so that fw_unit drivers don't have to. Signed-off-by: Stefan Richter --- sound/firewire/isight.c | 4 +--- sound/firewire/speakers.c | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'sound') diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 440030818db7..412b65f740d9 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c @@ -612,7 +612,6 @@ static void isight_card_free(struct snd_card *card) fw_iso_resources_destroy(&isight->resources); fw_unit_put(isight->unit); - fw_device_put(isight->device); mutex_destroy(&isight->mutex); } @@ -645,7 +644,7 @@ static int isight_probe(struct device *unit_dev) isight->card = card; mutex_init(&isight->mutex); isight->unit = fw_unit_get(unit); - isight->device = fw_device_get(fw_dev); + isight->device = fw_dev; isight->audio_base = get_unit_base(unit); if (!isight->audio_base) { dev_err(&unit->device, "audio unit base not found\n"); @@ -682,7 +681,6 @@ static int isight_probe(struct device *unit_dev) err_unit: fw_unit_put(isight->unit); - fw_device_put(isight->device); mutex_destroy(&isight->mutex); error: snd_card_free(card); diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 3fc257da180c..18b9b5607f3c 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c @@ -656,12 +656,10 @@ static u32 fwspk_read_firmware_version(struct fw_unit *unit) static void fwspk_card_free(struct snd_card *card) { struct fwspk *fwspk = card->private_data; - struct fw_device *dev = fw_parent_device(fwspk->unit); amdtp_out_stream_destroy(&fwspk->stream); cmp_connection_destroy(&fwspk->connection); fw_unit_put(fwspk->unit); - fw_device_put(dev); mutex_destroy(&fwspk->mutex); } @@ -718,7 +716,6 @@ static int __devinit fwspk_probe(struct device *unit_dev) fwspk = card->private_data; fwspk->card = card; mutex_init(&fwspk->mutex); - fw_device_get(fw_dev); fwspk->unit = fw_unit_get(unit); fwspk->device_info = fwspk_detect(fw_dev); if (!fwspk->device_info) { @@ -767,7 +764,6 @@ err_connection: cmp_connection_destroy(&fwspk->connection); err_unit: fw_unit_put(fwspk->unit); - fw_device_put(fw_dev); mutex_destroy(&fwspk->mutex); error: snd_card_free(card); -- cgit v1.2.1 From 462835e4a7f898662cc30064a33177af4823ef9d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 12:11:53 +0000 Subject: mfd/ASoC: Convert WM8994 driver to use regmap patches Early revisions of several of the WM8994 variants have register updates to improve performance. Move these over to using the regmap patch system instead of open coding them in the audio driver. Since the regmap init is done by the MFD the code is moved there. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz --- sound/soc/codecs/wm8994.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index ec69a6c152fe..7c686abf8bd9 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2099,26 +2099,9 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { switch (control->type) { - case WM8994: - if (wm8994->revision < 4) { - /* Tweak DC servo and DSP - * configuration for improved - * performance. */ - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0x56, 0x3); - snd_soc_write(codec, 0x817, 0); - snd_soc_write(codec, 0x102, 0); - } - break; - case WM8958: if (wm8994->revision == 0) { /* Optimise performance for rev A */ - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0xcb, 0x81); - snd_soc_write(codec, 0x817, 0); - snd_soc_write(codec, 0x102, 0); - snd_soc_update_bits(codec, WM8958_CHARGE_PUMP_2, WM8958_CP_DISCH, @@ -2126,13 +2109,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, } break; - case WM1811: - if (wm8994->revision < 2) { - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0x5d, 0x7e); - snd_soc_write(codec, 0x5e, 0x0); - snd_soc_write(codec, 0x102, 0x0); - } + default: break; } -- cgit v1.2.1 From b130d5c29544fe4cedafd35b112d27a06550d844 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Fri, 3 Feb 2012 14:29:23 +0900 Subject: ARM: S3C24XX: change the ARCH_S3C2410 to ARCH_S3C24XX This patch changes the ARCH name to "ARCH_S3C24XX" for Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, and S3C2450 SoCs so that we can merge the mach-xxx directories and plat-s3c24xx dir. to just one mach-s3c24xx for them. I think this should be sent to upstream via samsung tree because this touches many samsung stuff. Cc: Dmitry Torokhov Cc: Richard Purdie Cc: Chris Ball Cc: David Woodhouse Cc: Alessandro Zummo Cc: Grant Likely Cc: Greg Kroah-Hartman [for the gadget part:] Acked-by: Felipe Balbi [for the framebuffer (video) part:] Acked-by: Florian Tobias Schandinat [For the watchdog-part:] Acked-by: Wim Van Sebroeck Cc: Sangbeom Kim Cc: Liam Girdwood Cc: Mark Brown Cc: Russell King Signed-off-by: Kukjin Kim --- sound/soc/samsung/Kconfig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index f3417f2311b8..fe3995ce9b38 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,8 +1,8 @@ config SND_SOC_SAMSUNG tristate "ASoC support for Samsung" - depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 + depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 select S3C64XX_DMA if ARCH_S3C64XX - select S3C2410_DMA if ARCH_S3C2410 + select S3C2410_DMA if ARCH_S3C24XX help Say Y or M if you want to add support for codecs attached to the Samsung SoCs' Audio interfaces. You will also need to @@ -84,7 +84,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710 config SND_SOC_SAMSUNG_LN2440SBC_ALC650 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" - depends on SND_SOC_SAMSUNG && ARCH_S3C2410 + depends on SND_SOC_SAMSUNG && ARCH_S3C24XX select S3C2410_DMA select AC97_BUS select SND_SOC_AC97_CODEC @@ -95,7 +95,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650 config SND_SOC_SAMSUNG_S3C24XX_UDA134X tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" - depends on SND_SOC_SAMSUNG && ARCH_S3C2410 + depends on SND_SOC_SAMSUNG && ARCH_S3C24XX select SND_S3C24XX_I2S select SND_SOC_L3 select SND_SOC_UDA134X @@ -107,14 +107,14 @@ config SND_SOC_SAMSUNG_SIMTEC config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" - depends on SND_SOC_SAMSUNG && ARCH_S3C2410 + depends on SND_SOC_SAMSUNG && ARCH_S3C24XX select SND_S3C24XX_I2S select SND_SOC_TLV320AIC23 select SND_SOC_SAMSUNG_SIMTEC config SND_SOC_SAMSUNG_SIMTEC_HERMES tristate "SoC I2S Audio support for Simtec Hermes board" - depends on SND_SOC_SAMSUNG && ARCH_S3C2410 + depends on SND_SOC_SAMSUNG && ARCH_S3C24XX select SND_S3C24XX_I2S select SND_SOC_TLV320AIC3X select SND_SOC_SAMSUNG_SIMTEC -- cgit v1.2.1 From 0379c1f55b734d9d112f535e12f4508b90a1bab1 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Mon, 5 Mar 2012 17:05:12 +0100 Subject: ASoC: OMAP: ams-delta: drop .set_bias_level callback This functionality has already been implemented in the cx20442 codec driver (commit f75a8ff67d161b5166a2c2360bb2ffaefd5eb853, "ASoC: cx20442: add bias control over a platform provided regulator"), no need to keep it here duplicated. Once done, remove the no longer used AMS_DELTA_LATCH2_MODEM_NRESET symbol from the board header file and a call to the regulator_toggle() helper function from the old API wrapper found in the board file. While being at it, simplify the way the modem .pm callback handles the regulator and drop that helper function and its related consumer setup completely. Depends on patches 1/3 and 2/3 for clean apply and keep things working. Signed-off-by: Janusz Krzysztofik Acked-by: Mark Brown Cc: Tony Lindgren Signed-off-by: Tony Lindgren --- sound/soc/omap/ams-delta.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index da6e005c1c41..f610260065ba 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -426,29 +426,6 @@ static struct snd_soc_ops ams_delta_ops = { }; -/* Board specific codec bias level control */ -static int ams_delta_set_bias_level(struct snd_soc_card *card, - struct snd_soc_dapm_context *dapm, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: - case SND_SOC_BIAS_PREPARE: - case SND_SOC_BIAS_STANDBY: - if (card->dapm.bias_level == SND_SOC_BIAS_OFF) - ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, - AMS_DELTA_LATCH2_MODEM_NRESET); - break; - case SND_SOC_BIAS_OFF: - if (card->dapm.bias_level != SND_SOC_BIAS_OFF) - ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, - 0); - } - card->dapm.bias_level = level; - - return 0; -} - /* Digital mute implemented using modem/CPU multiplexer. * Shares hardware with codec config pulse generation */ static bool ams_delta_muted = 1; @@ -512,9 +489,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) ams_delta_ops.shutdown = ams_delta_shutdown; } - /* Set codec bias level */ - ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); - /* Add hook switch - can be used to control the codec from userspace * even if line discipline fails */ ret = snd_soc_jack_new(rtd->codec, "hook_switch", @@ -598,7 +572,6 @@ static struct snd_soc_card ams_delta_audio_card = { .owner = THIS_MODULE, .dai_link = &ams_delta_dai_link, .num_links = 1, - .set_bias_level = ams_delta_set_bias_level, }; /* Module init/exit */ @@ -647,11 +620,6 @@ static void __exit ams_delta_module_exit(void) ARRAY_SIZE(ams_delta_hook_switch_gpios), ams_delta_hook_switch_gpios); - /* Keep modem power on */ - ams_delta_set_bias_level(&ams_delta_audio_card, - &ams_delta_audio_card.rtd[0].codec->dapm, - SND_SOC_BIAS_STANDBY); - platform_device_unregister(cx20442_platform_device); platform_device_unregister(ams_delta_audio_platform_device); } -- cgit v1.2.1 From 51990e825431089747f8896244b5c17d3a6423f1 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 22 Jan 2012 11:23:42 -0500 Subject: device.h: cleanup users outside of linux/include (C files) For files that are actively using linux/device.h, make sure that they call it out. This will allow us to clean up some of the implicit uses of linux/device.h within include/* without introducing build regressions. Yes, this was created by "cheating" -- i.e. the headers were cleaned up, and then the fallout was found and fixed, and then the two commits were reordered. This ensures we don't introduce build regressions into the git history. Signed-off-by: Paul Gortmaker --- sound/core/init.c | 1 + sound/core/pcm.c | 1 + sound/core/seq/seq.c | 1 + sound/core/timer.c | 1 + 4 files changed, 4 insertions(+) (limited to 'sound') diff --git a/sound/core/init.c b/sound/core/init.c index 3ac49b1b7cb8..995fc5d4b1a3 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 8928ca871c22..1888a90bd5b6 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 9d8379aedf40..712110561082 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/sound/core/timer.c b/sound/core/timer.c index 8e7561dfc5fc..6ddcf06f52f9 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.1 From f15855bfaad29b2badd4a5c30ad73e0542a19d16 Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Wed, 11 Jan 2012 11:04:42 +1100 Subject: ep93xx: Don't use system controller defines in audio drivers Both the Snapper CL15 and EDB93xx audio drivers set the same audio configuration in ep93xx_i2s_acquire. Remove the arguments to ep93xx_i2s_acquire so that the audio drivers no longer need the EP93XX_SYSCON defines exported. Signed-off-by: Ryan Mallon Cc: Liam Girdwood Cc: Mark Brown Reviewed-by: Mika Westerberg Acked-by: Hartley Sweeten --- sound/soc/ep93xx/edb93xx.c | 4 +--- sound/soc/ep93xx/snappercl15.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c index bae5cbbbd2b2..e01cb02abd3a 100644 --- a/sound/soc/ep93xx/edb93xx.c +++ b/sound/soc/ep93xx/edb93xx.c @@ -85,9 +85,7 @@ static int __devinit edb93xx_probe(struct platform_device *pdev) struct snd_soc_card *card = &snd_soc_edb93xx; int ret; - ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, - EP93XX_SYSCON_I2SCLKDIV_ORIDE | - EP93XX_SYSCON_I2SCLKDIV_SPOL); + ret = ep93xx_i2s_acquire(); if (ret) return ret; diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index ccae34a3f280..a193cea3cf3c 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -103,9 +103,7 @@ static int __devinit snappercl15_probe(struct platform_device *pdev) struct snd_soc_card *card = &snd_soc_snappercl15; int ret; - ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, - EP93XX_SYSCON_I2SCLKDIV_ORIDE | - EP93XX_SYSCON_I2SCLKDIV_SPOL); + ret = ep93xx_i2s_acquire(); if (ret) return ret; -- cgit v1.2.1 From 9e5ed094c89e55fbf11d2e81d60be98eb12346c0 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 15 Mar 2012 10:40:38 +0100 Subject: ARM: 7362/1: AMBA: Add module_amba_driver() helper macro for amba_driver For simple modules that contain a single amba_driver without any additional setup code then ends up being a block of duplicated boilerplate. This patch adds a new macro, module_amba_driver(), which replaces the module_init()/module_exit() registrations with template functions. Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- sound/arm/aaci.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b37b702a3a6a..5119fdabcb98 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -1110,18 +1110,7 @@ static struct amba_driver aaci_driver = { .id_table = aaci_ids, }; -static int __init aaci_init(void) -{ - return amba_driver_register(&aaci_driver); -} - -static void __exit aaci_exit(void) -{ - amba_driver_unregister(&aaci_driver); -} - -module_init(aaci_init); -module_exit(aaci_exit); +module_amba_driver(aaci_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver"); -- cgit v1.2.1 From d4ecc83b79cc290eadf1ffb33a589c3c72bbc295 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Feb 2012 05:30:13 -0300 Subject: [media] tea575x-tuner: update to latest V4L2 framework requirements The tea575x-tuner module has been updated to use the latest V4L2 framework functionality. This also required changes in the drivers that rely on it. The tea575x changes are: - The drivers must provide a v4l2_device struct to the tea module. - The radio_nr module parameter must be part of the actual radio driver, and not of the tea module. - Changed the frequency range to the normal 76-108 MHz range instead of 50-150. - Add hardware frequency seek support. - Fix broken rxsubchans/audmode handling. - The application can now select between stereo and mono. - Support polling for control events. - Add V4L2 priority handling. And radio-sf16fmr2.c now uses the isa bus kernel framework. Signed-off-by: Hans Verkuil Thanks-to: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- sound/i2c/other/tea575x-tuner.c | 146 ++++++++++++++++++++++------------------ sound/pci/es1968.c | 15 +++++ sound/pci/fm801.c | 20 +++++- 3 files changed, 113 insertions(+), 68 deletions(-) (limited to 'sound') diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 6b68c8206805..b291bd86c4ca 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -25,21 +25,20 @@ #include #include #include -#include +#include +#include #include +#include #include +#include #include MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); MODULE_LICENSE("GPL"); -static int radio_nr = -1; -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) -#define FREQ_LO (50UL * 16000) -#define FREQ_HI (150UL * 16000) +#define FREQ_LO (76U * 16000) +#define FREQ_HI (108U * 16000) /* * definitions @@ -121,28 +120,10 @@ static unsigned int snd_tea575x_read(struct snd_tea575x *tea) return data; } -static void snd_tea575x_get_freq(struct snd_tea575x *tea) -{ - unsigned long freq; - - freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; - /* freq *= 12.5 */ - freq *= 125; - freq /= 10; - /* crystal fixup */ - if (tea->tea5759) - freq += TEA575X_FMIF; - else - freq -= TEA575X_FMIF; - - tea->freq = freq * 16; /* from kHz */ -} - static void snd_tea575x_set_freq(struct snd_tea575x *tea) { - unsigned long freq; + u32 freq = tea->freq; - freq = clamp(tea->freq, FREQ_LO, FREQ_HI); freq /= 16; /* to kHz */ /* crystal fixup */ if (tea->tea5759) @@ -167,12 +148,14 @@ static int vidioc_querycap(struct file *file, void *priv, { struct snd_tea575x *tea = video_drvdata(file); - strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); + 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->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + 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; } @@ -191,18 +174,24 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; v->rangelow = FREQ_LO; v->rangehigh = FREQ_HI; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; + 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, struct v4l2_tuner *v) { - if (v->index > 0) + struct snd_tea575x *tea = video_drvdata(file); + + if (v->index) return -EINVAL; + tea->val &= ~TEA575X_BIT_MONO; + if (v->audmode == V4L2_TUNER_MODE_MONO) + tea->val |= TEA575X_BIT_MONO; + snd_tea575x_write(tea, tea->val); return 0; } @@ -214,7 +203,6 @@ static int vidioc_g_frequency(struct file *file, void *priv, if (f->tuner != 0) return -EINVAL; f->type = V4L2_TUNER_RADIO; - snd_tea575x_get_freq(tea); f->frequency = tea->freq; return 0; } @@ -227,32 +215,47 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) return -EINVAL; - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) - return -EINVAL; - - tea->freq = f->frequency; - + tea->val &= ~TEA575X_BIT_SEARCH; + tea->freq = clamp(f->frequency, FREQ_LO, FREQ_HI); snd_tea575x_set_freq(tea); - return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_hw_freq_seek(struct file *file, void *fh, + struct v4l2_hw_freq_seek *a) { - if (a->index > 1) - return -EINVAL; - - strcpy(a->name, "Radio"); - a->capability = V4L2_AUDCAP_STEREO; - return 0; -} + struct snd_tea575x *tea = video_drvdata(file); -static int vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - if (a->index != 0) + if (tea->cannot_read_data) + return -ENOTTY; + if (a->tuner || a->wrap_around) return -EINVAL; + tea->val |= TEA575X_BIT_SEARCH; + tea->val &= ~TEA575X_BIT_UPDOWN; + if (a->seek_upward) + tea->val |= TEA575X_BIT_UPDOWN; + snd_tea575x_write(tea, tea->val); + for (;;) { + unsigned val = snd_tea575x_read(tea); + + if (!(val & TEA575X_BIT_SEARCH)) { + /* Found a frequency */ + val &= TEA575X_BIT_FREQ_MASK; + val = (val * 10) / 125; + if (tea->tea5759) + val += TEA575X_FMIF; + else + val -= TEA575X_FMIF; + tea->freq = clamp(val * 16, FREQ_LO, FREQ_HI); + return 0; + } + if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { + /* some signal arrived, stop search */ + tea->val &= ~TEA575X_BIT_SEARCH; + snd_tea575x_write(tea, tea->val); + return -ERESTARTSYS; + } + } return 0; } @@ -273,23 +276,27 @@ static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) static const struct v4l2_file_operations tea575x_fops = { .owner = THIS_MODULE, .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_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek, + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device tea575x_radio = { - .name = "tea575x-tuner", +static const struct video_device tea575x_radio = { .fops = &tea575x_fops, .ioctl_ops = &tea575x_ioctl_ops, - .release = video_device_release_empty, + .release = video_device_release_empty, }; static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { @@ -303,11 +310,15 @@ int snd_tea575x_init(struct snd_tea575x *tea) { int retval; - tea->mute = 1; + tea->mute = true; - snd_tea575x_write(tea, 0x55AA); - if (snd_tea575x_read(tea) != 0x55AA) - return -ENODEV; + /* 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_10_40; tea->freq = 90500 * 16; /* 90.5Mhz default */ @@ -316,14 +327,17 @@ int snd_tea575x_init(struct snd_tea575x *tea) 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->vd.ctrl_handler = &tea->ctrl_handler; + set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); - tea->vd.ctrl_handler = &tea->ctrl_handler; 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) { - printk(KERN_ERR "tea575x-tuner: can't initialize controls\n"); + v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); v4l2_ctrl_handler_free(&tea->ctrl_handler); return retval; } @@ -338,9 +352,9 @@ int snd_tea575x_init(struct snd_tea575x *tea) v4l2_ctrl_handler_setup(&tea->ctrl_handler); - retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr); + retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr); if (retval) { - printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); + v4l2_err(tea->v4l2_dev, "can't register video device!\n"); v4l2_ctrl_handler_free(&tea->ctrl_handler); return retval; } diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index cb557c603a80..a8faae1c85e4 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -142,6 +142,7 @@ static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; #ifdef SUPPORT_JOYSTICK static bool joystick[SNDRV_CARDS]; #endif +static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); @@ -165,6 +166,9 @@ MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)"); module_param_array(joystick, bool, NULL, 0444); MODULE_PARM_DESC(joystick, "Enable joystick."); #endif +module_param_array(radio_nr, int, NULL, 0444); +MODULE_PARM_DESC(radio_nr, "Radio device numbers"); + #define NR_APUS 64 @@ -558,6 +562,7 @@ struct es1968 { struct work_struct hwvol_work; #ifdef CONFIG_SND_ES1968_RADIO + struct v4l2_device v4l2_dev; struct snd_tea575x tea; #endif }; @@ -2613,6 +2618,7 @@ static int snd_es1968_free(struct es1968 *chip) #ifdef CONFIG_SND_ES1968_RADIO snd_tea575x_exit(&chip->tea); + v4l2_device_unregister(&chip->v4l2_dev); #endif if (chip->irq >= 0) @@ -2655,6 +2661,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, int capt_streams, int chip_type, int do_pm, + int radio_nr, struct es1968 **chip_ret) { static struct snd_device_ops ops = { @@ -2751,7 +2758,14 @@ static int __devinit snd_es1968_create(struct snd_card *card, snd_card_set_dev(card, &pci->dev); #ifdef CONFIG_SND_ES1968_RADIO + err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); + if (err < 0) { + snd_es1968_free(chip); + return err; + } + chip->tea.v4l2_dev = &chip->v4l2_dev; chip->tea.private_data = chip; + chip->tea.radio_nr = radio_nr; chip->tea.ops = &snd_es1968_tea_ops; strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); @@ -2797,6 +2811,7 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, pcm_substreams_c[dev], pci_id->driver_data, use_pm[dev], + radio_nr[dev], &chip)) < 0) { snd_card_free(card); return err; diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 9597ef1eccca..a416ea8af3e9 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -58,6 +58,7 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card * High 16-bits are video (radio) device number + 1 */ static int tea575x_tuner[SNDRV_CARDS]; +static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); @@ -67,6 +68,9 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); module_param_array(tea575x_tuner, int, NULL, 0444); MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); +module_param_array(radio_nr, int, NULL, 0444); +MODULE_PARM_DESC(radio_nr, "Radio device numbers"); + #define TUNER_DISABLED (1<<3) #define TUNER_ONLY (1<<4) @@ -197,6 +201,7 @@ struct fm801 { struct snd_info_entry *proc_entry; #ifdef CONFIG_SND_FM801_TEA575X_BOOL + struct v4l2_device v4l2_dev; struct snd_tea575x tea; #endif @@ -1154,8 +1159,10 @@ static int snd_fm801_free(struct fm801 *chip) __end_hw: #ifdef CONFIG_SND_FM801_TEA575X_BOOL - if (!(chip->tea575x_tuner & TUNER_DISABLED)) + if (!(chip->tea575x_tuner & TUNER_DISABLED)) { snd_tea575x_exit(&chip->tea); + v4l2_device_unregister(&chip->v4l2_dev); + } #endif if (chip->irq >= 0) free_irq(chip->irq, chip); @@ -1175,6 +1182,7 @@ static int snd_fm801_dev_free(struct snd_device *device) static int __devinit snd_fm801_create(struct snd_card *card, struct pci_dev * pci, int tea575x_tuner, + int radio_nr, struct fm801 ** rchip) { struct fm801 *chip; @@ -1234,6 +1242,13 @@ static int __devinit snd_fm801_create(struct snd_card *card, snd_card_set_dev(card, &pci->dev); #ifdef CONFIG_SND_FM801_TEA575X_BOOL + err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); + if (err < 0) { + snd_fm801_free(chip); + return err; + } + chip->tea.v4l2_dev = &chip->v4l2_dev; + chip->tea.radio_nr = radio_nr; chip->tea.private_data = chip; chip->tea.ops = &snd_fm801_tea_ops; sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); @@ -1241,6 +1256,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, (tea575x_tuner & TUNER_TYPE_MASK) < 4) { if (snd_tea575x_init(&chip->tea)) { snd_printk(KERN_ERR "TEA575x radio not found\n"); + snd_fm801_free(chip); return -ENODEV; } } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { @@ -1287,7 +1303,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci, err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); if (err < 0) return err; - if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { + if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) { snd_card_free(card); return err; } -- cgit v1.2.1 From bc2b395c031430639e5ad5dcb2669cfcf1fa5fd2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Feb 2012 05:31:58 -0300 Subject: [media] tea575x: fix HW seek Fix HW seek in TEA575x to work properly: - a delay must be present after search start and before first register read or the seek does weird things - when the search stops, the new frequency is not available immediately, we must wait until it appears in the register (fortunately, we can clear the frequency bits when starting the search as it starts at the frequency currently set, not from the value written) - sometimes, seek remains on the current frequency (or moves only a little), so repeat it until it moves by at least 50 kHz Signed-off-by: Ondrej Zary Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- sound/i2c/other/tea575x-tuner.c | 79 +++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 18 deletions(-) (limited to 'sound') diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index b291bd86c4ca..a63faec5e7fd 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -89,7 +89,7 @@ static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val) tea->ops->set_pins(tea, 0); } -static unsigned int snd_tea575x_read(struct snd_tea575x *tea) +static u32 snd_tea575x_read(struct snd_tea575x *tea) { u16 l, rdata; u32 data = 0; @@ -120,6 +120,25 @@ static unsigned int snd_tea575x_read(struct snd_tea575x *tea) return data; } +static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) +{ + u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; + + if (freq == 0) + return freq; + + /* freq *= 12.5 */ + freq *= 125; + freq /= 10; + /* crystal fixup */ + if (tea->tea5759) + freq += TEA575X_FMIF; + else + freq -= TEA575X_FMIF; + + return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */ +} + static void snd_tea575x_set_freq(struct snd_tea575x *tea) { u32 freq = tea->freq; @@ -225,38 +244,62 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *fh, struct v4l2_hw_freq_seek *a) { struct snd_tea575x *tea = video_drvdata(file); + unsigned long timeout; + int i; if (tea->cannot_read_data) return -ENOTTY; if (a->tuner || a->wrap_around) return -EINVAL; + + /* clear the frequency, HW will fill it in */ + tea->val &= ~TEA575X_BIT_FREQ_MASK; tea->val |= TEA575X_BIT_SEARCH; - tea->val &= ~TEA575X_BIT_UPDOWN; 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 (;;) { - unsigned val = snd_tea575x_read(tea); - - if (!(val & TEA575X_BIT_SEARCH)) { - /* Found a frequency */ - val &= TEA575X_BIT_FREQ_MASK; - val = (val * 10) / 125; - if (tea->tea5759) - val += TEA575X_FMIF; - else - val -= TEA575X_FMIF; - tea->freq = clamp(val * 16, FREQ_LO, FREQ_HI); - return 0; - } + 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_write(tea, tea->val); + 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 50 kHz, or in the wrong + * direction, continue seeking + */ + if (abs(tea->freq - freq) < 16 * 50 || + (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; + } } - return 0; + tea->val &= ~TEA575X_BIT_SEARCH; + snd_tea575x_set_freq(tea); + return -EAGAIN; } static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) @@ -320,7 +363,7 @@ int snd_tea575x_init(struct snd_tea575x *tea) return -ENODEV; } - tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; + tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28; tea->freq = 90500 * 16; /* 90.5Mhz default */ snd_tea575x_set_freq(tea); -- cgit v1.2.1