/* * raumfeld_audio.c -- SoC audio for Raumfeld audio devices * * Copyright (c) 2009 Daniel Mack * * based on code from: * * Wolfson Microelectronics PLC. * Openedhand Ltd. * Liam Girdwood * Richard Purdie * * 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. */ #include #include #include #include #include #include #include #include "pxa-ssp.h" #define GPIO_SPDIF_RESET (38) #define GPIO_MCLK_RESET (111) #define GPIO_CODEC_RESET (120) static struct i2c_client *max9486_client; static struct i2c_board_info max9486_hwmon_info = { I2C_BOARD_INFO("max9485", 0x63), }; #define MAX9485_MCLK_FREQ_112896 0x22 #define MAX9485_MCLK_FREQ_122880 0x23 #define MAX9485_MCLK_FREQ_225792 0x32 #define MAX9485_MCLK_FREQ_245760 0x33 static void set_max9485_clk(char clk) { i2c_master_send(max9486_client, &clk, 1); } static void raumfeld_enable_audio(bool en) { if (en) { gpio_set_value(GPIO_MCLK_RESET, 1); /* wait some time to let the clocks become stable */ msleep(100); gpio_set_value(GPIO_SPDIF_RESET, 1); gpio_set_value(GPIO_CODEC_RESET, 1); } else { gpio_set_value(GPIO_MCLK_RESET, 0); gpio_set_value(GPIO_SPDIF_RESET, 0); gpio_set_value(GPIO_CODEC_RESET, 0); } } /* CS4270 */ static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; /* set freq to 0 to enable all possible codec sample rates */ return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0); } static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; /* set freq to 0 to enable all possible codec sample rates */ snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0); } static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int clk = 0; int ret = 0; switch (params_rate(params)) { case 44100: set_max9485_clk(MAX9485_MCLK_FREQ_112896); clk = 11289600; break; case 48000: set_max9485_clk(MAX9485_MCLK_FREQ_122880); clk = 12288000; break; case 88200: set_max9485_clk(MAX9485_MCLK_FREQ_225792); clk = 22579200; break; case 96000: set_max9485_clk(MAX9485_MCLK_FREQ_245760); clk = 24576000; break; default: return -EINVAL; } ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0); if (ret < 0) return ret; /* setup the CPU DAI */ ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1); if (ret < 0) return ret; return 0; } static struct snd_soc_ops raumfeld_cs4270_ops = { .startup = raumfeld_cs4270_startup, .shutdown = raumfeld_cs4270_shutdown, .hw_params = raumfeld_cs4270_hw_params, }; static int raumfeld_analog_suspend(struct snd_soc_card *card) { raumfeld_enable_audio(false); return 0; } static int raumfeld_analog_resume(struct snd_soc_card *card) { raumfeld_enable_audio(true); return 0; } /* AK4104 */ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0, clk = 0; switch (params_rate(params)) { case 44100: set_max9485_clk(MAX9485_MCLK_FREQ_112896); clk = 11289600; break; case 48000: set_max9485_clk(MAX9485_MCLK_FREQ_122880); clk = 12288000; break; case 88200: set_max9485_clk(MAX9485_MCLK_FREQ_225792); clk = 22579200; break; case 96000: set_max9485_clk(MAX9485_MCLK_FREQ_245760); clk = 24576000; break; default: return -EINVAL; } /* setup the CPU DAI */ ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1); if (ret < 0) return ret; return 0; } static struct snd_soc_ops raumfeld_ak4104_ops = { .hw_params = raumfeld_ak4104_hw_params, }; #define DAI_LINK_CS4270 \ { \ .name = "CS4270", \ .stream_name = "CS4270", \ .cpu_dai_name = "pxa-ssp-dai.0", \ .platform_name = "pxa-pcm-audio", \ .codec_dai_name = "cs4270-hifi", \ .codec_name = "cs4270.0-0048", \ .dai_fmt = SND_SOC_DAIFMT_I2S | \ SND_SOC_DAIFMT_NB_NF | \ SND_SOC_DAIFMT_CBS_CFS, \ .ops = &raumfeld_cs4270_ops, \ } #define DAI_LINK_AK4104 \ { \ .name = "ak4104", \ .stream_name = "Playback", \ .cpu_dai_name = "pxa-ssp-dai.1", \ .codec_dai_name = "ak4104-hifi", \ .platform_name = "pxa-pcm-audio", \ .dai_fmt = SND_SOC_DAIFMT_I2S | \ SND_SOC_DAIFMT_NB_NF | \ SND_SOC_DAIFMT_CBS_CFS, \ .ops = &raumfeld_ak4104_ops, \ .codec_name = "spi0.0", \ } static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = { DAI_LINK_CS4270, DAI_LINK_AK4104, }; static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = { DAI_LINK_CS4270, }; static struct snd_soc_card snd_soc_raumfeld_connector = { .name = "Raumfeld Connector", .owner = THIS_MODULE, .dai_link = snd_soc_raumfeld_connector_dai, .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai), .suspend_post = raumfeld_analog_suspend, .resume_pre = raumfeld_analog_resume, }; static struct snd_soc_card snd_soc_raumfeld_speaker = { .name = "Raumfeld Speaker", .owner = THIS_MODULE, .dai_link = snd_soc_raumfeld_speaker_dai, .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai), .suspend_post = raumfeld_analog_suspend, .resume_pre = raumfeld_analog_resume, }; static struct platform_device *raumfeld_audio_device; static int __init raumfeld_audio_init(void) { int ret; if (!machine_is_raumfeld_speaker() && !machine_is_raumfeld_connector()) return 0; max9486_client = i2c_new_device(i2c_get_adapter(0), &max9486_hwmon_info); if (!max9486_client) return -ENOMEM; set_max9485_clk(MAX9485_MCLK_FREQ_122880); /* Register analog device */ raumfeld_audio_device = platform_device_alloc("soc-audio", 0); if (!raumfeld_audio_device) return -ENOMEM; if (machine_is_raumfeld_speaker()) platform_set_drvdata(raumfeld_audio_device, &snd_soc_raumfeld_speaker); if (machine_is_raumfeld_connector()) platform_set_drvdata(raumfeld_audio_device, &snd_soc_raumfeld_connector); ret = platform_device_add(raumfeld_audio_device); if (ret < 0) { platform_device_put(raumfeld_audio_device); return ret; } raumfeld_enable_audio(true); return 0; } static void __exit raumfeld_audio_exit(void) { raumfeld_enable_audio(false); platform_device_unregister(raumfeld_audio_device); i2c_unregister_device(max9486_client); gpio_free(GPIO_MCLK_RESET); gpio_free(GPIO_CODEC_RESET); gpio_free(GPIO_SPDIF_RESET); } module_init(raumfeld_audio_init); module_exit(raumfeld_audio_exit); /* Module information */ MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("Raumfeld audio SoC"); MODULE_LICENSE("GPL"); ating Flattened Image Trees (.itb) - generic: Introduce generic DT-based board support - generic: Convert SEAD-3 to a generic board - Enable hardened usercopy - Don't specify STACKPROTECTOR in defconfigs Octeon: - Delete dead code and files across the platform. - Change to use all memory into use by default. - Rename upper case variables in setup code to lowercase. - Delete legacy hack for broken bootloaders. - Leave maintaining the link state to the actual ethernet/PHY drivers. - Add DTS for D-Link DSR-500N. - Fix PCI interrupt routing on D-Link DSR-500N. Pistachio: - Remove ANDROID_TIMED_OUTPUT from defconfig TX39xx: - Move GPIO setup from .mem_setup() to .arch_init() - Convert to Common Clock Framework TX49xx: - Move GPIO setup from .mem_setup() to .arch_init() - Convert to Common Clock Framework txx9wdt: - Add missing clock (un)prepare calls for CCF BMIPS: - Add PW, GPIO SDHCI and NAND device node names - Support APPENDED_DTB - Add missing bcm97435svmb to DT_NONE - Rename bcm96358nb4ser to bcm6358-neufbox4-sercom - Add DT examples for BCM63268, BCM3368 and BCM6362 - Add support for BCM3368 and BCM6362 PCI - Reduce stack frame usage - Use struct list_head lists - Support for CONFIG_PCI_DOMAINS_GENERIC - Make pcibios_set_cache_line_size an initcall - Inline pcibios_assign_all_busses - Split pci.c into pci.c & pci-legacy.c - Introduce CONFIG_PCI_DRIVERS_LEGACY - Support generic drivers CPC - Convert bare 'unsigned' to 'unsigned int' - Avoid lock when MIPS CM >= 3 is present GIC: - Delete unused file smp-gic.c mt7620: - Delete unnecessary assignment for the field "owner" from PCI BCM63xx: - Let clk_disable() return immediately if clk is NULL pm-cps: - Change FSB workaround to CPU blacklist - Update comments on barrier instructions - Use MIPS standard lightweight ordering barrier - Use MIPS standard completion barrier - Remove selection of sync types - Add MIPSr6 CPU support - Support CM3 changes to Coherence Enable Register SMP: - Wrap call to mips_cpc_lock_other in mips_cm_lock_other - Introduce mechanism for freeing and allocating IPIs cpuidle: - cpuidle-cps: Enable use with MIPSr6 CPUs. SEAD3: - Rewrite to use DT and generic kernel feature. USB: - host: ehci-sead3: Remove SEAD-3 EHCI code FBDEV: - cobalt_lcdfb: Drop SEAD3 support dt-bindings: - Document a binding for simple ASCII LCDs auxdisplay: - img-ascii-lcd: driver for simple ASCII LCD displays irqchip i8259: - i8259: Add domain before mapping parent irq - i8259: Allow platforms to override poll function - i8259: Remove unused i8259A_irq_pending Malta: - Rewrite to use DT of/platform: - Probe "isa" busses by default CM: - Print CM error reports upon bus errors Module: - Migrate exception table users off module.h and onto extable.h - Make various drivers explicitly non-modular: - Audit and remove any unnecessary uses of module.h mailmap: - Canonicalize to Qais' current email address. Documentation: - MIPS supports HAVE_REGS_AND_STACK_ACCESS_API Loongson1C: - Add CPU support for Loongson1C - Add board support - Add defconfig - Add RTC support for Loongson1C board All this except one Documentation fix has sat in linux-next and has survived Imagination's automated build test system" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (127 commits) Documentation: MIPS supports HAVE_REGS_AND_STACK_ACCESS_API MIPS: ptrace: Fix regs_return_value for kernel context MIPS: VDSO: Drop duplicated -I*/-E* aflags MIPS: Fix -mabi=64 build of vdso.lds MIPS: Enable hardened usercopy MIPS: generic: Convert SEAD-3 to a generic board MIPS: generic: Introduce generic DT-based board support MIPS: Support generating Flattened Image Trees (.itb) MIPS: Adjust MIPS64 CAC_BASE to reflect Config.K0 MIPS: Print CM error reports upon bus errors MIPS: Support per-device DMA coherence MIPS: dma-default: Don't check hw_coherentio if device is non-coherent MIPS: Sanitise coherentio semantics MIPS: PCI: Support generic drivers MIPS: PCI: Introduce CONFIG_PCI_DRIVERS_LEGACY MIPS: PCI: Split pci.c into pci.c & pci-legacy.c MIPS: PCI: Inline pcibios_assign_all_busses MIPS: PCI: Make pcibios_set_cache_line_size an initcall MIPS: PCI: Support for CONFIG_PCI_DOMAINS_GENERIC MIPS: PCI: Use struct list_head lists ...
Diffstat (limited to 'include/drm/drm_displayid.h')