From f67a5ef4d6cce416984ba45110c3c1b2b0c85af8 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Wed, 11 Aug 2010 17:43:34 -0700 Subject: [PATCH] [ARM] tegra: cpcap-audio: enable turning off audio-output paths Signed-off-by: Iliyan Malchev --- drivers/mfd/cpcap-audio.c | 28 +++++++++++++++++----------- include/linux/cpcap_audio.h | 8 +++++++- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/cpcap-audio.c b/drivers/mfd/cpcap-audio.c index 7cb3bc51fa27..d335083899bf 100644 --- a/drivers/mfd/cpcap-audio.c +++ b/drivers/mfd/cpcap-audio.c @@ -126,35 +126,41 @@ static long cpcap_audio_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rc = 0; + struct cpcap_audio_output out; mutex_lock(&cpcap_lock); switch (cmd) { case CPCAP_AUDIO_OUT_SET_OUTPUT: - if (arg > CPCAP_AUDIO_OUT_MAX) { - pr_err("%s: invalid audio-output selector %ld\n", - __func__, arg); + if (copy_from_user(&out, (const void __user *)arg, + sizeof(out))) { + rc = -EFAULT; + goto done; + } + if (out.id > CPCAP_AUDIO_OUT_MAX) { + pr_err("%s: invalid audio-output selector %d\n", + __func__, out.id); rc = -EINVAL; goto done; } - switch (arg) { + switch (out.id) { case CPCAP_AUDIO_OUT_SPEAKER: pr_info("%s: setting output path to %s\n", __func__, pdata->speaker->name); cpcap_audio_set(pdata->headset, 0); - cpcap_audio_set(pdata->speaker, 1); + cpcap_audio_set(pdata->speaker, out.on); break; case CPCAP_AUDIO_OUT_HEADSET: pr_info("%s: setting output path to %s\n", __func__, pdata->headset->name); cpcap_audio_set(pdata->speaker, 0); - cpcap_audio_set(pdata->headset, 1); + cpcap_audio_set(pdata->headset, out.on); break; } - current_output = arg; + current_output = out.id; break; case CPCAP_AUDIO_OUT_GET_OUTPUT: - if (copy_to_user((void *)arg, ¤t_output, + if (copy_to_user((void __user *)arg, ¤t_output, sizeof(unsigned int))) rc = -EFAULT; break; @@ -187,7 +193,7 @@ static long cpcap_audio_ctl_ioctl(struct file *file, unsigned int cmd, current_input = arg; break; case CPCAP_AUDIO_IN_GET_INPUT: - if (copy_to_user((void *)arg, ¤t_input, + if (copy_to_user((void __user *)arg, ¤t_input, sizeof(unsigned int))) rc = -EFAULT; break; @@ -222,14 +228,14 @@ static long cpcap_audio_ctl_ioctl(struct file *file, unsigned int cmd, current_in_volume = arg; break; case CPCAP_AUDIO_OUT_GET_VOLUME: - if (copy_to_user((void *)arg, ¤t_volume, + if (copy_to_user((void __user *)arg, ¤t_volume, sizeof(unsigned int))) { rc = -EFAULT; goto done; } break; case CPCAP_AUDIO_IN_GET_VOLUME: - if (copy_to_user((void *)arg, ¤t_in_volume, + if (copy_to_user((void __user *)arg, ¤t_in_volume, sizeof(unsigned int))) { rc = -EFAULT; goto done; diff --git a/include/linux/cpcap_audio.h b/include/linux/cpcap_audio.h index 12b219325a1a..50097231b276 100644 --- a/include/linux/cpcap_audio.h +++ b/include/linux/cpcap_audio.h @@ -27,7 +27,13 @@ #define CPCAP_AUDIO_OUT_HEADSET 1 #define CPCAP_AUDIO_OUT_MAX 1 -#define CPCAP_AUDIO_OUT_SET_OUTPUT _IOW(CPCAP_AUDIO_MAGIC, 0, unsigned int) +struct cpcap_audio_output { + int id; /* e.g., CPCAP_AUDIO_OUT_SPEAKER */ + int on; +}; + +#define CPCAP_AUDIO_OUT_SET_OUTPUT _IOW(CPCAP_AUDIO_MAGIC, 0, \ + struct cpcap_audio_output *) #define CPCAP_AUDIO_OUT_VOL_MIN 0 #define CPCAP_AUDIO_OUT_VOL_MAX 15 -- 2.34.1