|
@@ -24,7 +24,8 @@
|
|
|
#include "msm_dailink.h"
|
|
|
#include <soc/qcom/boot_stats.h>
|
|
|
#include "msm_common.h"
|
|
|
-
|
|
|
+#include <linux/cdev.h>
|
|
|
+#include <linux/err.h>
|
|
|
|
|
|
#define DRV_NAME "spf-asoc-snd"
|
|
|
|
|
@@ -60,6 +61,9 @@
|
|
|
#define MSM_HIFI_ON 1
|
|
|
#define DIR_SZ 10
|
|
|
|
|
|
+#define AUTO_VIRT_SNDCARD_ONLINE 0
|
|
|
+#define AUTO_VIRT_SNDCARD_OFFLINE 1
|
|
|
+
|
|
|
struct snd_card_pdata {
|
|
|
struct kobject snd_card_kobj;
|
|
|
int card_status;
|
|
@@ -692,6 +696,70 @@ void msm_common_set_pdata(struct snd_soc_card *card,
|
|
|
pdata->common_pdata = common_pdata;
|
|
|
}
|
|
|
|
|
|
+static long virt_sndcard_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+ case AUTO_VIRT_SNDCARD_OFFLINE:
|
|
|
+ snd_card_notify_user(SND_CARD_STATUS_OFFLINE);
|
|
|
+ pr_debug("%s: mark sndcard offline\n", __func__);
|
|
|
+ break;
|
|
|
+ case AUTO_VIRT_SNDCARD_ONLINE:
|
|
|
+ snd_card_notify_user(SND_CARD_STATUS_ONLINE);
|
|
|
+ pr_debug("%s: mark sndcard online\n", __func__);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pr_err("%s: Invalid command = %d\n", __func__, cmd);
|
|
|
+ ret = -EFAULT;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static const struct file_operations virt_sndcard_ctl_fops = {
|
|
|
+ .owner = THIS_MODULE,
|
|
|
+ .unlocked_ioctl = virt_sndcard_ioctl,
|
|
|
+};
|
|
|
+
|
|
|
+static struct cdev virt_sndcard_ctl = {
|
|
|
+ .ops = &virt_sndcard_ctl_fops,
|
|
|
+};
|
|
|
+
|
|
|
+int msm_audio_ssr_register(struct cdev *virt_sndcard_ctl)
|
|
|
+{
|
|
|
+ static struct class *dev_class;
|
|
|
+ dev_t dev;
|
|
|
+
|
|
|
+ if ((alloc_chrdev_region(&dev, 0, 1, "virt_sndcard_ctl")) < 0) {
|
|
|
+ pr_err("%s: Cannot allocate major number\n", __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ pr_debug("Major = %d Minor = %d\n", MAJOR(dev), MINOR(dev));
|
|
|
+ cdev_init(virt_sndcard_ctl, &virt_sndcard_ctl_fops);
|
|
|
+ if ((cdev_add(virt_sndcard_ctl, dev, 1)) < 0) {
|
|
|
+ pr_err("%s: Cannot add the device to the system\n", __func__);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ dev_class = class_create(THIS_MODULE, "SSR");
|
|
|
+ if (IS_ERR(dev_class)) {
|
|
|
+ pr_err("%s: Cannot create the struct class\n", __func__);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ if (IS_ERR(device_create(dev_class, NULL, dev, NULL, "virt_sndcard_ctl"))) {
|
|
|
+ pr_err("%s: Cannot create the Device\n", __func__);
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+
|
|
|
+fail:
|
|
|
+ class_destroy(dev_class);
|
|
|
+err:
|
|
|
+ unregister_chrdev_region(dev, 1);
|
|
|
+ return -EINVAL;
|
|
|
+}
|
|
|
+
|
|
|
static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct snd_soc_card *card;
|
|
@@ -752,6 +820,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|
|
pr_debug("%s: DRIVER Audio Ready\n", __func__);
|
|
|
|
|
|
spdev = pdev;
|
|
|
+ ret = msm_audio_ssr_register(&virt_sndcard_ctl);
|
|
|
+ if (ret)
|
|
|
+ pr_err("%s: Audio virtual sndcard ctrl register fail, ret=%d\n", __func__, ret);
|
|
|
+ dev_info(&pdev->dev, "Audio virtual sndcard ctrl register complete\n");
|
|
|
|
|
|
ret = snd_card_sysfs_init();
|
|
|
if (ret)
|