summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c')
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c
new file mode 100755
index 00000000..8a6d374e
--- /dev/null
+++ b/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c
@@ -0,0 +1,259 @@
+/*++
+ * linux/sound/soc/wmt/wmt_hwdep.c
+ * WonderMedia I2S audio driver for ALSA
+ *
+ * Copyright c 2010 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+#include <asm/mach-types.h>
+#include <mach/gpio.h>
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc-dapm.h>
+#include <sound/hwdep.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include "wmt_hwdep.h"
+#include "wmt-pcm.h"
+
+int WFD_flag = 0;
+static int gmode = 2;
+static char gstring[3] = "LR";
+
+static char gSpdHdm[6] = "BOTH";
+static int gSpHd = 6;
+
+extern void wmt_i2s_dac0_ctrl(int HDMI_audio_enable);
+
+static int wmt_hwdep_open(struct snd_hwdep *hw, struct file *file)
+{
+ if ((file->f_flags & O_RDWR) && (WFD_flag)) {
+ return -EBUSY;
+ }
+ else if (file->f_flags & O_SYNC) {
+ WFD_flag = 1;
+ }
+ return 0;
+}
+
+static int wmt_hwdep_release(struct snd_hwdep *hw, struct file *file)
+{
+ WFD_flag = 0;
+ return 0;
+}
+
+static int wmt_hwdep_mmap(struct snd_hwdep *hw, struct file *file, struct vm_area_struct *vma)
+{
+ vma->vm_flags |= VM_IO | VM_RESERVED;
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ if (remap_pfn_range(vma, vma->vm_start, (vma->vm_pgoff),
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ printk("*E* remap page range failed: vm_pgoff=0x%x ", (unsigned int)vma->vm_pgoff);
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+static int wmt_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int *value;
+ WFDStrmInfo_t *info;
+ struct wmt_soc_vt1603_info vt1603_info;
+ int ret = 0;
+
+ switch (cmd) {
+ case WMT_SOC_IOCTL_HDMI:
+ value = (int __user *)arg;
+
+ if (*value > 1) {
+ printk("Not supported status for HDMI Audio %d", *value);
+ return 0;
+ }
+ wmt_i2s_dac0_ctrl(*value);
+ return 0;
+
+ case WMT_SOC_IOCTL_WFD_START:
+ wmt_pcm_wfd_start();
+ return copy_to_user( (void *)arg, (const void __user *) wmt_pcm_wfd_get_buf(), sizeof(unsigned int));
+
+ case WMT_SOC_IOCTL_GET_STRM:
+ info = (WFDStrmInfo_t *)wmt_pcm_wfd_get_strm((WFDStrmInfo_t *)arg);
+ return __put_user((int)info, (unsigned int __user *) arg);
+
+ case WMT_SOC_IOCTL_WFD_STOP:
+ wmt_pcm_wfd_stop();
+ return 0;
+
+ case WMT_SOC_IOCTL_VT1603_RD:
+ ret = copy_from_user(&vt1603_info, (void __user *)arg, sizeof(vt1603_info));
+
+ if (ret == 0) {
+ vt1603_info.reg_value = vt1603_hwdep_ioctl(0, vt1603_info.reg_offset, vt1603_info.reg_value);
+ printk("<<<%s read reg 0x%x val 0x%x\n", __FUNCTION__, vt1603_info.reg_offset, vt1603_info.reg_value);
+ ret = copy_to_user((void __user *)arg, &vt1603_info, sizeof(vt1603_info));
+ }
+ return ret;
+ case WMT_SOC_IOCTL_VT1603_WR:
+ ret = copy_from_user(&vt1603_info, (void __user *)arg, sizeof(vt1603_info));
+ printk("<<<%s write reg 0x%x val 0x%x\n", __FUNCTION__, vt1603_info.reg_offset, vt1603_info.reg_value);
+ if (ret == 0)
+ vt1603_hwdep_ioctl(1, vt1603_info.reg_offset, vt1603_info.reg_value);
+ return ret;
+
+ case WMT_SOC_IOCTL_CH_SEL:
+ value = (int __user *)arg;
+
+ if (*value > 2) {
+ printk("Not supported for CH select %d", *value);
+ return 0;
+ }
+ wmt_i2s_ch_sel(*value);
+ return 0;
+
+ default:
+ break;
+ }
+
+ printk("Not supported ioctl for WMT-HWDEP");
+ return -ENOIOCTLCMD;
+}
+
+static long wmt_hwdep_write(struct snd_hwdep *hw, const char __user *buf,
+ long count, loff_t *offset)
+{
+ char string[3];
+ //int mode;
+ memset(string, 0, sizeof(string));
+ copy_from_user(&string, buf, sizeof(string));
+ printk("<<<%s %s\n", __FUNCTION__, string);
+ if (!memcmp(string, "LL", 2)) {
+ gmode = 0;
+ }
+ else if (!memcmp(string, "RR", 2)) {
+ gmode = 1;
+ }
+ else if (!memcmp(string, "LR", 2)) {
+ gmode = 2;
+ }
+ else {
+ printk("Not supported for CH select");
+ return count;
+ }
+
+ memset(gstring, 0, sizeof(gstring));
+ strncpy(gstring, string, sizeof(string));
+ wmt_i2s_ch_sel(gmode);
+ return count;
+}
+
+static long wmt_hwdep_read(struct snd_hwdep *hw, char __user *buf,
+ long count, loff_t *offset)
+{
+ int len = 0;
+ printk("%s string %s --> mode %d\n", __FUNCTION__, gstring, gmode);
+ len = copy_to_user(buf, gstring, sizeof(gstring));
+
+ return sizeof(gstring);
+}
+
+static long wmt_hwdep_write_1(struct snd_hwdep *hw, const char __user *buf,
+ long count, loff_t *offset)
+{
+ char string[5];
+ //int mode;
+
+ copy_from_user(&string, buf, sizeof(string));
+ printk("<<<%s %s\n", __FUNCTION__, string);
+ if (!memcmp(string, "NONE", 4)) {
+ gSpHd = 3;
+ }
+ else if (!memcmp(string, "HDMI", 4)) {
+ gSpHd = 4;
+ }
+ else if (!memcmp(string, "SPDIF", 5)) {
+ gSpHd = 5;
+ }
+ else if (!memcmp(string, "BOTH", 4)) {
+ gSpHd = 6;
+ }
+ else {
+ printk("Not supported for SPDIF/HDMI switch");
+ return count;
+ }
+
+ memset(gSpdHdm, 0, sizeof(gSpdHdm));
+ strncpy(gSpdHdm, string, sizeof(string));
+
+ wmt_i2s_ch_sel(gSpHd);
+ return count;
+}
+
+
+static long wmt_hwdep_read_1(struct snd_hwdep *hw, char __user *buf,
+ long count, loff_t *offset)
+{
+ int len = 0;
+ printk("%s string %s --> mode %d\n", __FUNCTION__, gSpdHdm, gSpHd);
+ len = copy_to_user(buf, gSpdHdm, sizeof(gSpdHdm));
+
+ return sizeof(gstring);
+}
+
+void wmt_soc_hwdep_new(struct snd_soc_codec *codec)
+{
+ struct snd_hwdep *hwdep;
+ struct snd_hwdep *hwdep_1;
+ if (snd_hwdep_new(codec->card->snd_card, "WMT-HWDEP", 0, &hwdep) < 0) {
+ printk("create WMT-HWDEP_0 fail");
+ return;
+ }
+
+ sprintf(hwdep->name, "WMT-HWDEP %d", 0);
+
+ hwdep->iface = SNDRV_HWDEP_IFACE_WMT;
+ hwdep->ops.open = wmt_hwdep_open;
+ hwdep->ops.ioctl = wmt_hwdep_ioctl;
+ hwdep->ops.release = wmt_hwdep_release;
+ hwdep->ops.mmap = wmt_hwdep_mmap;
+ hwdep->ops.write = wmt_hwdep_write;
+ hwdep->ops.read = wmt_hwdep_read;
+
+ if (snd_hwdep_new(codec->card->snd_card, "WMT-HWDEP", 1, &hwdep_1) < 0) {
+ printk("create WMT-HWDEP_1 fail");
+ return;
+ }
+
+ sprintf(hwdep_1->name, "WMT-HWDEP %d", 1);
+ printk("create %s success", hwdep_1->name);
+
+ hwdep_1->iface = SNDRV_HWDEP_IFACE_WMT;
+ hwdep_1->ops.write = wmt_hwdep_write_1;
+ hwdep_1->ops.read = wmt_hwdep_read_1;
+}
+