Esempio n. 1
0
int msm_chg_usb_charger_disconnected(void)
{
    int rc = 0;
    struct hsusb_start_req {
        struct rpc_request_hdr hdr;
    } req;

    if (!chg_ep || IS_ERR(chg_ep))
        return -EAGAIN;
    rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_charger_disconnected_proc,
                      &req, sizeof(req), 5 * HZ);

    if (rc < 0) {
        pr_err("%s: charger_disconnected failed! rc = %d\n",
               __func__, rc);
    } else
        pr_debug("msm_chg_usb_charger_disconnected\n");

    return rc;
}
Esempio n. 2
0
static long snd_agc_enable(unsigned long arg)
{
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	struct snd_agc_ctl_msg agc_msg;
	int rc = 0;

	if ((arg != 1) && (arg != 0))
		return -EINVAL;

	agc_msg.args.agc_ctl = cpu_to_be32(arg);
	agc_msg.args.cb_func = -1;
	agc_msg.args.client_data = 0;

	MM_DBG("snd_agc_ctl %ld,%d\n", arg, agc_msg.args.agc_ctl);

	rc = msm_rpc_call(snd_sys->ept,
		SND_AGC_CTL_PROC,
		&agc_msg, sizeof(agc_msg), 5 * HZ);
	return rc;
}
Esempio n. 3
0
int msm_chg_usb_i_is_not_available(void)
{
	int rc = 0;
	struct hsusb_start_req {
		struct rpc_request_hdr hdr;
	} req;

	if (!chg_ep || IS_ERR(chg_ep))
		return -EAGAIN;
	rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_i_is_not_available_proc,
			&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		printk(KERN_ERR "%s: charger_i_not_available failed! rc ="
			"%d \n", __func__, rc);
	} else
		printk(KERN_INFO "msm_chg_usb_i_is_not_available\n");

	return rc;
}
Esempio n. 4
0
static long snd_cad_dev_enable(const char *arg)
{
	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
	struct snd_cad_set_device_msg dmsg;
	struct msm_cad_device_config dev;
	int rc = 0;


	rc = sscanf(arg, "%d %d %d %d", &dev.device.rx_device,
			&dev.device.tx_device, &dev.ear_mute, &dev.mic_mute);
	if (rc != 4) {
		MM_ERR("Invalid arguments. Usage: <rx_device> <tx_device> "\
			"<ear_mute> <mic_mute>\n");
		rc = -EINVAL;
		return rc;
	}
	dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
	dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
	dmsg.args.device.pathtype = cpu_to_be32(CAD_DEVICE_PATH_RX_TX);
	dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
	dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
	if (check_mute(dev.ear_mute) < 0 ||
			check_mute(dev.mic_mute) < 0) {
		MM_ERR("snd_cad_ioctl set device: invalid mute status\n");
		rc = -EINVAL;
		return rc;
	}
	dmsg.args.cb_func = -1;
	dmsg.args.client_data = 0;
	curr_dev.tx_dev = dev.device.tx_device;
	curr_dev.rx_dev = dev.device.rx_device;

	MM_INFO("snd_cad_set_device %d %d %d %d\n", dev.device.rx_device,
			dev.device.tx_device, dev.ear_mute, dev.mic_mute);

	rc = msm_rpc_call(snd_cad_sys->ept,
		SND_CAD_SET_DEVICE_PROC,
		&dmsg, sizeof(dmsg), 5 * HZ);
	return rc;
}
int msm_hsusb_send_serial_number(const char *serial_number)
{
	int rc = 0, serial_len, rlen;
	struct hsusb_send_sn_req {
		struct rpc_request_hdr hdr;
		uint32_t length;
		char sn[0];
	} *req;

	if (!usb_ep || IS_ERR(usb_ep)) {
		pr_err("%s: rpc connect failed: rc = %ld\n",
			__func__, PTR_ERR(usb_ep));
		return -EAGAIN;
	}

	/*
	 * USB driver passes null terminated string to us. Modem processor
	 * expects serial number to be 32 bit aligned.
	 */
	serial_len  = strlen(serial_number)+1;
	rlen = sizeof(struct rpc_request_hdr) + sizeof(uint32_t) +
			((serial_len + 3) & ~3);

	req = kmalloc(rlen, GFP_KERNEL);
	if (!req)
		return -ENOMEM;

	req->length = cpu_to_be32(serial_len);
	strncpy(req->sn , serial_number, serial_len);
	rc = msm_rpc_call(usb_ep, usb_rpc_ids.update_serial_num,
				req, rlen, 5 * HZ);
	if (rc < 0)
		pr_err("%s: rpc call failed! error: %d\n",
			__func__, rc);
	else
		pr_debug("%s: rpc call success\n", __func__);

	kfree(req);
	return rc;
}
int msm_chg_usb_charger_connected(uint32_t device)
{
	int rc = 0;
	struct hsusb_start_req {
		struct rpc_request_hdr hdr;
		uint32_t otg_dev;
	} req;

	if (!chg_ep || IS_ERR(chg_ep))
		return -EAGAIN;
	req.otg_dev = cpu_to_be32(device);
	rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_charger_connected_proc,
			&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		printk(KERN_ERR "%s: charger_connected failed! rc = %d\n",
			__func__, rc);
	} else
		printk(KERN_INFO "msm_chg_usb_charger_connected\n");

	return rc;
}
Esempio n. 7
0
static int snd_msm_device_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	struct snd_start_req {
		struct rpc_request_hdr hdr;
		uint32_t rpc_snd_device;
		uint32_t snd_mute_ear_mute;
		uint32_t snd_mute_mic_mute;
		uint32_t callback_ptr;
		uint32_t client_data;
	} req;

	snd_rpc_ids.device = (int)ucontrol->value.integer.value[0];
	req.hdr.type = 0;
	req.hdr.rpc_vers = 2;

	req.rpc_snd_device = cpu_to_be32(snd_rpc_ids.device);
	req.snd_mute_ear_mute =
		cpu_to_be32((int)ucontrol->value.integer.value[1]);
	req.snd_mute_mic_mute =
		cpu_to_be32((int)ucontrol->value.integer.value[2]);
	req.callback_ptr = -1;
	req.client_data = cpu_to_be32(0);

	req.hdr.prog = snd_rpc_ids.prog;
	req.hdr.vers = snd_rpc_ids.vers;

	rc = msm_rpc_call(snd_ep, snd_rpc_ids.rpc_set_snd_device ,
			&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
			__func__, rc);
	} else
		printk(KERN_INFO "snd device connected \n");

	return rc;
}
int msm_chg_usb_i_is_available(uint32_t sample)
{
	int rc = 0;
	struct hsusb_start_req {
		struct rpc_request_hdr hdr;
		uint32_t i_ma;
	} req;

	if (!chg_ep || IS_ERR(chg_ep))
		return -EAGAIN;
	req.i_ma = cpu_to_be32(sample);
	rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_i_is_available_proc,
			&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		printk(KERN_ERR "%s: charger_i_available failed! rc = %d\n",
			__func__, rc);
	} else
		pr_info("msm_chg_usb_i_is_available(%u)\n", sample);

	return rc;
}
Esempio n. 9
0
static void internal_phy_reset(void)
{
	struct msm_rpc_endpoint *usb_ep;
	int rc;
	struct hsusb_phy_start_req {
		struct rpc_request_hdr hdr;
	} req;

	printk(KERN_INFO "msm_hsusb_phy_reset\n");

	usb_ep = msm_rpc_connect(HSUSB_API_PROG, HSUSB_API_VERS, 0);
	if (IS_ERR(usb_ep)) {
		printk(KERN_ERR "%s: init rpc failed! error: %ld\n",
				__func__, PTR_ERR(usb_ep));
		return;
	}
	rc = msm_rpc_call(usb_ep, HSUSB_API_INIT_PHY_PROC,
			&req, sizeof(req), 5 * HZ);
	if (rc < 0)
		printk(KERN_ERR "%s: rpc call failed! (%d)\n", __func__, rc);

	msm_rpc_close(usb_ep);
}
int msm_chg_usb_i_is_not_available(void)
{
	int rc = 0;

#ifdef CONFIG_USE_PMIC_CHARGING_ON_AMSS
	struct hsusb_start_req {
		struct rpc_request_hdr hdr;
	} req;

	if (!chg_ep || IS_ERR(chg_ep))
		return -EAGAIN;
	rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_i_is_not_available_proc,
			&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		pr_err("%s: charger_i_not_available failed! rc ="
			"%d \n", __func__, rc);
	} else
		pr_debug("msm_chg_usb_i_is_not_available\n");
#endif

	return rc;
}
Esempio n. 11
0
static long snd_cad_vol_enable(const char *arg)
{
	struct snd_cad_sys_ctxt *snd_cad_sys = &the_snd_cad_sys;
	struct snd_cad_set_volume_msg vmsg;
	struct msm_cad_volume_config vol;
	int rc = 0;

	rc = sscanf(arg, "%d %d %d %d", &vol.device.rx_device,
			&vol.device.tx_device, &vol.method, &vol.volume);
	if (rc != 4) {
		MM_ERR("Invalid arguments. Usage: <rx_device> <tx_device>" \
			"method> <volume>\n");
		rc = -EINVAL;
		return rc;
	}

	vmsg.args.device.rx_device = cpu_to_be32(vol.device.rx_device);
	vmsg.args.device.tx_device = cpu_to_be32(vol.device.tx_device);
	vmsg.args.method = cpu_to_be32(vol.method);
	if (vol.method != SND_METHOD_VOICE) {
		MM_ERR("snd_cad_ioctl set volume: invalid method\n");
		rc = -EINVAL;
		return rc;
	}

	vmsg.args.volume = cpu_to_be32(vol.volume);
	vmsg.args.cb_func = -1;
	vmsg.args.client_data = 0;

	MM_DBG("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
			vol.device.rx_device, vol.method, vol.volume);

	rc = msm_rpc_call(snd_cad_sys->ept,
		SND_CAD_SET_VOLUME_PROC,
		&vmsg, sizeof(vmsg), 5 * HZ);
	return rc;
}
Esempio n. 12
0
int __init rpc_nv(uint32_t proc, uint32_t d1, uint32_t d2, uint32_t d3,
			uint32_t d4, uint32_t d5, uint32_t d6)
{
	struct msm_rpc_endpoint *mmoc_ep;
	int rc;
	struct mmoc_req {
		struct rpc_request_hdr hdr;
		uint32_t data[6];
	} req;

	printk(KERN_INFO "%s: proc: %02x\n", __func__, proc);
	mutex_lock(&mmoc_mutex);

	req.data[0] = cpu_to_be32(d1);
	req.data[1] = cpu_to_be32(d2);
	req.data[2] = cpu_to_be32(d3);
	req.data[3] = cpu_to_be32(d4);
	req.data[4] = cpu_to_be32(d5);
	req.data[5] = cpu_to_be32(d6);

	mmoc_ep = msm_rpc_connect(0x3000000e, 0, 0);
	if (IS_ERR(mmoc_ep)) {
		printk(KERN_ERR "%s: init rpc failed! error: %ld\n",
				__func__, PTR_ERR(mmoc_ep));
		goto close;
	}
	rc = msm_rpc_call(mmoc_ep, /*proc*/ proc,
			&req, sizeof(req), 5 * HZ);
	if (rc < 0)
		printk(KERN_ERR "%s: rpc call failed! (%d)\n", __func__, rc);

close:
	msm_rpc_close(mmoc_ep);
	mutex_unlock(&mmoc_mutex);
	printk(KERN_INFO "%s: exiting\n", __func__);
	return rc;
}
/* rpc call for vbus shutdown */
int msm_hsusb_vbus_shutdown(void)
{
	int rc = 0;
	struct hsusb_phy_start_req {
		struct rpc_request_hdr hdr;
	} req;

	if (!usb_ep || IS_ERR(usb_ep)) {
		printk(KERN_ERR "%s: vbus_shutdown rpc failed before call,"
			"rc = %ld\n", __func__, PTR_ERR(usb_ep));
		return -EAGAIN;
	}

	rc = msm_rpc_call(usb_ep, usb_rpc_ids.vbus_pwr_down,
		&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		printk(KERN_ERR "%s: vbus_shutdown failed! rc = %d\n",
			__func__, rc);
	} else
		printk(KERN_INFO "msm_hsusb_vbus_shutdown\n");

	return rc;
}
/* rpc call for vbus powerup */
int msm_hsusb_vbus_powerup(void)
{
	int rc = 0;
	struct hsusb_phy_start_req {
		struct rpc_request_hdr hdr;
	} req;

	if (!usb_ep || IS_ERR(usb_ep)) {
		pr_err("%s: vbus_powerup rpc failed before call,"
			"rc = %ld\n", __func__, PTR_ERR(usb_ep));
		return -EAGAIN;
	}

	rc = msm_rpc_call(usb_ep, usb_rpc_ids.vbus_pwr_up,
		&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		pr_err("%s: vbus_powerup failed! rc = %d\n",
			__func__, rc);
	} else
		pr_debug("msm_hsusb_vbus_powerup\n");

	return rc;
}
Esempio n. 15
0
static int shcamled_remote_a2m_null(void)
{
    int ret = -1;

    struct shcamled_req {
        struct rpc_request_hdr hdr;
    } req;

    /* get rpc endpoint */
    if(NULL == endpoint) {
        endpoint = msm_rpc_connect(SHCAMLED_RPC_A2M_PROG,
                                SHCAMLED_RPC_A2M_VERS,
                                0);
/*                                MSM_RPC_UNINTERRUPTIBLE);*/
/*    endpoint = msm_rpc_connect_compatible(
                                SHCAMLED_RPC_A2M_PROG,
                                SHCAMLED_RPC_A2M_VERS, 0);*/
    }
    if(IS_ERR(endpoint)) {
        ret = -1;
        printk(KERN_ERR "[%s]:[%d] ret=%d \n", __func__, __LINE__, ret);
    }
    else {
        /* rpc event send */
        ret = msm_rpc_call(endpoint, SHCAMLED_RPC_A2M_ONCRPC_NULL_PROC,
                            &req, sizeof(req), SHCAMLED_RPC_A2M_TIMEOUT);
        if(0 > ret) {
            printk(KERN_ERR "[%s]:[%d] ret=%d \n", __func__, __LINE__, ret);
        }
        else {
            ret = 0;
        }
    }

    return ret;
}
Esempio n. 16
0
static int snd_msm_device_vol_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;

	struct snd_cad_set_volume_msg {
		struct rpc_request_hdr hdr;
		struct rpc_cad_set_volume_args args;
	} vmsg;

	vmsg.args.device.rx_device
		= cpu_to_be32(snd_rpc_ids.device.rx_device);
	vmsg.args.device.tx_device
		= cpu_to_be32(snd_rpc_ids.device.tx_device);
	vmsg.args.method = cpu_to_be32(SND_METHOD_VOICE);
	vmsg.args.volume = cpu_to_be32(ucontrol->value.integer.value[0]);
	vmsg.args.cb_func = -1;
	vmsg.args.client_data = 0;

	rc = msm_rpc_call(snd_ep, snd_rpc_ids.rpc_set_device_vol ,
			&vmsg, sizeof(vmsg), 5 * HZ);

	if (rc < 0) {
		pr_err("%s: snd rpc call failed! rc = %d\n",
			__func__, rc);
	} else {
		pr_debug("%s:rx device [%d]", __func__,
			snd_rpc_ids.device.rx_device);
		pr_debug("%s:tx device [%d]", __func__,
			snd_rpc_ids.device.tx_device);
		pr_debug("%s:volume set to [%ld]\n", __func__,
			snd_rpc_ids.rpc_set_device_vol);
	}

	return rc;
}
Esempio n. 17
0
/* rpc call for phy_reset */
void msm_hsusb_phy_reset(void)
{
	int rc = 0;
	struct hsusb_phy_start_req {
		struct rpc_request_hdr hdr;
	} req;

	if (!usb_ep || IS_ERR(usb_ep)) {
		pr_err("%s: phy_reset rpc failed before call,"
			"rc = %ld\n", __func__, PTR_ERR(usb_ep));
		return;
	}

	rc = msm_rpc_call(usb_ep, usb_rpc_ids.init_phy,
				&req, sizeof(req), 5 * HZ);

	if (rc < 0) {
		pr_err("%s: phy_reset rpc failed! rc = %d\n",
			__func__, rc);
	} else
		pr_info("msm_hsusb_phy_reset\n");

	return;
}
Esempio n. 18
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	int data1, data2;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		dev.bluetooth_id = 0;
		dmsg.args.bluetooth_id = cpu_to_be32(dev.bluetooth_id);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);
		//printk("[Aaron][%s] snd_set_device %d %d %d\r\n", __func__, dev.device,
		//		dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		//printk("[Aaron][%s] rc=%x\r\n", __func__, rc);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		// Uper layer will send volume as 0,1,3,4,6,7
		// But L1 level is 0~6, 6=7.
		// We do not want 0 as mute, so shift 0 to 1.
		// Aaron Chen 2010.08.23
		if ((vol.device != 33) && (vol.device != 34))//FM needs volume 0 for mute brad 
		{
		    if (vol.volume == 0)
		    {
			vol.volume = 1;
		    }
		    else if (vol.volume == 1)
		    {
			vol.volume = 2;
		    }
		    else if (vol.volume == 6)
		    {
			vol.volume = 5;
		    }
		    else if (vol.volume == 7)
		    {
			vol.volume = 6;
		    }
		}
		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);
		//printk("[Aaron][%s] snd_set_volume %d %d %d %d\r\n", __func__, vol.device, vol.method, vol.volume, vmsg.args.volume);

		//printk("[Aaron][%s] PCOM_CCI_SET_AUX_PGA_GAIN(138)=%d\r\n", __func__, PCOM_CCI_SET_AUX_PGA_GAIN);
		if ((vol.device == 33) || (vol.device == 34))
		{
			#if 0
			data1 = 0;
			data2 = 3000;
			rc = msm_proc_comm(PCOM_CCI_VIBRATE, &data1, &data2);
			printk("[Aaron][%s] msm_proc_comm(PCOM_CCI_VIBRATE, 7, 0) rc=%d\r\n", __func__, rc);
			#endif
			
			data1 = vol.volume;
			data2 = vol.volume;
			rc = msm_proc_comm(PCOM_CCI_SET_AUX_PGA_GAIN, &data1, &data2);
			//printk("[Aaron][%s] msm_proc_comm(PCOM_CCI_SET_AUX_PGA_GAIN, 7, 0) rc=%d\r\n", __func__, rc);
		}

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 19
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
#if defined(CONFIG_MACH_KYLE_CHN) || defined(CONFIG_MACH_KYLE_I)
			if (vol.method != SND_METHOD_MIDI){
#endif				
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
#if defined(CONFIG_MACH_KYLE_CHN) || defined(CONFIG_MACH_KYLE_I)
				}
#endif				
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 20
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;

	struct msm_snd_set_voccal_param		 voccal;
	struct snd_set_voccal_param_msg		 cmsg;

	struct msm_snd_set_voccal_iir_param voccaliir;
	struct snd_set_voccal_iir_param_msg cimsg;	

	struct msm_snd_set_next_ec_param nextec;
	struct snd_set_next_ec_param_msg nmsg;

	struct msm_snd_set_rx_volume_param rxvol;
	struct snd_set_rx_volume_param_msg rmsg;	

	struct msm_snd_set_dtmf_volume_param dtmfvol;	
	struct snd_set_dtmf_volume_param_msg fmsg;

	struct msm_snd_set_pad_value_param padvalue;
	struct snd_set_pad_value_param_msg pmsg;

	struct msm_snd_set_loopback_mode_param loopback;
	struct snd_set_loopback_mode_msg lmsg;	

	struct snd_write_efs_msg wmsg;

	struct msm_snd_set_micamp_gain_param micampgain;
	struct snd_set_micamp_gain_param_msg mamsg;

	struct msm_snd_set_amp_gain_param ampgain;
	struct snd_set_set_amp_gain_param_msg amsg;

	struct msm_snd_set_fm_radio_vol_param fmradiovol;
	struct snd_set_fm_radio_vol_msg fmrmsg;	

	struct msm_snd_set_voice_clarity_param voiceclarity;
	struct snd_set_voice_clarity_msg vcmsg;


	//int fm_radio_vol;
	int wefs;

	struct snd_set_voccal_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_voccal;
	}crep;	

	struct snd_set_voccal_iir_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_voccal_iir;
	}cirep;	

	struct snd_set_nextec_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_nextec;
	}nrep;	

	struct snd_set_rxvol_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_rxvol;
	}rrep;	

	struct snd_set_dtmfvol_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_dtmfvol;
	}frep;	

	struct snd_set_padvalue_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_padvalue;
	}prep;	

	struct snd_set_loopback_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_mode;
	}lrep;	

	struct snd_write_efs_rep {
		struct rpc_reply_hdr hdr;
		uint32_t result;
	}wrep;	

	struct snd_set_amp_gain_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_gainvalue;
	}arep;	

	struct snd_set_voice_clarity_param_rep {
		struct rpc_reply_hdr hdr;
		uint32_t get_mode;
	}vcrep;	

	int rc = 0;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;
		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

#if defined (CONFIG_MACH_MSM7X27_SWIFT)
	case SND_SET_VOCCAL_PARAM:
		if (copy_from_user(&voccal, (void __user*) arg, sizeof(voccal))){
				pr_err("snd_ioctl set vocal_param: invalid pointer.\n");
				rc = -EFAULT;
				break;
		}
		cmsg.args.voc_codec = cpu_to_be32(voccal.voc_codec);
		cmsg.args.voccal_param_type = cpu_to_be32(voccal.voccal_param_type);
		cmsg.args.get_flag = cpu_to_be32(voccal.get_flag);
		cmsg.args.param_val = cpu_to_be32(voccal.param_val);
		cmsg.args.cb_func = -1;
		cmsg.args.client_data = 0;
		pr_info("snd_set_voccal_param %d %d %d %d\n", voccal.voc_codec,
						voccal.voccal_param_type, voccal.get_flag, voccal.param_val);

		rc = msm_rpc_call_reply(snd->ept,
						SND_SET_VOCCAL_PARAM_PROC,
						&cmsg, sizeof(cmsg), &crep, sizeof(crep), 5*HZ);
		if (rc < 0){
				printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
				voccal.get_param = be32_to_cpu(crep.get_voccal);
				printk(KERN_INFO "%s:voccal ->%d\n", __func__, voccal.get_param);
				if (copy_to_user((void __user*)arg, &voccal, sizeof(voccal))){
						pr_err("snd_ioctl get voccal: invalid write pointer.\n");
						rc = -EFAULT;
				}
		}
		break;

case SND_SET_VOCCAL_IIR_PARAM:
	if (copy_from_user(&voccaliir, (void __user *) arg, sizeof(voccaliir))) {
		pr_err("snd_ioctl set_voccal_iir_param: invalid pointer.\n");
		rc = -EFAULT;
		break;
	}
	cimsg.args.voc_codec = cpu_to_be32(voccaliir.voc_codec);
	cimsg.args.voccal_iir_param_type = cpu_to_be32(voccaliir.voccal_iir_param_type);
	cimsg.args.get_flag = cpu_to_be32(voccaliir.get_flag);
	cimsg.args.param_val = cpu_to_be32(voccaliir.param_val);
	cimsg.args.cb_func = -1;
	cimsg.args.client_data = 0;
	pr_info("set_voccal_iir_param %d %d %d\n", voccaliir.voc_codec,
					 voccaliir.voccal_iir_param_type, voccaliir.param_val);

	rc = msm_rpc_call_reply(snd->ept,
		SND_SET_VOCCAL_IIR_PARAM_PROC,
		&cimsg, sizeof(cimsg),&cirep, sizeof(cirep), 5 * HZ);
	if (rc < 0){
		printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
	}
	else
	{
		voccaliir.get_param = be32_to_cpu(cirep.get_voccal_iir);
		printk(KERN_INFO "%s:voccal_iir ->%d\n", __func__, voccaliir.get_param);
		if (copy_to_user((void __user *)arg, &voccaliir, sizeof(voccaliir))) {
			pr_err("snd_ioctl get voccal iir: invalid write pointer.\n");
			rc = -EFAULT;
		}
	}
	break;

case SND_SET_NEXT_EC_PARAM:
	if (copy_from_user(&nextec, (void __user *) arg, sizeof(nextec))) {
		pr_err("snd_ioctl set_next_ec_param: invalid pointer.\n");
		rc = -EFAULT;
		break;
	}
	nmsg.args.ec_mode = cpu_to_be32(nextec.ec_mode);
	nmsg.args.ec_param_type = cpu_to_be32(nextec.ec_param_type);
	nmsg.args.get_flag = cpu_to_be32(nextec.get_flag);
	nmsg.args.param_val = cpu_to_be32(nextec.param_val);
	nmsg.args.cb_func = -1;
	nmsg.args.client_data = 0;
	pr_info("set_next_ec_param %d %d %d\n", nextec.ec_mode,
					 nextec.ec_param_type, nextec.param_val);

	rc = msm_rpc_call_reply(snd->ept,
		SND_SET_NEXT_EC_PARAM_PROC,
		&nmsg, sizeof(nmsg),&nrep, sizeof(nrep), 5 * HZ);
	if (rc < 0){
		printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
	}
	else
	{
		nextec.get_param = be32_to_cpu(nrep.get_nextec);
		printk(KERN_INFO "%s:nextec ->%d\n", __func__, nextec.get_param);
		if (copy_to_user((void __user *)arg, &nextec, sizeof(nextec))) {
			pr_err("snd_ioctl get next ec: invalid write pointer.\n");
			rc = -EFAULT;
		}
	}
	break;

	case SND_SET_RX_VOLUME:
		if (copy_from_user(&rxvol, (void __user *) arg, sizeof(rxvol))) {
			pr_err("snd_ioctl set_rx_volume: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		rmsg.args.device = cpu_to_be32(rxvol.device);
		rmsg.args.method = cpu_to_be32(rxvol.method);
		rmsg.args.idx = cpu_to_be32(rxvol.idx);
		rmsg.args.get_flag = cpu_to_be32(rxvol.get_flag);
		rmsg.args.param_val = cpu_to_be32(rxvol.param_val);
		rmsg.args.cb_func = -1;
		rmsg.args.client_data = 0;
		pr_info("set_rx_volume %d %d %d %d\n", rxvol.device,
						 rxvol.method, rxvol.idx, rxvol.param_val);

		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_RX_VOLUME_PROC,
			&rmsg, sizeof(rmsg),&rrep, sizeof(rrep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			rxvol.get_param = be32_to_cpu(rrep.get_rxvol);
			printk(KERN_INFO "%s:rx vol ->%d\n", __func__, rxvol.get_param);
			if (copy_to_user((void __user *)arg, &rxvol, sizeof(rxvol))) {
				pr_err("snd_ioctl get rx vol: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_DTMF_VOLUME:
		if (copy_from_user(&dtmfvol, (void __user *) arg, sizeof(dtmfvol))) {
			pr_err("snd_ioctl set_dtmf_volume: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		fmsg.args.device = cpu_to_be32(dtmfvol.device);
		fmsg.args.method = cpu_to_be32(dtmfvol.method);
		fmsg.args.idx = cpu_to_be32(dtmfvol.idx);
		fmsg.args.get_flag = cpu_to_be32(dtmfvol.get_flag);
		fmsg.args.param_val = cpu_to_be32(dtmfvol.param_val);
		fmsg.args.cb_func = -1;
		fmsg.args.client_data = 0;
		pr_info("set_dtmf_volume %d %d %d %d\n", dtmfvol.device,
						 dtmfvol.method, dtmfvol.idx, dtmfvol.param_val);

		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_DTMF_VOLUME_PROC,
			&fmsg, sizeof(fmsg),&frep, sizeof(frep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			dtmfvol.get_param = be32_to_cpu(frep.get_dtmfvol);
			printk(KERN_INFO "%s:rx vol ->%d\n", __func__, dtmfvol.get_param);
			if (copy_to_user((void __user *)arg, &dtmfvol, sizeof(dtmfvol))) {
				pr_err("snd_ioctl get dtmf vol: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_PAD_VALUE:
		if (copy_from_user(&padvalue, (void __user *) arg, sizeof(padvalue))) {
			pr_err("snd_ioctl set_pad_value: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		pmsg.args.device = cpu_to_be32(padvalue.device);
		pmsg.args.method = cpu_to_be32(padvalue.method);
		pmsg.args.idx = cpu_to_be32(padvalue.idx);
		pmsg.args.get_flag = cpu_to_be32(padvalue.get_flag);
		pmsg.args.param_val = cpu_to_be32(padvalue.param_val);
		pmsg.args.cb_func = -1;
		pmsg.args.client_data = 0;
		pr_info("set_pad_value %d %d %d %d\n", padvalue.device,
						 padvalue.method, padvalue.idx, padvalue.param_val);

		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_PAD_VALUE_PROC,
			&pmsg, sizeof(pmsg),&prep, sizeof(prep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			padvalue.get_param = be32_to_cpu(prep.get_padvalue);
			printk(KERN_INFO "%s:rx vol ->%d\n", __func__, padvalue.get_param);
			if (copy_to_user((void __user *)arg, &padvalue, sizeof(padvalue))) {
				pr_err("snd_ioctl get pad value: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_LOOPBACK_MODE:
		if (copy_from_user(&loopback, (void __user *) arg, sizeof(loopback))) {
			pr_err("snd_ioctl set amp_gain: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		lmsg.args.mode = cpu_to_be32(loopback.mode);
		lmsg.args.cb_func = -1;
		lmsg.args.client_data = 0;
		pr_info("set_loopback_mode %d \n", loopback.mode);
					
		rc = msm_rpc_call(snd->ept,
			SND_SET_LOOPBACK_MODE_PROC,
			&lmsg, sizeof(lmsg), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			loopback.get_param = be32_to_cpu(lrep.get_mode);
			printk(KERN_INFO "%s:loopback mode ->%d\n", __func__, loopback.get_param);
			if (copy_to_user((void __user *)arg, &loopback, sizeof(loopback))) {
				pr_err("snd_ioctl get loopback mode: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;

	case SND_WRITE_EFS:
		wmsg.args.cb_func = -1;
		wmsg.args.client_data = 0;
		pr_info("set_write_efs \n");

		rc = msm_rpc_call_reply(snd->ept,
			SND_WRITE_EFS_PROC,
			&wmsg, sizeof(wmsg),&wrep, sizeof(wrep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		} 
		else
		{
			wefs = be32_to_cpu(wrep.result);
			printk(KERN_INFO "%s:loopback mode ->%d\n", __func__, wefs);
			if (copy_to_user((void __user *)arg, &wefs, sizeof(wefs))) {
				pr_err("snd_ioctl write efs: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_MICAMP_GAIN:
		if (copy_from_user(&micampgain, (void __user *) arg, sizeof(micampgain))) {
			pr_err("snd_ioctl set_pad_value: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		mamsg.args.voc_codec = cpu_to_be32(micampgain.voc_codec);
		mamsg.args.mic_channel = cpu_to_be32(micampgain.mic_channel);
		mamsg.args.get_flag = cpu_to_be32(micampgain.get_flag);
		mamsg.args.get_param = cpu_to_be32(micampgain.value);
		mamsg.args.cb_func = -1;
		mamsg.args.client_data = 0;
		pr_info("SND_SET_MICAMP_GAIN %d %d %d %d\n", micampgain.voc_codec,
						 micampgain.mic_channel, micampgain.get_flag, micampgain.get_param);

		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_MICAMP_GAIN_PROC,
			&mamsg, sizeof(mamsg),&mrep, sizeof(mrep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			micampgain.get_param = be32_to_cpu(mrep.get_gainvalue);
			printk(KERN_INFO "%s:rx vol ->%d\n", __func__, micampgain.get_param);
			if (copy_to_user((void __user *)arg, &micampgain, sizeof(micampgain))) {
				pr_err("snd_ioctl get pad value: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_AMP_GAIN:
		if (copy_from_user(&ampgain, (void __user *) arg, sizeof(ampgain))) {
			pr_err("snd_ioctl set amp_gain: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		amsg.args.voc_codec = cpu_to_be32(ampgain.voc_codec);
		amsg.args.gain_type = cpu_to_be32(ampgain.gain_type);
		amsg.args.get_flag = cpu_to_be32(ampgain.get_flag);
		amsg.args.get_param = cpu_to_be32(ampgain.value);
		amsg.args.cb_func = -1;
		amsg.args.client_data = 0;
		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_AMP_GAIN_PROC,
			&amsg, sizeof(amsg),&arep, sizeof(arep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			ampgain.get_param = be32_to_cpu(arep.get_gainvalue);
			printk(KERN_INFO "%s:rx vol ->%d\n", __func__, ampgain.get_param);
			if (copy_to_user((void __user *)arg, &ampgain, sizeof(ampgain))) {
				pr_err("snd_ioctl get pad value: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
			
		if (copy_to_user((void __user *)arg, &ampgain, sizeof(ampgain))) {
			pr_err("snd_ioctl get amp gain: invalid write pointer.\n");
			rc = -EFAULT;
		}
		break;		

	case SND_WRITE_MEM:	
		wmsg.args.cb_func = -1;
		wmsg.args.client_data = 0;
		pr_info("set_write_efs \n");

		rc = msm_rpc_call_reply(snd->ept,
			SND_WRITE_MEM_PROC,
			&wmsg, sizeof(wmsg),&wrep, sizeof(wrep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		} 
		else
		{
			wefs = be32_to_cpu(wrep.result);
			printk(KERN_INFO "%s:loopback mode ->%d\n", __func__, wefs);
			if (copy_to_user((void __user *)arg, &wefs, sizeof(wefs))) {
				pr_err("snd_ioctl write efs: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_FM_RADIO_VOLUME:
		if (copy_from_user(&fmradiovol, (void __user *) arg, sizeof(fmradiovol))) {
			pr_err("snd_ioctl set amp_gain: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		fmrmsg.args.volume = cpu_to_be32(fmradiovol.volume);
		fmrmsg.args.cb_func = -1;
		fmrmsg.args.client_data = 0;

		pr_info("snd_set_fm_radio_volume %d\n", fmradiovol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_FM_RADIO_VOLUME_PROC,
			&fmrmsg, sizeof(fmrmsg), 5 * HZ);
		break;
		
	case SND_SET_VOICE_CLARITY:
		if (copy_from_user(&voiceclarity, (void __user *) arg, sizeof(voiceclarity))) {
			pr_err("snd_ioctl set amp_gain: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}
		vcmsg.args.mode = cpu_to_be32(voiceclarity.mode);
		vcmsg.args.cb_func = -1;
		vcmsg.args.client_data = 0;
		pr_info("set_loopback_mode %d \n", voiceclarity.mode);
					
		rc = msm_rpc_call(snd->ept,
			SND_SET_VOICE_CLARITY_PROC,
			&vcmsg, sizeof(vcmsg), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		}
		else
		{
			voiceclarity.get_param = be32_to_cpu(vcrep.get_mode);
			printk(KERN_INFO "%s:voice clarity mode ->%d\n", __func__, voiceclarity.get_param);
			if (copy_to_user((void __user *)arg, &voiceclarity, sizeof(voiceclarity))) {
				pr_err("snd_ioctl get loopback mode: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;		

	case SND_SET_POWER_OFF:
		wmsg.args.cb_func = -1;
		wmsg.args.client_data = 0;
		pr_info("set_power_off \n");

		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_POWER_OFF_PROC,
			&wmsg, sizeof(wmsg),&wrep, sizeof(wrep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		} 
		else
		{
			wefs = be32_to_cpu(wrep.result);
			if (copy_to_user((void __user *)arg, &wefs, sizeof(wefs))) {
				pr_err("snd_ioctl write efs: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;	

	case SND_SET_FM_RADIO_MULTI_SOUND:
		wmsg.args.cb_func = -1;
		wmsg.args.client_data = 0;
		pr_info("set_fm_radio_multi_sound \n");

		rc = msm_rpc_call_reply(snd->ept,
			SND_SET_FM_RADIO_MULTI_SOUND_PROC,
			&wmsg, sizeof(wmsg),&wrep, sizeof(wrep), 5 * HZ);
		if (rc < 0){
			printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
		} 
		else
		{
			wefs = be32_to_cpu(wrep.result);
			if (copy_to_user((void __user *)arg, &wefs, sizeof(wefs))) {
				pr_err("snd_ioctl set_fm_radio_multi_sound: invalid write pointer.\n");
				rc = -EFAULT;
			}
		}
		break;		
		
#endif 

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 21
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			pr_err("snd_ioctl set device: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			pr_err("snd_ioctl set device: invalid mute status.\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		pr_info("snd_set_device %d %d %d\n", dev.device,
						 dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			pr_err("snd_ioctl set volume: invalid pointer.\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			pr_err("snd_ioctl set volume: invalid method.\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		pr_info("snd_set_volume %d %d %d\n", vol.device,
						vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			pr_err("snd_ioctl get endpoint: invalid pointer.\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	default:
		pr_err("snd_ioctl unknown command.\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 22
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;
	struct snd_set_lb_msg lb_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	uint32_t avc, agc;
	uint32_t set_lb;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		// FM_STEREO_HEADSET -> HEADSET
		if(SND_DEVICE_FM_STEREO_HEADSET_ZTE == dev.device)
			dev.device = 3;

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);
#if 0
		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
#else
		if(SND_DEVICE_FM_STEREO_HEADSET_ZTE == dev.device)
		{
			rc = msm_rpc_call(snd->ept,
				SND_SET_FM_HEADSET_DEVICE_PROC,
				&dmsg, sizeof(dmsg), 5 * HZ);
		}
		else
		{
			rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
        	}
#endif
	        if (dev.device != 28)
        	{
			keep_snd_dev_info[SND_DEV] = dev.device;
              	}
		keep_snd_dev_info[EAR_MUTE] = dev.ear_mute;
		keep_snd_dev_info[MIC_MUTE] = dev.mic_mute;
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;


	case SND_SET_AUDIO_LOOPBACK:
		if (get_user(set_lb, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((set_lb != 1) && (set_lb != 0)) {
			rc = -EINVAL;
			break;
		}

		lb_msg.args.lb_ctl = cpu_to_be32(set_lb);

		lb_msg.args.cb_func = -1;
		lb_msg.args.client_data = 0;

		pr_info("snd_lb_ctl %d\n", set_lb);

		rc = msm_rpc_call(snd->ept,
			SND_AUDIO_LOOPBACK_PROC,
			&lb_msg, sizeof(lb_msg), 5 * HZ);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 23
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;
	struct snd_set_extamp_msg emsg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct msm_snd_extamp_config extamp;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	uint32_t avc, agc;

#ifdef FEATURE_MAX8899_AMP_OFF
	int data1 = 0;
	int data2 = 0;
#endif
	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_ERR("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_ERR("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	case SND_SET_EXTAMP:
		if (copy_from_user(&extamp, (void __user *) arg, sizeof(extamp))) {
			MM_ERR("set extamp: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		emsg.args.device = cpu_to_be32(extamp.device);
		emsg.args.speaker_volume = cpu_to_be32(extamp.speaker_volume);
		emsg.args.headset_volume = cpu_to_be32(extamp.headset_volume);
		emsg.args.cb_func = -1;
		emsg.args.client_data = 0;

		MM_ERR("snd_set_extamp %d %d %d\n", extamp.device,
				extamp.speaker_volume, extamp.headset_volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_EXTAMP_PROC,
			&emsg, sizeof(emsg), 5 * HZ);
		break;
#ifdef CONFIG_MACH_FLIPBOOK		
	case SND_SET_MAIN_MIC:
		if(board_hw_revision>=1)
			rc = gpio_direction_output(89, 0);
		else
			rc = gpio_direction_output(89, 1);
		break;
	case SND_SET_SUB_MIC:
		if(board_hw_revision>=1)
			rc = gpio_direction_output(89, 1);
		else		
			rc = gpio_direction_output(89, 0);
		break;
#else
	case SND_SET_MAIN_MIC:
		rc = gpio_direction_output(89, 1);
		break;
	case SND_SET_SUB_MIC:
		rc = gpio_direction_output(89, 0);
		break;

#endif
#ifdef FEATURE_MAX8899_AMP_OFF
	case SND_MAX8899_AMP_OFF:
		if (copy_from_user(&data1, (void __user *) arg, sizeof(data1))) {
			MM_ERR("amp off: invalid pointer\n");
			rc = -EFAULT;
			break;
		}
		rc = msm_proc_comm(SMEM_PROC_COMM_AMP_OFF, &data1, &data2);
		if(rc < 0)
		{
			printk("%s max8899 amp off proccomm fail\n", __func__);
			return rc;
		}
		MM_ERR("snd_max8899_amp_off %d\n", data1);
		break;
#endif
	default:
		MM_ERR("unknown command %d\n", cmd);
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 24
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
#ifdef CONFIG_HUAWEI_KERNEL
		if (vol.method != SND_METHOD_VOICE&&vol.method != SND_METHOD_MIDI) {
#else
		if (vol.method != SND_METHOD_VOICE) {
#endif

			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}

static int snd_release(struct inode *inode, struct file *file)
{
	struct snd_ctxt *snd = file->private_data;
	int rc;

	mutex_lock(&snd->lock);
	rc = msm_rpc_close(snd->ept);
	if (rc < 0)
		MM_ERR("msm_rpc_close failed\n");
	snd->ept = NULL;
	snd->opened = 0;
	mutex_unlock(&snd->lock);
	return 0;
}
static int snd_sys_release(void)
{
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	int rc = 0;

	mutex_lock(&snd_sys->lock);
	rc = msm_rpc_close(snd_sys->ept);
	if (rc < 0)
		MM_ERR("msm_rpc_close failed\n");
	snd_sys->ept = NULL;
	mutex_unlock(&snd_sys->lock);
	return rc;
}
static int snd_open(struct inode *inode, struct file *file)
{
	struct snd_ctxt *snd = &the_snd;
	int rc = 0;

	mutex_lock(&snd->lock);
	if (snd->opened == 0) {
		if (snd->ept == NULL) {
			snd->ept = msm_rpc_connect_compatible(RPC_SND_PROG,
					RPC_SND_VERS, 0);
			if (IS_ERR(snd->ept)) {
				rc = PTR_ERR(snd->ept);
				snd->ept = NULL;
				MM_ERR("failed to connect snd svc\n");
				goto err;
			}
		}
		file->private_data = snd;
		snd->opened = 1;
	} else {
		MM_ERR("snd already opened\n");
		rc = -EBUSY;
	}

err:
	mutex_unlock(&snd->lock);
	return rc;
}
static int snd_sys_open(void)
{
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	int rc = 0;

	mutex_lock(&snd_sys->lock);
	if (snd_sys->ept == NULL) {
		snd_sys->ept = msm_rpc_connect_compatible(RPC_SND_PROG,
			RPC_SND_VERS, 0);
		if (IS_ERR(snd_sys->ept)) {
			rc = PTR_ERR(snd_sys->ept);
			snd_sys->ept = NULL;
			MM_ERR("failed to connect snd svc\n");
			goto err;
		}
	} else
		MM_DBG("snd already opened\n");

err:
	mutex_unlock(&snd_sys->lock);
	return rc;
}

static struct file_operations snd_fops = {
	.owner		= THIS_MODULE,
	.open		= snd_open,
	.release	= snd_release,
	.unlocked_ioctl	= snd_ioctl,
};

struct miscdevice snd_misc = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= "msm_snd",
	.fops	= &snd_fops,
};

static long snd_agc_enable(unsigned long arg)
{
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	struct snd_agc_ctl_msg agc_msg;
	int rc = 0;

	if ((arg != 1) && (arg != 0))
		return -EINVAL;

	agc_msg.args.agc_ctl = cpu_to_be32(arg);
	agc_msg.args.cb_func = -1;
	agc_msg.args.client_data = 0;

	MM_DBG("snd_agc_ctl %ld,%d\n", arg, agc_msg.args.agc_ctl);

	rc = msm_rpc_call(snd_sys->ept,
		SND_AGC_CTL_PROC,
		&agc_msg, sizeof(agc_msg), 5 * HZ);
	return rc;
}

static long snd_avc_enable(unsigned long arg)
{
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	struct snd_avc_ctl_msg avc_msg;
	int rc = 0;

	if ((arg != 1) && (arg != 0))
		return -EINVAL;

	avc_msg.args.avc_ctl = cpu_to_be32(arg);

	avc_msg.args.cb_func = -1;
	avc_msg.args.client_data = 0;

	MM_DBG("snd_avc_ctl %ld,%d\n", arg, avc_msg.args.avc_ctl);

	rc = msm_rpc_call(snd_sys->ept,
		SND_AVC_CTL_PROC,
		&avc_msg, sizeof(avc_msg), 5 * HZ);
	return rc;
}

static ssize_t snd_agc_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	ssize_t status;
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	int rc = 0;

	rc = snd_sys_open();
	if (rc)
		return rc;

	mutex_lock(&snd_sys->lock);

	if (sysfs_streq(buf, "enable"))
		status = snd_agc_enable(1);
	else if (sysfs_streq(buf, "disable"))
		status = snd_agc_enable(0);
	else
		status = -EINVAL;

	mutex_unlock(&snd_sys->lock);
	rc = snd_sys_release();
	if (rc)
		return rc;

	return status ? : size;
}

static ssize_t snd_avc_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	ssize_t status;
	struct snd_sys_ctxt *snd_sys = &the_snd_sys;
	int rc = 0;

	rc = snd_sys_open();
	if (rc)
		return rc;

	mutex_lock(&snd_sys->lock);

	if (sysfs_streq(buf, "enable"))
		status = snd_avc_enable(1);
	else if (sysfs_streq(buf, "disable"))
		status = snd_avc_enable(0);
	else
		status = -EINVAL;

	mutex_unlock(&snd_sys->lock);
	rc = snd_sys_release();
	if (rc)
		return rc;

	return status ? : size;
}
Esempio n. 25
0
static long snd_cad_ioctl(struct file *file, unsigned int cmd,
		unsigned long arg)
{
	struct snd_cad_set_device_msg dmsg;
	struct snd_cad_set_volume_msg vmsg;

	struct msm_cad_device_config dev;
	struct msm_cad_volume_config vol;
	struct snd_cad_ctxt *snd = file->private_data;
	int rc = 0;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
		dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
		dmsg.args.device.pathtype = cpu_to_be32(dev.device.pathtype);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;
		curr_dev.tx_dev = dev.device.tx_device;
		curr_dev.rx_dev = dev.device.rx_device;
		MM_ERR("snd_cad_set_device %d %d %d %d\n", dev.device.rx_device,
			dev.device.tx_device, dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_CAD_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
		vmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
		vmsg.args.method = cpu_to_be32(vol.method);
#if !defined(CONFIG_MACH_ARUBA_OPEN) && !defined(CONFIG_MACH_ARUBASLIM_OPEN) && !defined(CONFIG_MACH_ARUBA_DUOS_CTC)  \
      && !defined(CONFIG_MACH_KYLEPLUS_CTC) && !defined(CONFIG_MACH_INFINITE_DUOS_CTC) \
      && !defined(CONFIG_MACH_KYLEPLUS_OPEN) && !defined(CONFIG_MACH_BAFFIN_DUOS_CTC) && !defined(CONFIG_MACH_DELOS_DUOS_CTC)
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}
#endif
		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_ERR("snd_cad_set_volume %d %d %d %d\n", vol.device.rx_device,
				vol.device.tx_device, vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_CAD_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);

		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->cad_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	case CAD_SET_MUTE: 
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device.rx_device = cpu_to_be32(dev.device.rx_device);
		dmsg.args.device.tx_device = cpu_to_be32(dev.device.tx_device);
		dmsg.args.device.pathtype = cpu_to_be32(dev.device.pathtype);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_ERR("snd_cad_set_mute %d %d %d %d\n", dev.device.rx_device,
			dev.device.tx_device, dev.ear_mute, dev.mic_mute);
		
		rc = msm_rpc_call(snd->ept,
			SND_CAD_SET_MUTE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 26
0
static void set_pmic_vibrator(void)
{
	static struct msm_rpc_endpoint *vib_endpoint;
	struct pm_vib_mot_set_volt_args {
		struct rpc_request_hdr hdr;
		uint32_t data;
	} req;
	int rc;
	unsigned long flags;
	int kick_time;

	if (!vib_endpoint) {
		int i;
		for (i = 0; i < ARRAY_SIZE(pm_rpc_versions); i++) {
			vib_endpoint = msm_rpc_connect(PM_LIBPROG,
					pm_rpc_versions[i], 0);
			if (IS_ERR(vib_endpoint))
				printk(KERN_INFO \
				"init vib rpc version %d failed!\n", \
				pm_rpc_versions[i]);
			else
				break;
		}
	}

	if (IS_ERR(vib_endpoint)) {
		printk(KERN_ERR "init vib rpc failed!\n");
		vib_endpoint = 0;
		return;
	}
	pr_debug("%s: ON=%d\n", __func__, vibe_state);

	spin_lock_irqsave(&vibe_lock, flags);
	switch (vibe_state) {
	case TASK_KICK_START:
		if (long_vibe_time > STRONG_VIBRATION_TIME) {
			kick_time = STRONG_VIBRATION_TIME;
			long_vibe_time -= STRONG_VIBRATION_TIME;
			vibe_state = TASK_START;
		} else {
			kick_time = long_vibe_time;
			vibe_state = TASK_STOP;
			long_vibe_time = 0;
		}
		req.data = cpu_to_be32(VIBRATOR_LEVEL_STRONG);
		hrtimer_start(&vibe_timer,
			ktime_set(kick_time / 1000,
			(kick_time % 1000) * 1000000), HRTIMER_MODE_REL);

		pr_debug("%s: KICK START for %d ms\n", __func__, kick_time);
		break;
	case TASK_START:
		req.data = cpu_to_be32(PM_VIBRATOR_LEVEL);
		pr_debug("%s: START for %d ms\n", __func__, long_vibe_time);
		hrtimer_start(&vibe_timer,
			ktime_set((long_vibe_time) / 1000,
			((long_vibe_time) % 1000) * 1000000), HRTIMER_MODE_REL);
		long_vibe_time = 0;
		vibe_state = TASK_STOP;
		break;
	case TASK_STOP:
	case TASK_FORCE_STOP:
	default:
		vibe_state = TASK_NONE;
		req.data = cpu_to_be32(0);
	}
	spin_unlock_irqrestore(&vibe_lock, flags);

	rc = msm_rpc_call(vib_endpoint, PM_VIB_MOT_SET_VOLT_PROC, &req,
		sizeof(req), 5 * HZ);
	if (rc)
		printk(KERN_ERR "vib rpc failed! rc=%d\n", rc);
}
Esempio n. 27
0
static void set_pmic_vibrator(int on)
{
	static struct msm_rpc_endpoint *vib_endpoint;
    /* < DTS2012041806002 houming 20120504 begin*/	
	int ret=0;
	/*  DTS2012041806002 houming 20120504 end > */
	struct set_vib_on_off_req {
		struct rpc_request_hdr hdr;
/* < DTS2010080500080 luojianhong 201000817 begin*/
		#ifndef CONFIG_HUAWEI_SETTING_TIMER_FOR_VIBRATOR_OFF
		uint32_t data;
		#else
		uint32_t vib_volt;
		uint32_t vib_time;//vibratting time pass to modem .
		#endif
/*  DTS2010080500080 luojianhong 201000817 end > */
	} req;

	if (!vib_endpoint) {
		vib_endpoint = msm_rpc_connect(PM_LIBPROG, PM_LIBVERS, 0);
		if (IS_ERR(vib_endpoint)) {
			printk(KERN_ERR "init vib rpc failed!\n");
			vib_endpoint = 0;
			return;
		}
	}

/* < DTS2010080500080 luojianhong 201000817 begin*/
	if (on)
	{
		#ifndef CONFIG_HUAWEI_SETTING_TIMER_FOR_VIBRATOR_OFF
		req.data = cpu_to_be32(PMIC_VIBRATOR_LEVEL);
		#else
		req.vib_volt = cpu_to_be32(PMIC_VIBRATOR_LEVEL); 
		req.vib_time = cpu_to_be32(time_value); 
		#endif
	}
	else
	{
		#ifndef CONFIG_HUAWEI_SETTING_TIMER_FOR_VIBRATOR_OFF
		req.data = cpu_to_be32(0);
		#else
		req.vib_volt = cpu_to_be32(0); 
		req.vib_time = cpu_to_be32(0); 
		#endif
	}
/*  DTS2010080500080 luojianhong 201000817 end > */
/*<BU5D07918, sibingsong 20100416 begin*/
#ifndef CONFIG_HUAWEI_FEATURE_VIBRATOR
/*BU5D07918, sibingsong 20100416 end>*/
	msm_rpc_call(vib_endpoint, HTC_PROCEDURE_SET_VIB_ON_OFF, &req,
		sizeof(req), 5 * HZ);
/*<BU5D07918, sibingsong 20100416 begin*/
#else
    /* < DTS2012041806002 houming 20120504 begin*/
	/* Add return value to determine */
	ret=msm_rpc_call(vib_endpoint, HW_PROCEDURE_SET_VIB_ON_OFF, &req,
		sizeof(req), 5 * HZ);
	if(ret)
	{
		printk("%s:msm_rpc_call fail,ret=%d\n",__func__,ret);
	}
	/*  DTS2012041806002 houming 20120504 end > */
#endif
/*BU5D07918, sibingsong 20100416 end>*/
}
Esempio n. 28
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;
        //jrd add
        int spkr_param = 0;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

        //JRD add for speaker pa control
	case SND_SET_PA:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		}

		spkr_param = avc;
		isSpkr = (spkr_param > 1) ? true:false;
		isIncallMode = spkr_param%2;
		MM_INFO("snd_avc_ctl %d; isIncallMode: %d;spkr_param : %d; ===\n", avc,isIncallMode,spkr_param);

		audio_opal_spkr_pa_enable();
		rc = 0;
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 29
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	/*++ Kevin Shiu - 20120612 implement secondary mic test ++*/
	struct msm_snd_info_config info;
	struct snd_set_info_msg imsg;
	/*-- Kevin Shiu - 20120612 implement secondary mic test --*/
	/*++ Kevin Shiu - 20121002 voip mute and change path ++*/
	struct msm_snd_voip_config voip;
	struct snd_set_voip_msg voipmsg;
	/*-- Kevin Shiu - 20121002 voip mute and change path --*/
	/*++ Kvein Shiu - 20121103 always enable hesd bias when TTY turn on ++*/
	struct msm_snd_tty_config tty;
	struct snd_set_tty_msg ttymsg;
	/*-- Kvein Shiu - 20121103 always enable hesd bias when TTY turn on --*/
	
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;
/*++ Kevin Shiu - 20120612 implement secondary mic test ++*/
	case SND_SET_INFO:
		if (copy_from_user(&info, (void __user *) arg, sizeof(info))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}
		
		imsg.args.secondary_mic = cpu_to_be32(info.secondary_mic);
		imsg.args.reserved_1 = cpu_to_be32(info.reserved_1);
		imsg.args.reserved_2 = cpu_to_be32(info.reserved_2);
		imsg.args.cb_func = -1;
		imsg.args.client_data = 0;
		
		MM_INFO("snd_set_info %d %d %d\n",imsg.args.secondary_mic, imsg.args.reserved_1, imsg.args.reserved_2);
		
		rc = msm_rpc_call(snd->ept,
			SND_SET_INFO_PROC,&imsg, 
			sizeof(imsg), 5 * HZ);
		break;
/*-- Kevin Shiu - 20120612 implement secondary mic test --*/

/*++ Kevin Shiu - 20121002 voip mute and change path ++*/
	case SND_SET_VOIP:
		if (copy_from_user(&voip, (void __user *) arg, sizeof(voip))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}
		
		voipmsg.args.audiopath = cpu_to_be32(voip.audiopath);
		voipmsg.args.voip_mute = cpu_to_be32(voip.voip_mute);
		voipmsg.args.reserved_2 = cpu_to_be32(voip.reserved_2);
		voipmsg.args.cb_func = -1;
		voipmsg.args.client_data = 0;
		
		MM_INFO("snd_set_voip %d %d %d\n",voipmsg.args.audiopath, voipmsg.args.voip_mute, voipmsg.args.reserved_2);
		
		rc = msm_rpc_call(snd->ept,
			SND_SET_VOIP_PROC,&voipmsg, 
			sizeof(voipmsg), 5 * HZ);
		break;
/*-- Kevin Shiu - 20121002 voip mute and change path --*/

/*++ Kvein Shiu - 20121103 always enable hesd bias when TTY turn on ++*/
	case SND_SET_TTY:
		if (copy_from_user(&tty, (void __user *) arg, sizeof(tty))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		ttymsg.args.tty_mode = cpu_to_be32(tty.tty_mode);
		ttymsg.args.cb_func = -1;
		ttymsg.args.client_data = 0x0;

		MM_INFO("snd_set_tty %d\n",ttymsg.args.tty_mode);
		
		rc = msm_rpc_call(snd->ept,
			SND_SET_TTY_PROC,&ttymsg, 
			sizeof(ttymsg), 5 * HZ);
		break;
/*-- Kvein Shiu - 20121103 always enable hesd bias when TTY turn on --*/	
	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Esempio n. 30
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_avc_ctl_msg avc_msg;
	struct snd_agc_ctl_msg agc_msg;

	struct msm_snd_device_config dev;
	struct msm_snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;

	uint32_t avc, agc;

	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
			MM_ERR("set device: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

//SW2-6-MM-RC-Audio_Porting-00*{
#ifndef CONFIG_NK_AUDIO
		/* FIH, Karen Liao, 2009/10/23 { */
		/* [F0X.FC-663], Allow user to use the normal headset.*/
		if((dev.device == 3) && EnableAbnormalHS) // 3: SND_DEVICE_STEREO_HEADSET
			dev.device = 27;  // 27: SND_DEVICE_STEREO_HEADSET_WITH_INNER_MIC	
		/* } FIH, Karen Liao, 2009/10/23 */
#else
		//a.This is the solution for headset detect while inserting 4-ring headset during device boot
		//   snd_set_device to 3 to enable mic_bias in AudioHardware is too late to update mHeadphone.
		//b.For headset detect in phone call, insert 4-ring headset and then inserting 3-ring headset
		//   mHeadphone is updated too late, so update mHeadphone here to switch to the correct path. 
		//MM_ERR("set device[1]:  ptt gpio(21) = %d , mHeadphone=%d\n", gpio_get_value(21), mHeadphone);
		if ((dev.device == 3) &&(gpio_get_value(21) == 0))
		{
			mHeadphone = false;
		}
		else if ((dev.device == 3) &&(gpio_get_value(21) == 1))
		{
			mHeadphone = true;
		}
		if((dev.device == 3) && mHeadphone) 
			dev.device = 27; 
#endif


//SW2-6-MM-RC-Audio_Porting-00*}

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		if (check_mute(dev.ear_mute) < 0 ||
				check_mute(dev.mic_mute) < 0) {
			MM_ERR("set device: invalid mute status\n");
			rc = -EINVAL;
			break;
		}
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		MM_INFO("snd_set_device %d %d %d\n", dev.device,
				dev.ear_mute, dev.mic_mute);

		rc = msm_rpc_call(snd->ept,
			SND_SET_DEVICE_PROC,
			&dmsg, sizeof(dmsg), 5 * HZ);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
			MM_ERR("set volume: invalid pointer\n");
			rc = -EFAULT;
			break;
		}

		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE) {
			MM_ERR("set volume: invalid method\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		MM_INFO("snd_set_volume %d %d %d\n", vol.device,
				vol.method, vol.volume);

		rc = msm_rpc_call(snd->ept,
			SND_SET_VOLUME_PROC,
			&vmsg, sizeof(vmsg), 5 * HZ);
		break;

	case SND_AVC_CTL:
		if (get_user(avc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((avc != 1) && (avc != 0)) {
			rc = -EINVAL;
			break;
		}

		avc_msg.args.avc_ctl = cpu_to_be32(avc);
		avc_msg.args.cb_func = -1;
		avc_msg.args.client_data = 0;

		MM_INFO("snd_avc_ctl %d\n", avc);

		rc = msm_rpc_call(snd->ept,
			SND_AVC_CTL_PROC,
			&avc_msg, sizeof(avc_msg), 5 * HZ);
		break;

	case SND_AGC_CTL:
		if (get_user(agc, (uint32_t __user *) arg)) {
			rc = -EFAULT;
			break;
		} else if ((agc != 1) && (agc != 0)) {
			rc = -EINVAL;
			break;
		}
		agc_msg.args.agc_ctl = cpu_to_be32(agc);
		agc_msg.args.cb_func = -1;
		agc_msg.args.client_data = 0;

		MM_INFO("snd_agc_ctl %d\n", agc);

		rc = msm_rpc_call(snd->ept,
			SND_AGC_CTL_PROC,
			&agc_msg, sizeof(agc_msg), 5 * HZ);
		break;

	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			MM_ERR("get endpoint: invalid pointer\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;

	default:
		MM_ERR("unknown command\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}