144 lines
3.8 KiB
C
144 lines
3.8 KiB
C
/*
|
|
* qca-cus227.c -- ALSA machine code for CUS227 board ref design (and relatives)
|
|
*
|
|
* Copyright (c) 2013 The Linux Foundation. All rights reserved.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include <asm/delay.h>
|
|
#include <linux/types.h>
|
|
#include <sound/core.h>
|
|
#include <sound/soc.h>
|
|
#include <linux/module.h>
|
|
|
|
/* Driver include */
|
|
#include <asm/mach-ath79/ar71xx_regs.h>
|
|
#include <asm/mach-ath79/ath79.h>
|
|
#include "ath79-i2s.h"
|
|
#include "ath79-pcm.h"
|
|
#include "../codecs/wm8988.h"
|
|
|
|
static struct platform_device *cus227_snd_device;
|
|
|
|
static int cus227_hifi_hw_params(struct snd_pcm_substream *ss,
|
|
struct snd_pcm_hw_params *params)
|
|
{
|
|
struct snd_soc_pcm_runtime *rtd = ss->private_data;
|
|
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
|
struct snd_soc_codec *codec = rtd->codec;
|
|
unsigned int clk = 0;
|
|
int ret;
|
|
u16 vol_reg;
|
|
switch (params_rate(params)) {
|
|
case 8000:
|
|
case 16000:
|
|
case 32000:
|
|
case 48000:
|
|
case 96000:
|
|
clk = 12288000;
|
|
break;
|
|
case 11025:
|
|
case 22050:
|
|
case 44100:
|
|
case 88200:
|
|
clk = 11289600;
|
|
break;
|
|
}
|
|
|
|
/* set the codec system clock for DAC and ADC */
|
|
ret = snd_soc_dai_set_sysclk(codec_dai, WM8988_SYSCLK, clk,
|
|
SND_SOC_CLOCK_OUT);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if (ss->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
|
/*Disable Left&Right Channel Input Analogue Mute,
|
|
* and wm8988 datasheet says we should also set bit8
|
|
* for WM8988_LINVOL&WM8988_RINVOL concurrently.*/
|
|
vol_reg = snd_soc_read(codec, WM8988_LINVOL) & 0x7f;
|
|
snd_soc_write(codec, WM8988_LINVOL, 0x100 | vol_reg);
|
|
vol_reg = snd_soc_read(codec, WM8988_RINVOL) & 0x7f;
|
|
snd_soc_write(codec, WM8988_RINVOL, 0x100 | vol_reg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int cus227_late_probe(struct snd_soc_card *card)
|
|
{
|
|
struct snd_soc_dai *codec_dai = card->rtd->codec_dai;
|
|
int ret;
|
|
|
|
ret = snd_soc_dai_set_sysclk(codec_dai, WM8988_SYSCLK,
|
|
11289600, SND_SOC_CLOCK_OUT);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct snd_soc_ops cus227_dai_ops = {
|
|
.hw_params = cus227_hifi_hw_params,
|
|
};
|
|
|
|
static struct snd_soc_dai_link cus227_dai = {
|
|
.name = "CUS227 audio",
|
|
.stream_name = "CUS227 audio",
|
|
.cpu_dai_name = "ath79-i2s",
|
|
.codec_dai_name = "wm8988-hifi",
|
|
.platform_name = "ath79-pcm-audio",
|
|
.codec_name = "spi0.1",
|
|
/* use ops to check startup state */
|
|
.ops = &cus227_dai_ops,
|
|
};
|
|
|
|
static struct snd_soc_card snd_soc_cus227 = {
|
|
.name = "QCA CUS227",
|
|
.long_name = "CUS227 - ath79-pcm/ath79-i2s/wm8988",
|
|
.dai_link = &cus227_dai,
|
|
.num_links = 1,
|
|
|
|
.late_probe = cus227_late_probe,
|
|
};
|
|
|
|
static int __init cus227_init(void)
|
|
{
|
|
int ret;
|
|
|
|
cus227_snd_device = platform_device_alloc("soc-audio", -1);
|
|
if(!cus227_snd_device)
|
|
return -ENOMEM;
|
|
|
|
platform_set_drvdata(cus227_snd_device, &snd_soc_cus227);
|
|
ret = platform_device_add(cus227_snd_device);
|
|
|
|
if (ret) {
|
|
platform_device_put(cus227_snd_device);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void __exit cus227_exit(void)
|
|
{
|
|
platform_device_unregister(cus227_snd_device);
|
|
}
|
|
|
|
module_init(cus227_init);
|
|
module_exit(cus227_exit);
|
|
|
|
MODULE_AUTHOR("Qualcomm-Atheros Inc.");
|
|
MODULE_AUTHOR("Mathieu Olivari <mathieu@qca.qualcomm.com>");
|
|
MODULE_DESCRIPTION("QCA Audio Machine module");
|
|
MODULE_LICENSE("Dual BSD/GPL");
|