diff options
author | Sumit Bhattacharya <sumitb@nvidia.com> | 2011-01-19 09:09:01 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-02-03 19:14:13 -0800 |
commit | 950c23d0bd1ffc19d01416fe2bb0e814233ce68e (patch) | |
tree | b3ccae94787d2e7c06f39457a5cd6c332091c1ec /arch | |
parent | 782c58b61982497762a852466163dd15d1bbe30e (diff) |
i2s: Support DSP mode in i2s driver
Change-Id: I6e60f06a0487a03553300130ef36dbe28de0139d
Reviewed-on: http://git-master/r/16196
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/include/mach/tegra2_i2s.h | 107 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_i2s.c | 78 |
2 files changed, 185 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/tegra2_i2s.h b/arch/arm/mach-tegra/include/mach/tegra2_i2s.h index 45929f20f0e2..46846c1ef834 100644 --- a/arch/arm/mach-tegra/include/mach/tegra2_i2s.h +++ b/arch/arm/mach-tegra/include/mach/tegra2_i2s.h @@ -157,6 +157,109 @@ #define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (I2S_FIFO_ATN_LVL_EIGHT_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT) #define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (I2S_FIFO_ATN_LVL_TWELVE_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT) +/* + * I2S_I2S_PCM_CTRL_0 + */ +#define I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ 0 +#define I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ 1 +#define I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ 2 +#define I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ 3 +#define I2S_PCM_TRM_EDGE_CTRL_SHIFT 9 + +#define I2S_I2S_PCM_TRM_EDGE_CTRL_MASK \ + (3 << I2S_PCM_TRM_EDGE_CTRL_SHIFT) +#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ \ + (I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ \ + << I2S_PCM_TRM_EDGE_CTRL_SHIFT) +#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ \ + (I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ \ + << I2S_PCM_TRM_EDGE_CTRL_SHIFT) +#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ \ + (I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ \ + << I2S_PCM_TRM_EDGE_CTRL_SHIFT) +#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ \ + (I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ \ + << I2S_PCM_TRM_EDGE_CTRL_SHIFT) + +#define I2S_PCM_TRM_MASK_BITS_ZERO 0 +#define I2S_PCM_TRM_MASK_BITS_ONE 1 +#define I2S_PCM_TRM_MASK_BITS_TWO 2 +#define I2S_PCM_TRM_MASK_BITS_THREE 3 +#define I2S_PCM_TRM_MASK_BITS_FOUR 4 +#define I2S_PCM_TRM_MASK_BITS_FIVE 5 +#define I2S_PCM_TRM_MASK_BITS_SIX 6 +#define I2S_PCM_TRM_MASK_BITS_SEVEN 7 +#define I2S_PCM_TRM_MASK_BITS_SHIFT 6 + +#define I2S_I2S_PCM_TRM_MASK_BITS_MASK \ + (7 << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_ZERO \ + (I2S_PCM_TRM_MASK_BITS_ZERO \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_ONE \ + (I2S_PCM_TRM_MASK_BITS_ONE \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_TWO \ + (I2S_PCM_TRM_MASK_BITS_TWO \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_THREE \ + (I2S_PCM_TRM_MASK_BITS_THREE \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_FOUR \ + (I2S_PCM_TRM_MASK_BITS_FOUR \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_FIVE \ + (I2S_PCM_TRM_MASK_BITS_FIVE \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_SIX \ + (I2S_PCM_TRM_MASK_BITS_SIX \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_TRM_MASK_BITS_SEVEN \ + (I2S_PCM_TRM_MASK_BITS_SEVEN \ + << I2S_PCM_TRM_MASK_BITS_SHIFT) + +#define I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL (1<<5) +#define I2S_I2S_PCM_CTRL_TRM_MODE (1<<4) + +#define I2S_PCM_RCV_MASK_BITS_ZERO 0 +#define I2S_PCM_RCV_MASK_BITS_ONE 1 +#define I2S_PCM_RCV_MASK_BITS_TWO 2 +#define I2S_PCM_RCV_MASK_BITS_THREE 3 +#define I2S_PCM_RCV_MASK_BITS_FOUR 4 +#define I2S_PCM_RCV_MASK_BITS_FIVE 5 +#define I2S_PCM_RCV_MASK_BITS_SIX 6 +#define I2S_PCM_RCV_MASK_BITS_SEVEN 7 +#define I2S_PCM_RCV_MASK_BITS_SHIFT 1 + +#define I2S_I2S_PCM_RCV_MASK_BITS_MASK \ + (7 << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_ZERO \ + (I2S_PCM_RCV_MASK_BITS_ZERO \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_ONE \ + (I2S_PCM_RCV_MASK_BITS_ONE \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_TWO \ + (I2S_PCM_RCV_MASK_BITS_TWO \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_THREE \ + (I2S_PCM_RCV_MASK_BITS_THREE \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_FOUR \ + (I2S_PCM_RCV_MASK_BITS_FOUR \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_FIVE \ + (I2S_PCM_RCV_MASK_BITS_FIVE \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_SIX \ + (I2S_PCM_RCV_MASK_BITS_SIX \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) +#define I2S_I2S_PCM_RCV_MASK_BITS_SEVEN \ + (I2S_PCM_RCV_MASK_BITS_SEVEN \ + << I2S_PCM_RCV_MASK_BITS_SHIFT) + +#define I2S_I2S_PCM_CTRL_RCV_MODE (1<<0) + struct i2s_runtime_data { int i2s_ctrl_0; int i2s_status_0; @@ -184,6 +287,10 @@ int i2s_set_bit_format(int ifc, unsigned format); int i2s_set_bit_size(int ifc, unsigned bit_size); int i2s_set_fifo_format(int ifc, unsigned fmt); void i2s_set_left_right_control_polarity(int ifc, int high_low); +int i2s_set_pcm_edge_mode(int ifc, unsigned edge_mode); +int i2s_set_pcm_mask_bits(int ifc, unsigned mask_bits, int tx); +void i2s_set_pcm_fsync_width(int ifc, int fsync_long); +void i2s_enable_pcm_mode(int ifc, int enable); void i2s_set_fifo_irq_on_err(int ifc, int fifo, int on); void i2s_set_fifo_irq_on_qe(int ifc, int fifo, int on); void i2s_enable_fifos(int ifc, int on); diff --git a/arch/arm/mach-tegra/tegra2_i2s.c b/arch/arm/mach-tegra/tegra2_i2s.c index f721f6d313a9..de50df917048 100644 --- a/arch/arm/mach-tegra/tegra2_i2s.c +++ b/arch/arm/mach-tegra/tegra2_i2s.c @@ -240,6 +240,13 @@ int i2s_set_bit_format(int ifc, unsigned fmt) val |= fmt << I2S_BIT_FORMAT_SHIFT; i2s_writel(ifc, val, I2S_I2S_CTRL_0); + + if (fmt == I2S_BIT_FORMAT_DSP) { + i2s_enable_pcm_mode(ifc, 1); + } + else { + i2s_enable_pcm_mode(ifc, 0); + } return 0; } @@ -296,6 +303,77 @@ void i2s_set_left_right_control_polarity(int ifc, int high_low) i2s_writel(ifc, val, I2S_I2S_CTRL_0); } +void i2s_enable_pcm_mode(int ifc, int on) +{ + u32 val; + + check_ifc(ifc); + + val = i2s_readl(ifc, I2S_I2S_PCM_CTRL_0); + val &= ~(I2S_I2S_PCM_CTRL_TRM_MODE | I2S_I2S_PCM_CTRL_RCV_MODE); + val |= on ? (I2S_I2S_PCM_CTRL_TRM_MODE | I2S_I2S_PCM_CTRL_RCV_MODE) : 0; + i2s_writel(ifc, val, I2S_I2S_PCM_CTRL_0); +} + +int i2s_set_pcm_edge_mode(int ifc, unsigned edge_mode) +{ + u32 val; + + check_ifc(ifc, -EINVAL); + + if (edge_mode > I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ) { + pr_err("%s: invalid dsp edge mode \n", __func__); + return -EINVAL; + } + + val = i2s_readl(ifc, I2S_I2S_PCM_CTRL_0); + val &= ~I2S_I2S_PCM_TRM_EDGE_CTRL_MASK; + val |= edge_mode << I2S_PCM_TRM_EDGE_CTRL_SHIFT; + + i2s_writel(ifc, val, I2S_I2S_PCM_CTRL_0); + return 0; +} + +int i2s_set_pcm_mask_bits(int ifc, unsigned mask_bits, int tx) +{ + u32 val; + + check_ifc(ifc, -EINVAL); + + val = i2s_readl(ifc, I2S_I2S_PCM_CTRL_0); + if (tx) { + if (mask_bits > I2S_I2S_PCM_TRM_MASK_BITS_SEVEN) { + pr_err("%s: invalid dsp mask bits \n", __func__); + return -EINVAL; + } + val &= ~I2S_I2S_PCM_TRM_MASK_BITS_MASK; + val |= mask_bits << I2S_PCM_TRM_MASK_BITS_SHIFT; + } + else { + if (mask_bits > I2S_I2S_PCM_RCV_MASK_BITS_SEVEN) { + pr_err("%s: invalid dsp mask bits \n", __func__); + return -EINVAL; + } + val &= ~I2S_I2S_PCM_RCV_MASK_BITS_MASK; + val |= mask_bits << I2S_PCM_RCV_MASK_BITS_SHIFT; + } + i2s_writel(ifc, val, I2S_I2S_PCM_CTRL_0); + return 0; +} + +void i2s_set_pcm_fsync_width(int ifc, int fsync_long) +{ + u32 val; + + check_ifc(ifc); + + val = i2s_readl(ifc, I2S_I2S_PCM_CTRL_0); + val &= ~I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL; + val |= fsync_long ? I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL : 0; + + i2s_writel(ifc, val, I2S_I2S_PCM_CTRL_0); +} + void i2s_set_fifo_irq_on_err(int ifc, int fifo, int on) { u32 val; |