cregit-Linux how code gets into the kernel

Release 4.7 sound/soc/pxa/raumfeld.c

Directory: sound/soc/pxa
/*
 * raumfeld_audio.c  --  SoC audio for Raumfeld audio devices
 *
 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
 *
 * based on code from:
 *
 *    Wolfson Microelectronics PLC.
 *    Openedhand Ltd.
 *    Liam Girdwood <lrg@slimlogic.co.uk>
 *    Richard Purdie <richard@openedhand.com>
 *
 * 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 <linux/module.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <sound/pcm.h>
#include <sound/soc.h>

#include <asm/mach-types.h>

#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); }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack19100.00%1100.00%
Total19100.00%1100.00%


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); } }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack66100.00%1100.00%
Total66100.00%1100.00%

/* 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); }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack42100.00%2100.00%
Total42100.00%2100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack41100.00%1100.00%
Total41100.00%1100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack212100.00%3100.00%
Total212100.00%3100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack1789.47%266.67%
mark brownmark brown210.53%133.33%
Total19100.00%3100.00%


static int raumfeld_analog_resume(struct snd_soc_card *card) { raumfeld_enable_audio(true); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack1789.47%266.67%
mark brownmark brown210.53%133.33%
Total19100.00%3100.00%

/* 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; }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack179100.00%3100.00%
Total179100.00%3100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack11791.41%250.00%
axel linaxel lin75.47%125.00%
liam girdwoodliam girdwood43.12%125.00%
Total128100.00%4100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack3897.44%150.00%
liam girdwoodliam girdwood12.56%150.00%
Total39100.00%2100.00%

module_init(raumfeld_audio_init); module_exit(raumfeld_audio_exit); /* Module information */ MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); MODULE_DESCRIPTION("Raumfeld audio SoC"); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
daniel mackdaniel mack97095.38%444.44%
liam girdwoodliam girdwood242.36%111.11%
axel linaxel lin171.67%222.22%
mark brownmark brown40.39%111.11%
lars-peter clausenlars-peter clausen20.20%111.11%
Total1017100.00%9100.00%
Directory: sound/soc/pxa
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}