/* sound/soc/samsung/i2s.c * * ALSA SoC Audio Layer - Samsung I2S Controller driver * * Copyright (c) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh <jassisinghbrar@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include<linux/delay.h>#include<linux/slab.h>#include<linux/clk.h>#include<linux/io.h>#include<linux/module.h>#include<linux/of.h>#include<linux/of_gpio.h>#include<linux/pm_runtime.h>#include<sound/soc.h>#include<sound/pcm_params.h>#include<mach/dma.h>#include<linux/platform_data/asoc-s3c.h>#include"dma.h"#include"idma.h"#include"i2s.h"#include"i2s-regs.h"#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)enumsamsung_dai_type{TYPE_PRI,TYPE_SEC,};structsamsung_i2s_dai_data{intdai_type;};structi2s_dai{/* Platform device for this DAI */structplatform_device*pdev;/* IOREMAP'd SFRs */void__iomem*addr;/* Physical base address of SFRs */u32base;/* Rate of RCLK source clock */unsignedlongrclk_srcrate;/* Frame Clock */unsignedfrmclk;/* * Specifically requested RCLK,BCLK by MACHINE Driver. * 0 indicates CPU driver is free to choose any value. */unsignedrfs,bfs;/* I2S Controller's core clock */structclk*clk;/* Clock for generating I2S signals */structclk*op_clk;/* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */structi2s_dai*pri_dai;/* Pointer to the Secondary_Fifo if it has one, NULL otherwise */structi2s_dai*sec_dai;#define DAI_OPENED (1 << 0) /* Dai is opened */#define DAI_MANAGER (1 << 1) /* Dai is the manager */unsignedmode;/* Driver for this DAI */structsnd_soc_dai_driveri2s_dai_drv;/* DMA parameters */structs3c_dma_paramsdma_playback;structs3c_dma_paramsdma_capture;structs3c_dma_paramsidma_playback;u32quirks;u32suspend_i2smod;u32suspend_i2scon;u32suspend_i2spsr;unsignedlonggpios[7];/* i2s gpio line numbers */};/* Lock for cross i/f checks */staticDEFINE_SPINLOCK(lock);/* If this is the 'overlay' stereo DAI */staticinlineboolis_secondary(structi2s_dai*i2s){returni2s->pri_dai?true:false;}/* If operating in SoC-Slave mode */staticinlineboolis_slave(structi2s_dai*i2s){return(readl(i2s->addr+I2SMOD)&MOD_SLAVE)?true:false;}/* If this interface of the controller is transmitting data */staticinlinebooltx_active(structi2s_dai*i2s){u32active;if(!i2s)returnfalse;active=readl(i2s->addr+I2SCON);if(is_secondary(i2s))active&=CON_TXSDMA_ACTIVE;else