diff options
author | Chris Fries <C.Fries@motorola.com> | 2010-10-08 13:54:28 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2010-10-08 15:41:54 -0700 |
commit | bd3ee16444d6e35e6f2837521c2508fb05dc436d (patch) | |
tree | 3140f4ce4afbe883d3e0e1dd6d75b44ed2024fb8 /arch/arm/mach-tegra/tegra_i2s_audio.c | |
parent | aee8fd4a24840c8336bba9ad3f992a1083e68897 (diff) |
[ARM] tegra: i2s: Add I2S ioctl for setting bit format
Added an ioctl to set the bit format for I2S between "DSP"/"PCM" mode and
normal mode (set by board file)
Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_i2s_audio.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra_i2s_audio.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra_i2s_audio.c b/arch/arm/mach-tegra/tegra_i2s_audio.c index a70f769b61cf..6f3295d62bf2 100644 --- a/arch/arm/mach-tegra/tegra_i2s_audio.c +++ b/arch/arm/mach-tegra/tegra_i2s_audio.c @@ -126,6 +126,10 @@ struct audio_driver_state { struct miscdevice misc_in; struct miscdevice misc_in_ctl; struct audio_stream in; + + /* Control for whole I2S (Data format, etc.) */ + struct miscdevice misc_ctl; + unsigned int bit_format; }; static inline int buf_size(struct audio_stream *s) @@ -183,6 +187,17 @@ static inline struct audio_driver_state *ads_from_misc_in_ctl( return ads; } +static inline struct audio_driver_state *ads_from_misc_ctl( + struct file *file) +{ + struct miscdevice *m = file->private_data; + struct audio_driver_state *ads = + container_of(m, struct audio_driver_state, + misc_ctl); + BUG_ON(!ads); + return ads; +} + static inline struct audio_driver_state *ads_from_out( struct audio_stream *aos) { @@ -1313,6 +1328,44 @@ static long tegra_audio_out_ioctl(struct file *file, return rc; } +static long tegra_audio_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int rc = 0; + struct audio_driver_state *ads = ads_from_misc_ctl(file); + unsigned int mode; + + switch (cmd) { + case TEGRA_AUDIO_SET_BIT_FORMAT: + if (copy_from_user(&mode, (const void __user *)arg, + sizeof(mode))) { + rc = -EFAULT; + break; + } + switch(mode) { + case TEGRA_AUDIO_BIT_FORMAT_DEFAULT: + i2s_set_bit_format(ads->i2s_base, ads->pdata->mode); + ads->bit_format = mode; + case TEGRA_AUDIO_BIT_FORMAT_DSP: + i2s_set_bit_format(ads->i2s_base, I2S_BIT_FORMAT_DSP); + ads->bit_format = mode; + break; + default: + pr_err("%s: Invald PCM mode %d", __func__, mode); + rc = -EINVAL; + break; + } + break; + case TEGRA_AUDIO_GET_BIT_FORMAT: + if (copy_to_user((void __user *)arg, &ads->bit_format, + sizeof(mode))) { + rc = -EFAULT; + } + break; + } + return rc; +} + static long tegra_audio_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1795,6 +1848,13 @@ static const struct file_operations tegra_audio_in_ctl_fops = { .unlocked_ioctl = tegra_audio_in_ioctl, }; +static const struct file_operations tegra_audio_ctl_fops = { + .owner = THIS_MODULE, + .open = tegra_audio_ctl_open, + .release = tegra_audio_ctl_release, + .unlocked_ioctl = tegra_audio_ioctl, +}; + static int init_stream_buffer(struct audio_stream *s, struct tegra_audio_buf_config *cfg, unsigned padding) @@ -2221,6 +2281,12 @@ static int tegra_audio_probe(struct platform_device *pdev) if (rc < 0) return rc; + rc = setup_misc_device(&state->misc_ctl, + &tegra_audio_ctl_fops, + "audio%d_ctl", state->pdev->id); + if (rc < 0) + return rc; + state->using_dma = state->pdata->dma_on; if (!state->using_dma) sound_ops = &pio_sound_ops; |