summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra_i2s_audio.c
diff options
context:
space:
mode:
authorChris Fries <C.Fries@motorola.com>2010-10-08 13:54:28 -0500
committerIliyan Malchev <malchev@google.com>2010-10-08 15:41:54 -0700
commitbd3ee16444d6e35e6f2837521c2508fb05dc436d (patch)
tree3140f4ce4afbe883d3e0e1dd6d75b44ed2024fb8 /arch/arm/mach-tegra/tegra_i2s_audio.c
parentaee8fd4a24840c8336bba9ad3f992a1083e68897 (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.c66
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;