[ARM] tegra: i2s: Add I2S ioctl for setting bit format
authorChris Fries <C.Fries@motorola.com>
Fri, 8 Oct 2010 18:54:28 +0000 (13:54 -0500)
committerIliyan Malchev <malchev@google.com>
Fri, 8 Oct 2010 22:41:54 +0000 (15:41 -0700)
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>
arch/arm/mach-tegra/tegra_i2s_audio.c
include/linux/tegra_audio.h

index a70f769b61cfac3a8e1b2abfce03a384e1a4a01d..6f3295d62bf221fe8c322e7343769aaaae6b1881 100644 (file)
@@ -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;
index 07192b28a936589cedbbf28a3ffe749858274ff4..b97b640819a036bb12fe2510c225396739356ae9 100644 (file)
@@ -72,4 +72,11 @@ struct tegra_audio_out_preload {
 #define TEGRA_AUDIO_OUT_PRELOAD_FIFO   _IOWR(TEGRA_AUDIO_MAGIC, 10, \
                        struct tegra_audio_out_preload *)
 
+#define TEGRA_AUDIO_BIT_FORMAT_DEFAULT 0
+#define TEGRA_AUDIO_BIT_FORMAT_DSP 1
+#define TEGRA_AUDIO_SET_BIT_FORMAT       _IOW(TEGRA_AUDIO_MAGIC, 11, \
+                       unsigned int *)
+#define TEGRA_AUDIO_GET_BIT_FORMAT       _IOR(TEGRA_AUDIO_MAGIC, 12, \
+                       unsigned int *)
+
 #endif/*_CPCAP_AUDIO_H*/