Revert "odroid-c:hdmi spdif audio output 2-ch fixed."

This reverts commit eccdca38c95e50dc61f4669e94e94b8ba44e78a5.

Conflicts:
	arch/arm/boot/dts/amlogic/meson8b_odroidc.dtd

Change-Id: I5d4a4e753e5b602742ec28ccc2b2d8aea8ce9b46
This commit is contained in:
Mauro Ribeiro
2014-12-08 22:18:56 -02:00
committed by Dongjin Kim
parent dd9a6d2fad
commit 81bc0002ee
8 changed files with 628 additions and 523 deletions

View File

@@ -1410,12 +1410,23 @@ void root_func(){
amlogic,pins="GPIOAO_7";
};
//$$ MATCH "Audio_pin_0_match" = "&audio_spdif_pins"
//$$ L2 PROP_U32 2 = "amlogic,setmask"
//$$ L2 PROP_U32 2 = "amlogic,clrmask"
//$$ L2 PROP_STR 1 = "amlogic,pins"
audio_spdif_pins:audio_pin1{
amlogic,setmask=<10 0x8>; /*spdif_out*/
amlogic,clrmask=<10 0x80002000>; /*spdif_out*/
amlogic,pins ="GPIOAO_6"; /*spdif_out*/
};
//$$ MATCH "Audio_pin_0_match" = "&audio_pins"
//$$ L2 PROP_U32 4 = "amlogic,setmask"
//$$ L2 PROP_U32 10 = "amlogic,clrmask"
//$$ L2 PROP_STR 6 = "amlogic,pins"
audio_pins:audio_pin{
amlogic,setmask=<10 0x78000000>;
amlogic,setmask=<10 0x78000008>;
amlogic,clrmask=<10 0x80002000>;
amlogic,pins = "GPIOAO_8","GPIOAO_9","GPIOAO_10","GPIOAO_11";
};

View File

@@ -236,10 +236,8 @@ void audio_set_aiubuf(u32 addr, u32 size, unsigned int channel)
audio_out_buf_ready = 1;
}
void audio_set_958outbuf(u32 addr, u32 size, int channels, int flag)
void audio_set_958outbuf(u32 addr, u32 size,int flag)
{
u8 chanmask;
if (ENABLE_IEC958) {
WRITE_MPEG_REG(AIU_MEM_IEC958_START_PTR, addr & 0xffffffc0);
if(READ_MPEG_REG(AIU_MEM_IEC958_START_PTR) == READ_MPEG_REG(AIU_MEM_I2S_START_PTR)){
@@ -252,8 +250,7 @@ void audio_set_958outbuf(u32 addr, u32 size, int channels, int flag)
}else{
WRITE_MPEG_REG(AIU_MEM_IEC958_END_PTR, (addr & 0xffffffc0) + (size & 0xffffffc0) - 1); // this is for RAW mode
}
chanmask = (1 << channels) - 1;
WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_MASKS, chanmask << 8 | chanmask, 0, 16);
WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_MASKS, 0x303, 0, 16);
WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 0, 1);
WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 0, 1);

View File

@@ -105,7 +105,7 @@ extern unsigned IEC958_MODE;
extern unsigned I2S_MODE;
void audio_set_aiubuf(u32 addr, u32 size, unsigned int channel);
void audio_set_958outbuf(u32 addr, u32 size, int channels, int flag);
void audio_set_958outbuf(u32 addr, u32 size, int flag);
void audio_in_i2s_set_buf(u32 addr, u32 size,u32 i2s_mode, u32 i2s_sync);
void audio_in_spdif_set_buf(u32 addr, u32 size);
void audio_in_i2s_enable(int flag);

187
sound/soc/aml/m8/aml_i2s.c Normal file → Executable file
View File

@@ -81,22 +81,22 @@ EXPORT_SYMBOL(aml_i2s_alsa_write_addr);
* them against real values for AML
*/
static const struct snd_pcm_hardware aml_i2s_hardware = {
.info = SNDRV_PCM_INFO_NONINTERLEAVED|
.info = SNDRV_PCM_INFO_INTERLEAVED|
SNDRV_PCM_INFO_BLOCK_TRANSFER|
SNDRV_PCM_INFO_PAUSE,
.formats = SNDRV_PCM_FMTBIT_S16_LE|SNDRV_PCM_FMTBIT_S24_LE|SNDRV_PCM_FMTBIT_S32_LE,
.period_bytes_min = 64,
.period_bytes_max = 32 * 1024,
.period_bytes_max = 32 * 1024*2,
.periods_min = 2,
.periods_max = 1024,
.buffer_bytes_max = 32 * 1024*2,
.buffer_bytes_max = 128 * 1024*2*2,
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
.channels_min = 2,
.channels_max = 8,
.fifo_size = 0,
};
@@ -116,8 +116,8 @@ static const struct snd_pcm_hardware aml_i2s_capture = {
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
.channels_min = 2,
.channels_max = 8,
.fifo_size = 0,
};
@@ -598,49 +598,123 @@ static int aml_i2s_copy_playback(struct snd_pcm_runtime *runtime, int channel,
snd_pcm_uframes_t pos,
void __user *buf, snd_pcm_uframes_t count, struct snd_pcm_substream *substream)
{
int i;
unsigned char __user *ubuf = (unsigned char __user *) buf;
int datasize = frames_to_bytes(runtime, count);
int pos_offset = frames_to_bytes(runtime, pos);
unsigned char *hwbuf = runtime->dma_area;
int to_copy = datasize;
int res = 0;
int n;
int i = 0, j = 0;
int align = runtime->channels * 32 / runtime->byte_align;
char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, pos);
struct aml_runtime_data *prtd = runtime->private_data;
struct snd_dma_buffer *buffer = &substream->dma_buffer;
struct aml_audio_buffer *tmp_buf = buffer->private_data;
void *ubuf = tmp_buf->buffer_start;
audio_stream_t *s = &prtd->s;
if(s->device_type == AML_AUDIO_I2SOUT){
aml_i2s_alsa_write_addr = frames_to_bytes(runtime, pos);
}
n = frames_to_bytes(runtime, count);
if(aml_i2s_playback_enable == 0 && s->device_type == AML_AUDIO_I2SOUT)
return res;
res = copy_from_user(ubuf, buf, n);
if (res) return -EFAULT;
if(access_ok(VERIFY_READ, buf, frames_to_bytes(runtime, count)))
{
if(runtime->format == SNDRV_PCM_FORMAT_S16_LE ){
int16_t * tfrom, *to, *left, *right;
tfrom = (int16_t*)ubuf;
to = (int16_t*)hwbuf;
/* Distance between starting byte for each block */
int blockgap = runtime->channels * 32;
left = to;
right = to + 16;
if (pos % align) {
printk("audio data unligned: pos=%d, n=%d, align=%d\n", (int)pos, n, align);
}
for (j = 0; j < n; j += 64) {
for (i = 0; i < 16; i++) {
*left++ = (*tfrom++) ;
*right++ = (*tfrom++);
}
left += 16;
right += 16;
}
}else if(runtime->format == SNDRV_PCM_FORMAT_S24_LE && I2S_MODE == AIU_I2S_MODE_PCM24){
int32_t *tfrom, *to, *left, *right;
tfrom = (int32_t*)ubuf;
to = (int32_t*) hwbuf;
/* FIXME: here I would have thought that we should convert the 'pos'
* hardware offset into the right block number as follows. However,
* that results in the sound output being choppy and partially
* repeated. Instead, just using simple bytes arithmetic seems to
* land us in the right place for the correct audible output,
* but how does it happen? This isn't considering the channels, is it?
* Is it somehow related to the pointer being read?
*/
#if 0
int blockno = pos_offset / 32;
left = to;
right = to + 8;
hwbuf += blockno * blockgap;
hwbuf += channel * 32;
#else
hwbuf += pos_offset;
if (channel == 1) hwbuf += 32;
#endif
if(pos % align){
printk("audio data unaligned: pos=%d, n=%d, align=%d\n", (int)pos, n, align);
}
for(j=0; j< n; j+= 64){
for(i=0; i<8; i++){
*left++ = (*tfrom ++);
*right++ = (*tfrom ++);
}
left += 8;
right += 8;
}
if (runtime->channels == 1) {
if (copy_from_user(hwbuf, buf, datasize))
return -EFAULT;
return 0;
}else if(runtime->format == SNDRV_PCM_FORMAT_S32_LE /*&& I2S_MODE == AIU_I2S_MODE_PCM32*/){
int32_t *tfrom, *to, *left, *right;
tfrom = (int32_t*)ubuf;
to = (int32_t*) hwbuf;
left = to;
right = to + 8;
if(pos % align){
printk("audio data unaligned: pos=%d, n=%d, align=%d\n", (int)pos, n, align);
}
if(runtime->channels == 8){
int32_t *lf, *cf, *rf, *ls, *rs, *lef, *sbl, *sbr;
lf = to;
cf = to + 8*1;
rf = to + 8*2;
ls = to + 8*3;
rs = to + 8*4;
lef = to + 8*5;
sbl = to + 8*6;
sbr = to + 8*7;
for (j = 0; j < n; j += 256) {
for (i = 0; i < 8; i++) {
*lf++ = (*tfrom ++)>>8;
*cf++ = (*tfrom ++)>>8;
*rf++ = (*tfrom ++)>>8;
*ls++ = (*tfrom ++)>>8;
*rs++ = (*tfrom ++)>>8;
*lef++ = (*tfrom ++)>>8;
*sbl++ = (*tfrom ++)>>8;
*sbr++ = (*tfrom ++)>>8;
}
lf += 7*8;
cf += 7*8;
rf += 7*8;
ls += 7*8;
rs += 7*8;
lef += 7*8;
sbl += 7*8;
sbr += 7*8;
}
}
else {
for(j=0; j< n; j+= 64){
for(i=0; i<8; i++){
*left++ = (*tfrom ++)>>8;
*right++ = (*tfrom ++)>>8;
}
left += 8;
right += 8;
}
}
}
}else{
res = -EFAULT;
}
for (i = 0; i < datasize; i += 32) {
int copysize = min(32, to_copy);
if (copy_from_user(hwbuf, ubuf + i, copysize))
return -EFAULT;
to_copy -= copysize;
hwbuf += blockgap;
}
return 0;
return res;
}
static unsigned int aml_get_in_wr_ptr(void){
@@ -724,22 +798,15 @@ static int aml_i2s_copy(struct snd_pcm_substream *substream, int channel,
int aml_i2s_silence(struct snd_pcm_substream *substream, int channel,
snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
{
struct snd_pcm_runtime *runtime = substream->runtime;
int i;
int datasize = frames_to_bytes(runtime, count);
int pos_offset = frames_to_bytes(runtime, pos);
char *hwbuf = runtime->dma_area;
int to_copy = datasize;
int blockgap = runtime->channels * 32;
char* ppos;
int n;
struct snd_pcm_runtime *runtime = substream->runtime;
ALSA_TRACE();
/* FIXME: same blocking consideration as copy_playback */
hwbuf += pos_offset;
for (i = 0; i < to_copy; i += 32) {
memset(hwbuf, 0, 32);
hwbuf += blockgap;
}
return 0;
n = frames_to_bytes(runtime, count);
ppos = runtime->dma_area + frames_to_bytes(runtime, pos);
memset(ppos, 0, n);
return 0;
}
static struct snd_pcm_ops aml_i2s_ops = {

View File

@@ -300,12 +300,12 @@ struct snd_soc_dai_driver aml_i2s_dai[] = {
.resume = aml_dai_i2s_resume,
.playback = {
.channels_min = 1,
.channels_max = 2,
.channels_max = 8,
.rates = AML_DAI_I2S_RATES,
.formats = AML_DAI_I2S_FORMATS,},
.capture = {
.channels_min = 1,
.channels_max = 2,
.channels_max = 8,
.rates = AML_DAI_I2S_RATES,
.formats = AML_DAI_I2S_FORMATS,},
.ops = &aml_dai_i2s_ops,

40
sound/soc/aml/m8/aml_spdif_codec.c Normal file → Executable file
View File

@@ -26,7 +26,7 @@
#define DRV_NAME "spdif-dit"
#define STUB_RATES SNDRV_PCM_RATE_8000_192000
#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE
static struct snd_soc_codec_driver soc_codec_spdif_dit;
@@ -38,14 +38,14 @@ static struct snd_soc_dai_driver dit_stub_dai = {
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
.channels_max = 8,
.rates = STUB_RATES,
.formats = STUB_FORMATS,
},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 2,
.channels_max = 8,
.rates = STUB_RATES,
.formats = STUB_FORMATS,
},
@@ -57,6 +57,11 @@ void aml_spdif_pinmux_init(struct device *dev)
printk(KERN_INFO"aml_spdif_unmute \n");
if(!spdif_pinmux){
spdif_pinmux = 1;
pin_spdif_ctl = devm_pinctrl_get_select(dev, "aml_audio_spdif");
if (IS_ERR(pin_spdif_ctl)){
pin_spdif_ctl = NULL;
printk("aml_spdif_pinmux_init can't get pinctrl \n");
}
}
}
@@ -65,12 +70,38 @@ void aml_spdif_pinmux_deinit(struct device *dev)
printk(KERN_INFO"aml_spdif_mute \n");
if(spdif_pinmux){
spdif_pinmux = 0;
if(pin_spdif_ctl)
devm_pinctrl_put(pin_spdif_ctl);
}
}
static ssize_t spdif_mute_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
if(spdif_pinmux){
return sprintf(buf, "spdif_unmute\n");
}else{
return sprintf(buf, "spdif_mute\n");
}
}
static ssize_t spdif_mute_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
if(strncmp(buf,"spdif_mute",10)){
aml_spdif_pinmux_init(dev);
}else if(strncmp(buf,"spdif_unmute",12)){
aml_spdif_pinmux_deinit(dev);
}else{
printk("spdif set the wrong value\n");
}
return count;
}
static DEVICE_ATTR(spdif_mute, 0660, spdif_mute_show, spdif_mute_set);
static int spdif_dit_probe(struct platform_device *pdev)
{
int ret=0;
int ret = device_create_file(&pdev->dev, &dev_attr_spdif_mute);
printk("enter spdif_dit_probe \n");
spdif_dev = &pdev->dev;
@@ -83,6 +114,7 @@ static int spdif_dit_probe(struct platform_device *pdev)
static int spdif_dit_remove(struct platform_device *pdev)
{
aml_spdif_pinmux_deinit(&pdev->dev);
device_remove_file(&pdev->dev, &dev_attr_spdif_mute);
snd_soc_unregister_codec(&pdev->dev);
return 0;
}

894
sound/soc/aml/m8/aml_spdif_dai.c Normal file → Executable file
View File

@@ -1,8 +1,8 @@
/*
Amlogic S/PDIF(HDMI) Soc dai driver
author:jian.xu@amlogic.com
*/
#include <linux/module.h>
/*
Amlogic S/PDIF(HDMI) Soc dai driver
author:jian.xu@amlogic.com
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/init.h>
@@ -21,120 +21,118 @@
#include <sound/initval.h>
#include <sound/control.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <sound/pcm_params.h>
#include <mach/am_regs.h>
#include <mach/pinmux.h>
#include "aml_audio_hw.h"
#include "aml_spdif_dai.h"
#include "aml_i2s.h"
#include <linux/of.h>
//#define DEBUG_ALSA_SPDIF_DAI
#define ALSA_PRINT(fmt,args...) printk(KERN_INFO "[aml-spdif-dai]" fmt,##args)
#ifdef DEBUG_ALSA_SPDIF_DAI
#define ALSA_DEBUG(fmt,args...) printk(KERN_INFO "[aml-spdif-dai]" fmt,##args)
#define ALSA_TRACE() printk("[aml-spdif-dai] enter func %s,line %d\n",__FUNCTION__,__LINE__)
#include <mach/pinmux.h>
#include "aml_audio_hw.h"
#include "aml_spdif_dai.h"
#include "aml_i2s.h"
#include <linux/of.h>
//#define DEBUG_ALSA_SPDIF_DAI
#define ALSA_PRINT(fmt,args...) printk(KERN_INFO "[aml-spdif-dai]" fmt,##args)
#ifdef DEBUG_ALSA_SPDIF_DAI
#define ALSA_DEBUG(fmt,args...) printk(KERN_INFO "[aml-spdif-dai]" fmt,##args)
#define ALSA_TRACE() printk("[aml-spdif-dai] enter func %s,line %d\n",__FUNCTION__,__LINE__)
#else
#define ALSA_DEBUG(fmt,args...)
#define ALSA_TRACE()
#endif
static unsigned last_iec_clock = -1;
extern int aout_notifier_call_chain(unsigned long val, void *v);
//static unsigned playback_substream_handle = 0 ;
extern unsigned int IEC958_mode_codec;
//static int iec958buf[32+16];
void aml_spdif_play(void)
{
return;
#endif
static unsigned last_iec_clock = -1;
extern int aout_notifier_call_chain(unsigned long val, void *v);
//static unsigned playback_substream_handle = 0 ;
extern unsigned int IEC958_mode_codec;
//static int iec958buf[32+16];
void aml_spdif_play(void)
{
return;
#if 0
_aiu_958_raw_setting_t set;
_aiu_958_channel_status_t chstat;
struct snd_pcm_substream substream;
struct snd_pcm_runtime runtime;
substream.runtime = & runtime;
runtime.rate = 48000;
runtime.format = SNDRV_PCM_FORMAT_S16_LE;
runtime.channels = 2;
runtime.sample_bits = 16;
memset((void*)(&set), 0, sizeof(set));
memset((void*)(&chstat), 0, sizeof(chstat));
set.chan_stat = &chstat;
set.chan_stat->chstat0_l = 0x0100;
set.chan_stat->chstat0_r = 0x0100;
set.chan_stat->chstat1_l = 0X200;
set.chan_stat->chstat1_r = 0X200;
audio_hw_958_enable(0);
if(last_iec_clock != AUDIO_CLK_FREQ_48){
ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n",__func__,last_iec_clock,AUDIO_CLK_FREQ_48);
last_iec_clock = AUDIO_CLK_FREQ_48;
audio_set_958_clk(AUDIO_CLK_FREQ_48,AUDIO_CLK_256FS);
}
audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
memset(iec958buf,0,sizeof(iec958buf));
audio_set_958outbuf((virt_to_phys(iec958buf)+63)&(~63),128,2,0); //128 bytes as dma buffer
audio_set_958_mode(AIU_958_MODE_PCM16, &set);
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);//512fs divide 4 == 128fs
#else
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2); //256fs divide 2 == 128fs
_aiu_958_raw_setting_t set;
_aiu_958_channel_status_t chstat;
struct snd_pcm_substream substream;
struct snd_pcm_runtime runtime;
substream.runtime = & runtime;
runtime.rate = 48000;
runtime.format = SNDRV_PCM_FORMAT_S16_LE;
runtime.channels = 2;
runtime.sample_bits = 16;
memset((void*)(&set), 0, sizeof(set));
memset((void*)(&chstat), 0, sizeof(chstat));
set.chan_stat = &chstat;
set.chan_stat->chstat0_l = 0x0100;
set.chan_stat->chstat0_r = 0x0100;
set.chan_stat->chstat1_l = 0X200;
set.chan_stat->chstat1_r = 0X200;
audio_hw_958_enable(0);
if(last_iec_clock != AUDIO_CLK_FREQ_48){
ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n",__func__,last_iec_clock,AUDIO_CLK_FREQ_48);
last_iec_clock = AUDIO_CLK_FREQ_48;
audio_set_958_clk(AUDIO_CLK_FREQ_48,AUDIO_CLK_256FS);
}
audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
memset(iec958buf,0,sizeof(iec958buf));
audio_set_958outbuf((virt_to_phys(iec958buf)+63)&(~63),128,0); //128 bytes as dma buffer
audio_set_958_mode(AIU_958_MODE_PCM16, &set);
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);//512fs divide 4 == 128fs
#else
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2); //256fs divide 2 == 128fs
#endif
aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,&substream);
audio_spdifout_pg_enable(1);
audio_hw_958_enable(1);
aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,&substream);
audio_spdifout_pg_enable(1);
audio_hw_958_enable(1);
#endif
}
static void aml_spdif_play_stop(void)
{
audio_hw_958_enable(0);
}
static int aml_dai_spdif_set_sysclk(struct snd_soc_dai *cpu_dai,
#endif
}
static void aml_spdif_play_stop(void)
{
audio_hw_958_enable(0);
}
{
ALSA_TRACE();
return 0;
static int aml_dai_spdif_set_sysclk(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
{
ALSA_TRACE();
return 0;
static int aml_dai_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
}
{
struct snd_soc_pcm_runtime *rtd = NULL;
ALSA_TRACE();
rtd = (struct snd_soc_pcm_runtime *)substream->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
ALSA_PRINT("aiu 958 playback enable\n");
audio_hw_958_enable(1);
}
else{
ALSA_PRINT("spdif in capture enable\n");
audio_in_spdif_enable(1);
}
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
ALSA_PRINT("aiu 958 playback disable \n");
audio_hw_958_enable(0);
}
else{
ALSA_PRINT("spdif in capture disable\n");
audio_in_spdif_enable(0);
}
break;
default:
return -EINVAL;
static int aml_dai_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = NULL;
ALSA_TRACE();
rtd = (struct snd_soc_pcm_runtime *)substream->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
ALSA_PRINT("aiu 958 playback enable\n");
audio_hw_958_enable(1);
}
else{
ALSA_PRINT("spdif in capture enable\n");
audio_in_spdif_enable(1);
}
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
ALSA_PRINT("aiu 958 playback disable \n");
audio_hw_958_enable(0);
}
else{
ALSA_PRINT("spdif in capture disable\n");
audio_in_spdif_enable(0);
}
break;
default:
return -EINVAL;
}
@@ -145,181 +143,181 @@ special call by the audiodsp,add these code,as there are three cases for 958 s/p
special call by the audiodsp,add these code,as there are three cases for 958 s/pdif output
1)NONE-PCM raw output ,only available when ac3/dts audio,when raw output mode is selected by user.
2)PCM output for all audio, when pcm mode is selected by user .
static void aml_hw_iec958_init(struct snd_pcm_substream *substream)
{
_aiu_958_raw_setting_t set;
_aiu_958_channel_status_t chstat;
unsigned i2s_mode,iec958_mode;
unsigned start,size;
int sample_rate;
struct snd_dma_buffer *buf = &substream->dma_buffer;
struct snd_pcm_runtime *runtime = substream->runtime;
if(buf==NULL && runtime==NULL){
printk("buf/0x%x runtime/0x%x\n",(unsigned )buf,(unsigned )runtime);
return;
}
i2s_mode = AIU_I2S_MODE_PCM16;
sample_rate = AUDIO_CLK_FREQ_48;
memset((void*)(&set), 0, sizeof(set));
memset((void*)(&chstat), 0, sizeof(chstat));
set.chan_stat = &chstat;
printk("----aml_hw_iec958_init,runtime->rate=%d--\n",runtime->rate);
switch(runtime->rate){
case 192000:
sample_rate = AUDIO_CLK_FREQ_192;
break;
case 176400:
sample_rate = AUDIO_CLK_FREQ_1764;
break;
case 96000:
sample_rate = AUDIO_CLK_FREQ_96;
break;
case 88200:
sample_rate = AUDIO_CLK_FREQ_882;
break;
case 48000:
sample_rate = AUDIO_CLK_FREQ_48;
break;
case 44100:
sample_rate = AUDIO_CLK_FREQ_441;
break;
case 32000:
sample_rate = AUDIO_CLK_FREQ_32;
break;
case 8000:
sample_rate = AUDIO_CLK_FREQ_8;
break;
case 11025:
sample_rate = AUDIO_CLK_FREQ_11;
break;
case 16000:
sample_rate = AUDIO_CLK_FREQ_16;
break;
case 22050:
sample_rate = AUDIO_CLK_FREQ_22;
break;
case 12000:
sample_rate = AUDIO_CLK_FREQ_12;
break;
case 24000:
sample_rate = AUDIO_CLK_FREQ_22;
break;
default:
sample_rate = AUDIO_CLK_FREQ_441;
break;
};
if(last_iec_clock != sample_rate){
ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n",__func__,last_iec_clock,sample_rate);
last_iec_clock = sample_rate;
audio_set_958_clk(sample_rate, AUDIO_CLK_256FS);
}
printk("----aml_hw_iec958_init,runtime->rate=%d,sample_rate=%d--\n",runtime->rate,sample_rate);
audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
switch(runtime->format){
case SNDRV_PCM_FORMAT_S32_LE:
i2s_mode = AIU_I2S_MODE_PCM32;
break;
case SNDRV_PCM_FORMAT_S24_LE:
i2s_mode = AIU_I2S_MODE_PCM24;
break;
case SNDRV_PCM_FORMAT_S16_LE:
i2s_mode = AIU_I2S_MODE_PCM16;
break;
}
//audio_set_i2s_mode(i2s_mode);
/* case 1,raw mode enabled */
if(IEC958_mode_codec){
if(IEC958_mode_codec == 1){ //dts, use raw sync-word mode
iec958_mode = AIU_958_MODE_RAW;
printk("iec958 mode RAW\n");
}
else{ //ac3,use the same pcm mode as i2s configuration
iec958_mode = AIU_958_MODE_PCM_RAW;
printk("iec958 mode %s\n",(i2s_mode == AIU_I2S_MODE_PCM32)?"PCM32_RAW":((I2S_MODE == AIU_I2S_MODE_PCM24)?"PCM24_RAW":"PCM16_RAW"));
}
}
else{
if(i2s_mode == AIU_I2S_MODE_PCM32)
iec958_mode = AIU_958_MODE_PCM32;
else if(i2s_mode == AIU_I2S_MODE_PCM24)
iec958_mode = AIU_958_MODE_PCM24;
else
iec958_mode = AIU_958_MODE_PCM16;
printk("iec958 mode %s\n",(i2s_mode == AIU_I2S_MODE_PCM32)?"PCM32":((i2s_mode == AIU_I2S_MODE_PCM24)?"PCM24":"PCM16"));
}
if(iec958_mode == AIU_958_MODE_PCM16 || iec958_mode == AIU_958_MODE_PCM24 ||
iec958_mode == AIU_958_MODE_PCM32){
set.chan_stat->chstat0_l = 0x0100;
set.chan_stat->chstat0_r = 0x0100;
set.chan_stat->chstat1_l = 0x200;
set.chan_stat->chstat1_r = 0x200;
if(sample_rate==AUDIO_CLK_FREQ_882){
printk("----sample_rate==AUDIO_CLK_FREQ_882---\n");
set.chan_stat->chstat1_l = 0x800;
set.chan_stat->chstat1_r = 0x800;
}
if(sample_rate==AUDIO_CLK_FREQ_96){
printk("----sample_rate==AUDIO_CLK_FREQ_96---\n");
set.chan_stat->chstat1_l = 0xa00;
set.chan_stat->chstat1_r = 0xa00;
}
start = buf->addr;
size = snd_pcm_lib_buffer_bytes(substream);
audio_set_958outbuf(start, size, runtime->channels, 0);
//audio_set_i2s_mode(AIU_I2S_MODE_PCM16);
//audio_set_aiubuf(start, size);
}else{
set.chan_stat->chstat0_l = 0x1902;
set.chan_stat->chstat0_r = 0x1902;
if(IEC958_mode_codec == 4 || IEC958_mode_codec == 5){ //DD+
if(runtime->rate == 32000){
set.chan_stat->chstat1_l = 0x300;
set.chan_stat->chstat1_r = 0x300;
}
else if(runtime->rate == 44100){
set.chan_stat->chstat1_l = 0xc00;
set.chan_stat->chstat1_r = 0xc00;
}
else{
set.chan_stat->chstat1_l = 0Xe00;
set.chan_stat->chstat1_r = 0Xe00;
}
}
else{ //DTS,DD
if(runtime->rate == 32000){
set.chan_stat->chstat1_l = 0x300;
set.chan_stat->chstat1_r = 0x300;
}
else if(runtime->rate == 44100){
set.chan_stat->chstat1_l = 0;
set.chan_stat->chstat1_r = 0;
}
else{
set.chan_stat->chstat1_l = 0x200;
set.chan_stat->chstat1_r = 0x200;
}
}
start = buf->addr;
size = snd_pcm_lib_buffer_bytes(substream);;
audio_set_958outbuf(start, size, runtime->channels, (iec958_mode == AIU_958_MODE_RAW)?1:0);
memset((void*)buf->area,0,size);
}
ALSA_DEBUG("aiu 958 pcm buffer size %d \n",size);
audio_set_958_mode(iec958_mode, &set);
if(IEC958_mode_codec == 4 || IEC958_mode_codec == 5 || IEC958_mode_codec == 7){ //dd+
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 4, 2); // 4x than i2s
printk("DEBUG--> IEC958_mode_codec/%d 4x than i2s\n",IEC958_mode_codec);
}else
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);//512fs divide 4 == 128fs
#else
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2); //256fs divide 2 == 128fs
#endif
3)PCM output for audios except ac3/dts,when raw output mode is selected by user
*/
static void aml_hw_iec958_init(struct snd_pcm_substream *substream)
{
_aiu_958_raw_setting_t set;
_aiu_958_channel_status_t chstat;
unsigned i2s_mode,iec958_mode;
unsigned start,size;
int sample_rate;
struct snd_dma_buffer *buf = &substream->dma_buffer;
struct snd_pcm_runtime *runtime = substream->runtime;
if(buf==NULL && runtime==NULL){
printk("buf/0x%x runtime/0x%x\n",(unsigned )buf,(unsigned )runtime);
return;
}
i2s_mode = AIU_I2S_MODE_PCM16;
sample_rate = AUDIO_CLK_FREQ_48;
memset((void*)(&set), 0, sizeof(set));
memset((void*)(&chstat), 0, sizeof(chstat));
set.chan_stat = &chstat;
printk("----aml_hw_iec958_init,runtime->rate=%d--\n",runtime->rate);
switch(runtime->rate){
case 192000:
sample_rate = AUDIO_CLK_FREQ_192;
break;
case 176400:
sample_rate = AUDIO_CLK_FREQ_1764;
break;
case 96000:
sample_rate = AUDIO_CLK_FREQ_96;
break;
case 88200:
sample_rate = AUDIO_CLK_FREQ_882;
break;
case 48000:
sample_rate = AUDIO_CLK_FREQ_48;
break;
case 44100:
sample_rate = AUDIO_CLK_FREQ_441;
break;
case 32000:
sample_rate = AUDIO_CLK_FREQ_32;
break;
case 8000:
sample_rate = AUDIO_CLK_FREQ_8;
break;
case 11025:
sample_rate = AUDIO_CLK_FREQ_11;
break;
case 16000:
sample_rate = AUDIO_CLK_FREQ_16;
break;
case 22050:
sample_rate = AUDIO_CLK_FREQ_22;
break;
case 12000:
sample_rate = AUDIO_CLK_FREQ_12;
break;
case 24000:
sample_rate = AUDIO_CLK_FREQ_22;
break;
default:
sample_rate = AUDIO_CLK_FREQ_441;
break;
};
if(last_iec_clock != sample_rate){
ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n",__func__,last_iec_clock,sample_rate);
last_iec_clock = sample_rate;
audio_set_958_clk(sample_rate, AUDIO_CLK_256FS);
}
printk("----aml_hw_iec958_init,runtime->rate=%d,sample_rate=%d--\n",runtime->rate,sample_rate);
audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
switch(runtime->format){
case SNDRV_PCM_FORMAT_S32_LE:
i2s_mode = AIU_I2S_MODE_PCM32;
break;
case SNDRV_PCM_FORMAT_S24_LE:
i2s_mode = AIU_I2S_MODE_PCM24;
break;
case SNDRV_PCM_FORMAT_S16_LE:
i2s_mode = AIU_I2S_MODE_PCM16;
break;
}
//audio_set_i2s_mode(i2s_mode);
/* case 1,raw mode enabled */
if(IEC958_mode_codec){
if(IEC958_mode_codec == 1){ //dts, use raw sync-word mode
iec958_mode = AIU_958_MODE_RAW;
printk("iec958 mode RAW\n");
}
else{ //ac3,use the same pcm mode as i2s configuration
iec958_mode = AIU_958_MODE_PCM_RAW;
printk("iec958 mode %s\n",(i2s_mode == AIU_I2S_MODE_PCM32)?"PCM32_RAW":((I2S_MODE == AIU_I2S_MODE_PCM24)?"PCM24_RAW":"PCM16_RAW"));
}
}
else{
if(i2s_mode == AIU_I2S_MODE_PCM32)
iec958_mode = AIU_958_MODE_PCM32;
else if(i2s_mode == AIU_I2S_MODE_PCM24)
iec958_mode = AIU_958_MODE_PCM24;
else
iec958_mode = AIU_958_MODE_PCM16;
printk("iec958 mode %s\n",(i2s_mode == AIU_I2S_MODE_PCM32)?"PCM32":((i2s_mode == AIU_I2S_MODE_PCM24)?"PCM24":"PCM16"));
}
if(iec958_mode == AIU_958_MODE_PCM16 || iec958_mode == AIU_958_MODE_PCM24 ||
iec958_mode == AIU_958_MODE_PCM32){
set.chan_stat->chstat0_l = 0x0100;
set.chan_stat->chstat0_r = 0x0100;
set.chan_stat->chstat1_l = 0x200;
set.chan_stat->chstat1_r = 0x200;
if(sample_rate==AUDIO_CLK_FREQ_882){
printk("----sample_rate==AUDIO_CLK_FREQ_882---\n");
set.chan_stat->chstat1_l = 0x800;
set.chan_stat->chstat1_r = 0x800;
}
if(sample_rate==AUDIO_CLK_FREQ_96){
printk("----sample_rate==AUDIO_CLK_FREQ_96---\n");
set.chan_stat->chstat1_l = 0xa00;
set.chan_stat->chstat1_r = 0xa00;
}
start = buf->addr;
size = snd_pcm_lib_buffer_bytes(substream);
audio_set_958outbuf(start, size, 0);
//audio_set_i2s_mode(AIU_I2S_MODE_PCM16);
//audio_set_aiubuf(start, size);
}else{
set.chan_stat->chstat0_l = 0x1902;
set.chan_stat->chstat0_r = 0x1902;
if(IEC958_mode_codec == 4 || IEC958_mode_codec == 5){ //DD+
if(runtime->rate == 32000){
set.chan_stat->chstat1_l = 0x300;
set.chan_stat->chstat1_r = 0x300;
}
else if(runtime->rate == 44100){
set.chan_stat->chstat1_l = 0xc00;
set.chan_stat->chstat1_r = 0xc00;
}
else{
set.chan_stat->chstat1_l = 0Xe00;
set.chan_stat->chstat1_r = 0Xe00;
}
}
else{ //DTS,DD
if(runtime->rate == 32000){
set.chan_stat->chstat1_l = 0x300;
set.chan_stat->chstat1_r = 0x300;
}
else if(runtime->rate == 44100){
set.chan_stat->chstat1_l = 0;
set.chan_stat->chstat1_r = 0;
}
else{
set.chan_stat->chstat1_l = 0x200;
set.chan_stat->chstat1_r = 0x200;
}
}
start = buf->addr;
size = snd_pcm_lib_buffer_bytes(substream);;
audio_set_958outbuf(start, size, (iec958_mode == AIU_958_MODE_RAW)?1:0);
memset((void*)buf->area,0,size);
}
ALSA_DEBUG("aiu 958 pcm buffer size %d \n",size);
audio_set_958_mode(iec958_mode, &set);
if(IEC958_mode_codec == 4 || IEC958_mode_codec == 5 || IEC958_mode_codec == 7){ //dd+
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 4, 2); // 4x than i2s
printk("DEBUG--> IEC958_mode_codec/%d 4x than i2s\n",IEC958_mode_codec);
}else
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);//512fs divide 4 == 128fs
#else
WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2); //256fs divide 2 == 128fs
#endif
if(IEC958_mode_codec == 2){
@@ -328,47 +326,47 @@ static void aml_hw_iec958_init(struct snd_pcm_substream *substream)
else if(IEC958_mode_codec == 3){
aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DTS,substream);
}
}else if(IEC958_mode_codec == 5){
aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DTS_HD,substream);
}else if(IEC958_mode_codec == 7){
WRITE_MPEG_REG(AIU_958_CHSTAT_L0, 0x1902);
WRITE_MPEG_REG(AIU_958_CHSTAT_L1, 0x900);
WRITE_MPEG_REG(AIU_958_CHSTAT_R0, 0x1902);
WRITE_MPEG_REG(AIU_958_CHSTAT_R1, 0x900);
aout_notifier_call_chain(AOUT_EVENT_RAWDATA_MAT_MLP,substream);
}else{
aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,substream);
else if(IEC958_mode_codec == 4){
aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS,substream);
}else if(IEC958_mode_codec == 5){
aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DTS_HD,substream);
}else if(IEC958_mode_codec == 7){
WRITE_MPEG_REG(AIU_958_CHSTAT_L0, 0x1902);
WRITE_MPEG_REG(AIU_958_CHSTAT_L1, 0x900);
WRITE_MPEG_REG(AIU_958_CHSTAT_R0, 0x1902);
WRITE_MPEG_REG(AIU_958_CHSTAT_R1, 0x900);
aout_notifier_call_chain(AOUT_EVENT_RAWDATA_MAT_MLP,substream);
}else{
}
aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,substream);
}
}
/*
special call by the audiodsp,add these code,as there are three cases for 958 s/pdif output
1)NONE-PCM raw output ,only available when ac3/dts audio,when raw output mode is selected by user.
2)PCM output for all audio, when pcm mode is selected by user .
3)PCM output for audios except ac3/dts,when raw output mode is selected by user
*/
{
ALSA_TRACE();
//M8 disable it
#if 0
void aml_alsa_hw_reprepare(void)
{
ALSA_TRACE();
//M8 disable it
#if 0
if(playback_substream_handle!=0)
aml_hw_iec958_init((struct snd_pcm_substream *)playback_substream_handle);
#endif
}
static int aml_dai_spdif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
/* diable 958 module before call initiation */
audio_hw_958_enable(0);
if(playback_substream_handle!=0)
aml_hw_iec958_init((struct snd_pcm_substream *)playback_substream_handle);
#endif
}
static int aml_dai_spdif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int ret = 0;
audio_stream_t *s;
ALSA_TRACE();
struct snd_pcm_runtime *runtime = substream->runtime;
struct aml_runtime_data *prtd = runtime->private_data;
audio_stream_t *s;
ALSA_TRACE();
if(!prtd){
@@ -381,188 +379,188 @@ static int aml_dai_spdif_startup(struct snd_pcm_substream *substream,
prtd->substream = substream;
runtime->private_data = prtd;
}
s->device_type = AML_AUDIO_SPDIFOUT;
audio_spdifout_pg_enable(1);
aml_spdif_play_stop();
s = &prtd->s;
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
s->device_type = AML_AUDIO_SPDIFOUT;
audio_spdifout_pg_enable(1);
aml_spdif_play_stop();
}
else{
s->device_type = AML_AUDIO_SPDIFIN;
return 0;
}
return 0;
}
out:
return ret;
}
static void aml_dai_spdif_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
//struct snd_dma_buffer *buf = &substream->dma_buffer;
ALSA_TRACE();
struct snd_pcm_runtime *runtime = substream->runtime;
//struct snd_dma_buffer *buf = &substream->dma_buffer;
memset((void*)runtime->dma_area,0,snd_pcm_lib_buffer_bytes(substream));
if(IEC958_mode_codec == 6){
printk("[%s %d]8chPCM output:disable aml_spdif_play()\n",__FUNCTION__,__LINE__);
}else{
aml_spdif_play();
}
// audio_spdifout_pg_enable(0);
ALSA_TRACE();
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
memset((void*)runtime->dma_area,0,snd_pcm_lib_buffer_bytes(substream));
if(IEC958_mode_codec == 6){
printk("[%s %d]8chPCM output:disable aml_spdif_play()\n",__FUNCTION__,__LINE__);
}else{
aml_spdif_play();
}
// audio_spdifout_pg_enable(0);
}
static int aml_dai_spdif_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
//struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
// struct aml_runtime_data *prtd = runtime->private_data;
//audio_stream_t *s = &prtd->s;
ALSA_TRACE();
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
aml_hw_iec958_init(substream);
}
else{
audio_in_spdif_set_buf(runtime->dma_addr, runtime->dma_bytes*2);
memset((void*)runtime->dma_area,0,runtime->dma_bytes*2);
{
int * ppp = (int*)(runtime->dma_area+runtime->dma_bytes*2-8);
ppp[0] = 0x78787878;
ppp[1] = 0x78787878;
}
}
return 0;
}
static int aml_dai_spdif_hw_params(struct snd_pcm_substream *substream,
}
}
static int aml_dai_spdif_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
//struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
// struct aml_runtime_data *prtd = runtime->private_data;
//audio_stream_t *s = &prtd->s;
ALSA_TRACE();
if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
aml_hw_iec958_init(substream);
}
else{
audio_in_spdif_set_buf(runtime->dma_addr, runtime->dma_bytes*2);
memset((void*)runtime->dma_area,0,runtime->dma_bytes*2);
{
int * ppp = (int*)(runtime->dma_area+runtime->dma_bytes*2-8);
ppp[0] = 0x78787878;
ppp[1] = 0x78787878;
}
}
return 0;
}
static int aml_dai_spdif_hw_params(struct snd_pcm_substream *substream,
{
ALSA_TRACE();
// struct snd_soc_pcm_runtime *rtd = substream->private_data;
// struct snd_pcm_runtime *runtime = substream->runtime;
// struct aml_runtime_data *prtd = runtime->private_data;
//audio_stream_t *s = &prtd->s;
return 0;
}
struct snd_pcm_hw_params *params,
struct snd_soc_dai *socdai)
{
ALSA_TRACE();
// struct snd_soc_pcm_runtime *rtd = substream->private_data;
// struct snd_pcm_runtime *runtime = substream->runtime;
// struct aml_runtime_data *prtd = runtime->private_data;
//audio_stream_t *s = &prtd->s;
return 0;
}
static int aml_dai_spdif_suspend(struct snd_soc_dai *cpu_dai)
#ifdef CONFIG_PM
ALSA_TRACE();
aml_spdif_play_stop();
static int aml_dai_spdif_suspend(struct snd_soc_dai *cpu_dai)
{
ALSA_TRACE();
aml_spdif_play_stop();
return 0;
static int aml_dai_spdif_resume(struct snd_soc_dai *cpu_dai)
{
ALSA_TRACE();
aml_spdif_play();
}
static int aml_dai_spdif_resume(struct snd_soc_dai *cpu_dai)
{
ALSA_TRACE();
aml_spdif_play();
return 0;
#define aml_spdif_suspend NULL
#define aml_spdif_resume NULL
}
#else
#define aml_spdif_suspend NULL
#define aml_spdif_resume NULL
#endif
.set_sysclk = aml_dai_spdif_set_sysclk,
.trigger = aml_dai_spdif_trigger,
.prepare = aml_dai_spdif_prepare,
.hw_params = aml_dai_spdif_hw_params,
.shutdown = aml_dai_spdif_shutdown,
static struct snd_soc_dai_ops spdif_dai_ops = {
.set_sysclk = aml_dai_spdif_set_sysclk,
.trigger = aml_dai_spdif_trigger,
.prepare = aml_dai_spdif_prepare,
.hw_params = aml_dai_spdif_hw_params,
.shutdown = aml_dai_spdif_shutdown,
.startup = aml_dai_spdif_startup,
static struct snd_soc_dai_driver aml_spdif_dai[] = {
{
.name = "aml-spdif-dai",
.playback = {
.stream_name = "S/PDIF Playback",
.channels_min = 1,
.channels_max = 2,
.rates = (
SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000),
.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE), },
.capture = {
.stream_name = "S/PDIF Capture",
.channels_min = 1,
.channels_max = 2,
.rates = (SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000),
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
.ops = &spdif_dai_ops,
.suspend = aml_dai_spdif_suspend,
.resume = aml_dai_spdif_resume,
}
};
static struct snd_soc_dai_driver aml_spdif_dai[] = {
{
.name = "aml-spdif-dai",
.playback = {
.stream_name = "S/PDIF Playback",
.channels_min = 1,
.channels_max = 8,
.rates = (
SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000),
.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE), },
.capture = {
.stream_name = "S/PDIF Capture",
.channels_min = 1,
.channels_max = 8,
.rates = (SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000),
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
.ops = &spdif_dai_ops,
.suspend = aml_dai_spdif_suspend,
.resume = aml_dai_spdif_resume,
static const struct snd_soc_component_driver aml_component= {
.name = "aml-spdif-dai",
};
static int aml_dai_spdif_probe(struct platform_device *pdev)
{
ALSA_PRINT("aml_spdif_probe \n");
return snd_soc_register_component(&pdev->dev, &aml_component,
aml_spdif_dai, ARRAY_SIZE(aml_spdif_dai));}
}
};
static const struct snd_soc_component_driver aml_component= {
.name = "aml-spdif-dai",
};
static int aml_dai_spdif_probe(struct platform_device *pdev)
{
ALSA_PRINT("aml_spdif_probe \n");
return snd_soc_register_component(&pdev->dev, &aml_component,
static int aml_dai_spdif_remove(struct platform_device *pdev)
aml_spdif_dai, ARRAY_SIZE(aml_spdif_dai));}
snd_soc_unregister_component(&pdev->dev);
static int aml_dai_spdif_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
#ifdef CONFIG_USE_OF
static const struct of_device_id amlogic_spdif_dai_dt_match[]={
{ .compatible = "amlogic,aml-spdif-dai",
},
{},
};
#else
#define amlogic_spdif_dai_dt_match NULL
#endif
static struct platform_driver aml_spdif_dai_driver = {
.probe = aml_dai_spdif_probe,
.remove = aml_dai_spdif_remove,
return 0;
}
#ifdef CONFIG_USE_OF
static const struct of_device_id amlogic_spdif_dai_dt_match[]={
{ .compatible = "amlogic,aml-spdif-dai",
},
{},
};
#else
#define amlogic_spdif_dai_dt_match NULL
#endif
static struct platform_driver aml_spdif_dai_driver = {
.probe = aml_dai_spdif_probe,
.name = "aml-spdif-dai",
.owner = THIS_MODULE,
.of_match_table = amlogic_spdif_dai_dt_match,
.remove = aml_dai_spdif_remove,
.driver = {
.name = "aml-spdif-dai",
.owner = THIS_MODULE,
.of_match_table = amlogic_spdif_dai_dt_match,
},
static int __init aml_dai_spdif_init(void)
{
ALSA_PRINT("enter aml_dai_spdif_init \n");
aml_spdif_play();
return platform_driver_register(&aml_spdif_dai_driver);
};
static int __init aml_dai_spdif_init(void)
{
ALSA_PRINT("enter aml_dai_spdif_init \n");
aml_spdif_play();
module_init(aml_dai_spdif_init);
return platform_driver_register(&aml_spdif_dai_driver);
}
static void __exit aml_dai_spdif_exit(void)
module_init(aml_dai_spdif_init);
platform_driver_unregister(&aml_spdif_dai_driver);
static void __exit aml_dai_spdif_exit(void)
{
module_exit(aml_dai_spdif_exit);
platform_driver_unregister(&aml_spdif_dai_driver);
}
MODULE_AUTHOR("jian.xu, <jian.xu@amlogic.com>");
MODULE_DESCRIPTION("Amlogic S/PDIF<HDMI> Controller Driver");
module_exit(aml_dai_spdif_exit);
MODULE_AUTHOR("jian.xu, <jian.xu@amlogic.com>");
MODULE_ALIAS("platform:aml-spdif");
MODULE_DESCRIPTION("Amlogic S/PDIF<HDMI> Controller Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:aml-spdif");

View File

@@ -18,7 +18,7 @@ struct dummy_codec_private {
};
#define DUMMY_CODEC_RATES (SNDRV_PCM_RATE_8000_192000)
#define DUMMY_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
#define DUMMY_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |SNDRV_PCM_FMTBIT_S32_LE)
static int dummy_codec_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -73,7 +73,7 @@ struct snd_soc_dai_driver dummy_codec_dai[] = {
.playback = {
.stream_name = "HIFI Playback",
.channels_min = 1,
.channels_max = 2,
.channels_max = 8,
.rates = DUMMY_CODEC_RATES,
.formats = DUMMY_CODEC_FORMATS,
},