blob: 1dfbd7a1a19a105b736374664042faefdf01ccfc [file] [log] [blame]
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001/* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/err.h>
16#include <linux/module.h>
17#include <sound/hwdep.h>
18#include <sound/devdep_params.h>
19#include <sound/msm-dts-eagle.h>
20
21#include "msm-pcm-routing-devdep.h"
22#include "msm-ds2-dap-config.h"
23
24#ifdef CONFIG_SND_HWDEP
25static int msm_pcm_routing_hwdep_open(struct snd_hwdep *hw, struct file *file)
26{
27 pr_debug("%s\n", __func__);
28 msm_ds2_dap_update_port_parameters(hw, file, true);
29 return 0;
30}
31
32static int msm_pcm_routing_hwdep_release(struct snd_hwdep *hw,
33 struct file *file)
34{
35 pr_debug("%s\n", __func__);
36 msm_ds2_dap_update_port_parameters(hw, file, false);
37 return 0;
38}
39
40static int msm_pcm_routing_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
41 unsigned int cmd, unsigned long arg)
42{
43 int ret = 0;
44 void __user *argp = (void __user *)arg;
45
46 pr_debug("%s:cmd %x\n", __func__, cmd);
47 switch (cmd) {
48 case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM:
49 case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM:
50 case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND:
51 case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE:
52 msm_pcm_routing_acquire_lock();
53 ret = msm_ds2_dap_ioctl(hw, file, cmd, argp);
54 msm_pcm_routing_release_lock();
55 break;
56 case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER:
57 ret = msm_ds2_dap_ioctl(hw, file, cmd, argp);
58 break;
59 case DTS_EAGLE_IOCTL_GET_CACHE_SIZE:
60 case DTS_EAGLE_IOCTL_SET_CACHE_SIZE:
61 case DTS_EAGLE_IOCTL_GET_PARAM:
62 case DTS_EAGLE_IOCTL_SET_PARAM:
63 case DTS_EAGLE_IOCTL_SET_CACHE_BLOCK:
64 case DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE:
65 case DTS_EAGLE_IOCTL_GET_LICENSE:
66 case DTS_EAGLE_IOCTL_SET_LICENSE:
67 case DTS_EAGLE_IOCTL_SEND_LICENSE:
68 case DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS:
69 ret = msm_dts_eagle_ioctl(cmd, arg);
70 if (ret == -EPERM) {
71 pr_err("%s called with invalid control 0x%X\n",
72 __func__, cmd);
73 ret = -EINVAL;
74 }
75 break;
76 default:
77 pr_err("%s called with invalid control 0x%X\n", __func__, cmd);
78 ret = -EINVAL;
79 break;
80 }
81 return ret;
82}
83
84void msm_pcm_routing_hwdep_free(struct snd_pcm *pcm)
85{
86 pr_debug("%s\n", __func__);
87 msm_dts_eagle_pcm_free(pcm);
88}
89
90#ifdef CONFIG_COMPAT
91static int msm_pcm_routing_hwdep_compat_ioctl(struct snd_hwdep *hw,
92 struct file *file,
93 unsigned int cmd,
94 unsigned long arg)
95{
96 int ret = 0;
97 void __user *argp = (void __user *)arg;
98
99 pr_debug("%s:cmd %x\n", __func__, cmd);
100 switch (cmd) {
101 case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32:
102 case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32:
103 case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND32:
104 case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE32:
105 msm_pcm_routing_acquire_lock();
106 ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp);
107 msm_pcm_routing_release_lock();
108 break;
109 case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER32:
110 ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp);
111 break;
112 case DTS_EAGLE_IOCTL_GET_CACHE_SIZE32:
113 case DTS_EAGLE_IOCTL_SET_CACHE_SIZE32:
114 case DTS_EAGLE_IOCTL_GET_PARAM32:
115 case DTS_EAGLE_IOCTL_SET_PARAM32:
116 case DTS_EAGLE_IOCTL_SET_CACHE_BLOCK32:
117 case DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE32:
118 case DTS_EAGLE_IOCTL_GET_LICENSE32:
119 case DTS_EAGLE_IOCTL_SET_LICENSE32:
120 case DTS_EAGLE_IOCTL_SEND_LICENSE32:
121 case DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS32:
122 ret = msm_dts_eagle_compat_ioctl(cmd, arg);
123 if (ret == -EPERM) {
124 pr_err("%s called with invalid control 0x%X\n",
125 __func__, cmd);
126 ret = -EINVAL;
127 }
128 break;
129 default:
130 pr_err("%s called with invalid control 0x%X\n", __func__, cmd);
131 ret = -EINVAL;
132 break;
133 }
134 return ret;
135}
136#endif
137
138int msm_pcm_routing_hwdep_new(struct snd_soc_pcm_runtime *runtime,
139 struct msm_pcm_routing_bdai_data *msm_bedais)
140{
141 struct snd_hwdep *hwdep;
142 struct snd_soc_dai_link *dai_link = runtime->dai_link;
143 int rc;
144
Banajit Goswami9f923c32016-12-16 16:06:25 -0800145 if (dai_link->id < 0 ||
146 dai_link->id >= MSM_BACKEND_DAI_MAX) {
147 pr_err("%s:BE id %d invalid index\n",
148 __func__, dai_link->id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800149 return -EINVAL;
150 }
Banajit Goswami9f923c32016-12-16 16:06:25 -0800151 pr_debug("%s BE id %d\n", __func__, dai_link->id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800152 rc = snd_hwdep_new(runtime->card->snd_card,
Banajit Goswami9f923c32016-12-16 16:06:25 -0800153 msm_bedais[dai_link->id].name,
154 dai_link->id, &hwdep);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800155 if (hwdep == NULL) {
156 pr_err("%s: hwdep intf failed to create %s- hwdep NULL\n",
Banajit Goswami9f923c32016-12-16 16:06:25 -0800157 __func__, msm_bedais[dai_link->id].name);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800158 return rc;
159 }
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -0800160 if (rc < 0) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800161 pr_err("%s: hwdep intf failed to create %s rc %d\n", __func__,
Banajit Goswami9f923c32016-12-16 16:06:25 -0800162 msm_bedais[dai_link->id].name, rc);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800163 return rc;
164 }
165
166 hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE;
Banajit Goswami9f923c32016-12-16 16:06:25 -0800167 hwdep->private_data = &msm_bedais[dai_link->id];
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800168 hwdep->ops.open = msm_pcm_routing_hwdep_open;
169 hwdep->ops.ioctl = msm_pcm_routing_hwdep_ioctl;
170 hwdep->ops.release = msm_pcm_routing_hwdep_release;
171#ifdef CONFIG_COMPAT
172 hwdep->ops.ioctl_compat = msm_pcm_routing_hwdep_compat_ioctl;
173#endif
174 return msm_dts_eagle_pcm_new(runtime);
175}
176#endif