blob: cddc2a1e3f265f5ed70d60d81ef8d7ebe0af571d [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302/* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303 */
4
5#include <linux/kernel.h>
6#include <linux/platform_device.h>
7#include <linux/err.h>
8#include <linux/module.h>
9#include <sound/hwdep.h>
10#include <sound/devdep_params.h>
11#include "msm-pcm-routing-devdep.h"
12#include "msm-ds2-dap-config.h"
13
14#ifdef CONFIG_SND_HWDEP
15static int msm_pcm_routing_hwdep_open(struct snd_hwdep *hw, struct file *file)
16{
17 pr_debug("%s\n", __func__);
18 msm_ds2_dap_update_port_parameters(hw, file, true);
19 return 0;
20}
21
22static int msm_pcm_routing_hwdep_release(struct snd_hwdep *hw,
23 struct file *file)
24{
25 pr_debug("%s\n", __func__);
26 msm_ds2_dap_update_port_parameters(hw, file, false);
27 return 0;
28}
29
30static int msm_pcm_routing_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
31 unsigned int cmd, unsigned long arg)
32{
33 int ret = 0;
34 void __user *argp = (void __user *)arg;
35
36 pr_debug("%s:cmd %x\n", __func__, cmd);
37 switch (cmd) {
38 case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM:
39 case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM:
40 case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND:
41 case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE:
42 msm_pcm_routing_acquire_lock();
43 ret = msm_ds2_dap_ioctl(hw, file, cmd, argp);
44 msm_pcm_routing_release_lock();
45 break;
46 case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER:
47 ret = msm_ds2_dap_ioctl(hw, file, cmd, argp);
48 break;
49 default:
50 pr_err("%s called with invalid control 0x%X\n", __func__, cmd);
51 ret = -EINVAL;
52 break;
53 }
54 return ret;
55}
56
57void msm_pcm_routing_hwdep_free(struct snd_pcm *pcm)
58{
59 pr_debug("%s\n", __func__);
60}
61
62#ifdef CONFIG_COMPAT
63static int msm_pcm_routing_hwdep_compat_ioctl(struct snd_hwdep *hw,
64 struct file *file,
65 unsigned int cmd,
66 unsigned long arg)
67{
68 int ret = 0;
69 void __user *argp = (void __user *)arg;
70
71 pr_debug("%s:cmd %x\n", __func__, cmd);
72 switch (cmd) {
73 case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32:
74 case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32:
75 case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND32:
76 case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE32:
77 msm_pcm_routing_acquire_lock();
78 ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp);
79 msm_pcm_routing_release_lock();
80 break;
81 case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER32:
82 ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp);
83 break;
84 default:
85 pr_err("%s called with invalid control 0x%X\n", __func__, cmd);
86 ret = -EINVAL;
87 break;
88 }
89 return ret;
90}
91#endif
92
93int msm_pcm_routing_hwdep_new(struct snd_soc_pcm_runtime *runtime,
94 struct msm_pcm_routing_bdai_data *msm_bedais)
95{
96 struct snd_hwdep *hwdep;
97 struct snd_soc_dai_link *dai_link = runtime->dai_link;
98 int rc;
99
100 if (dai_link->id < 0 ||
101 dai_link->id >= MSM_BACKEND_DAI_MAX) {
102 pr_err("%s:BE id %d invalid index\n",
103 __func__, dai_link->id);
104 return -EINVAL;
105 }
106 pr_debug("%s BE id %d\n", __func__, dai_link->id);
107 rc = snd_hwdep_new(runtime->card->snd_card,
108 msm_bedais[dai_link->id].name,
109 dai_link->id, &hwdep);
110 if (hwdep == NULL) {
111 pr_err("%s: hwdep intf failed to create %s- hwdep NULL\n",
112 __func__, msm_bedais[dai_link->id].name);
113 return rc;
114 }
115 if (rc < 0) {
116 pr_err("%s: hwdep intf failed to create %s rc %d\n", __func__,
117 msm_bedais[dai_link->id].name, rc);
118 return rc;
119 }
120
121 hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE;
122 hwdep->private_data = &msm_bedais[dai_link->id];
123 hwdep->ops.open = msm_pcm_routing_hwdep_open;
124 hwdep->ops.ioctl = msm_pcm_routing_hwdep_ioctl;
125 hwdep->ops.release = msm_pcm_routing_hwdep_release;
126#ifdef CONFIG_COMPAT
127 hwdep->ops.ioctl_compat = msm_pcm_routing_hwdep_compat_ioctl;
128#endif
129 return rc;
130}
131#endif