Example #1
0
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)) {
				MM_DBG("connect failed with current VERS \
					= %x, trying again with another API\n",
					RPC_SND_VERS2);
				snd->ept =
					msm_rpc_connect_compatible(RPC_SND_PROG,
							RPC_SND_VERS2, 0);
			}
			if (IS_ERR(snd->ept)) {
				rc = PTR_ERR(snd->ept);
				snd->ept = NULL;
				MM_ERR("failed to connect snd svc\n");
				goto err;
			}
		}
Example #2
0
int msm_snd_rpc_connect(void)
{
	if (snd_ep) {
		printk(KERN_INFO "%s: snd_ep already connected\n", __func__);
		return 0;
	}

	/* Initialize rpc ids */
	if (msm_snd_init_rpc_ids()) {
		printk(KERN_ERR "%s: snd rpc ids initialization failed\n"
			, __func__);
		return -ENODATA;
	}

	snd_ep = msm_rpc_connect_compatible(snd_rpc_ids.prog,
				snd_rpc_ids.vers, 0);
	if (IS_ERR(snd_ep)) {
		printk(KERN_DEBUG "%s failed (compatible VERS = %ld) \
				 trying again with another API\n",
				__func__, snd_rpc_ids.vers);
		snd_ep =
			msm_rpc_connect_compatible(snd_rpc_ids.prog,
					snd_rpc_ids.vers2, 0);
	}
	if (IS_ERR(snd_ep)) {
		printk(KERN_ERR "%s: failed (compatible VERS = %ld)\n",
				__func__, snd_rpc_ids.vers2);
		snd_ep = NULL;
		return -EAGAIN;
	}
	return 0;
}
static int __devinit hs_rpc_init(void)
{
	int rc;

	rc = hs_rpc_cb_init();
	if (rc) {
		pr_err("%s: failed to initialize rpc client, try server...\n",
						__func__);
		}
		rc = msm_rpc_create_server(&hs_rpc_server);
		if (rc) {
			pr_err("%s: failed to create rpc server\n", __func__);
			return rc;
		}
	
	rpc_svc_p = msm_rpc_connect_compatible(HS_RPC_PROG,HS_RPC_VERS_1,0);

	if(IS_ERR(rpc_svc_p)) {
		pr_err("%s: couldn't connect compatible rpc client err %ld\n", __func__,
			 PTR_ERR(rpc_svc_p));
		rpc_svc_p = msm_rpc_connect_compatible(HS_RPC_PROG,HS_RPC_VERS_2,0);
	}

	if(IS_ERR(rpc_svc_p)) {
		pr_err("%s: couldn't connect compatible rpc client err %ld\n", __func__,
			 PTR_ERR(rpc_svc_p));
		return PTR_ERR(rpc_svc_p);
	}

	return rc;
}
Example #4
0
static int msm_chg_init_rpc(unsigned long vers)
{
	if (((vers & RPC_VERSION_MAJOR_MASK) == 0x00010000) ||
	    ((vers & RPC_VERSION_MAJOR_MASK) == 0x00020000) ||
	    ((vers & RPC_VERSION_MAJOR_MASK) == 0x00030000) ||
	    ((vers & RPC_VERSION_MAJOR_MASK) == 0x00040000)) {
		chg_ep = msm_rpc_connect_compatible(MSM_RPC_CHG_PROG, vers,
						     MSM_RPC_UNINTERRUPTIBLE);
		if (IS_ERR(chg_ep))
			return -ENODATA;
		chg_rpc_ids.vers_comp				= vers;
		chg_rpc_ids.chg_is_charging_proc 		= 2;
		chg_rpc_ids.chg_usb_charger_connected_proc 	= 7;
		chg_rpc_ids.chg_usb_charger_disconnected_proc 	= 8;
		chg_rpc_ids.chg_usb_i_is_available_proc 	= 9;
		chg_rpc_ids.chg_usb_i_is_not_available_proc 	= 10;
#if defined(CONFIG_MACH_ES209RA)
		chg_rpc_ids.chg_battery_thermo_proc		= 22;
		chg_rpc_ids.chg_charger_current_proc = 23;
		chg_rpc_ids.chg_qsd_thermo_proc = 24;
		chg_rpc_ids.chg_charger_thermo_proc = 25;
#endif /* CONFIG_MACH_ES209RA */

		return 0;
	} else
		return -ENODATA;
}
Example #5
0
/* rpc connect for charging */
int msm_chg_rpc_connect(void)
{

	if (machine_is_msm7201a_surf() || machine_is_msm7x25_surf() ||
		machine_is_qst1500_surf() || machine_is_qst1600_surf()
					|| machine_is_qsd8x50_surf())
		return -ENOTSUPP;

	if (chg_ep && !IS_ERR(chg_ep)) {
		printk(KERN_INFO "%s: chg_ep already connected\n", __func__);
		return 0;
	}

	/* Initialize rpc ids */
	if (msm_chg_init_rpc_ids(0x00010001)) {
		printk(KERN_ERR "%s: rpc ids initialization failed\n"
			, __func__);
		return -ENODATA;
	}

	chg_ep = msm_rpc_connect_compatible(chg_rpc_ids.prog,
				chg_rpc_ids.vers_comp, 0);

	if (IS_ERR(chg_ep)) {
		printk(KERN_ERR "%s: connect compatible failed vers = %lx\n",
				__func__, chg_rpc_ids.vers_comp);
		return -EAGAIN;
	} else
		printk(KERN_INFO "%s: rpc connect success vers = %lx\n",
				__func__, chg_rpc_ids.vers_comp);

	return 0;
}
Example #6
0
static int __init shterm_init( void )
{
    int ret;

    ret = msm_rpc_create_server( &shterm_rpc_server );

    ret = misc_register( &shterm_dev );
    if( ret ){
        printk( "misc_register failure %s\n", __FUNCTION__ );
        return ret;
    }

    ret = misc_register( &shterm_cmd_dev );
    if( ret ){
        printk( "misc_register failure %s\n", __FUNCTION__ );
        return ret;
    }

    endpoint = msm_rpc_connect_compatible( SHTERM_A2M_PROG, SHTERM_A2M_VERS, 0 );
    if( IS_ERR(endpoint) ){
        printk( "%s: init rpc failed! ret = %lx\n", __FUNCTION__, PTR_ERR(endpoint) );
        return -1;
    }

    return ret;
}
Example #7
0
static int snd_cad_open(struct inode *inode, struct file *file)
{
	struct snd_cad_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("cad connect failed with VERS %x\n",
					RPC_SND_VERS);
				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;
}
Example #8
0
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;
	}
#if defined(CONFIG_MACH_MSM7X27_SWIFT)		
	gpio_direction_output(GPIO_HS_MIC_BIAS_EN, 1);
#endif
err:
	mutex_unlock(&snd->lock);
	return rc;
}
Example #9
0
static int msm_fb_lcdc_config(int on)
{
	int rc = 0;
	struct rpc_request_hdr hdr;

	if (on)
		pr_info("lcdc config\n");
	else
		pr_info("lcdc un-config\n");

	lcdc_ep = msm_rpc_connect_compatible(LCDC_API_PROG, LCDC_API_VERS, 0);
	if (IS_ERR(lcdc_ep)) {
		printk(KERN_ERR "%s: msm_rpc_connect failed! rc = %ld\n",
			__func__, PTR_ERR(lcdc_ep));
		return -EINVAL;
	}

	rc = msm_rpc_call(lcdc_ep,
				(on) ? LCDC_CONFIG_PROC : LCDC_UN_CONFIG_PROC,
				&hdr, sizeof(hdr),
				5 * HZ);
	if (rc)
		printk(KERN_ERR
			"%s: msm_rpc_call failed! rc = %d\n", __func__, rc);

	msm_rpc_close(lcdc_ep);
	return rc;
}
/* rpc connect for hsusb */
int msm_hsusb_rpc_connect(void)
{

	if (usb_ep && !IS_ERR(usb_ep)) {
		printk(KERN_INFO "%s: usb_ep already connected\n", __func__);
		return 0;
	}

	/* Initialize rpc ids */
	if (msm_hsusb_init_rpc_ids(0x00010001)) {
		printk(KERN_ERR "%s: rpc ids initialization failed\n"
			, __func__);
		return -ENODATA;
	}

	usb_ep = msm_rpc_connect_compatible(usb_rpc_ids.prog,
					usb_rpc_ids.vers_comp,
					MSM_RPC_UNINTERRUPTIBLE);

	if (IS_ERR(usb_ep)) {
		printk(KERN_ERR "%s: connect compatible failed vers = %lx\n",
			 __func__, usb_rpc_ids.vers_comp);

		/* Initialize rpc ids */
		if (msm_hsusb_init_rpc_ids(0x00010002)) {
			printk(KERN_ERR "%s: rpc ids initialization failed\n",
				__func__);
			return -ENODATA;
		}
		usb_ep = msm_rpc_connect_compatible(usb_rpc_ids.prog,
					usb_rpc_ids.vers_comp,
					MSM_RPC_UNINTERRUPTIBLE);
	}

	if (IS_ERR(usb_ep)) {
		printk(KERN_ERR "%s: connect compatible failed vers = %lx\n",
				__func__, usb_rpc_ids.vers_comp);
		return -EAGAIN;
	} else
		printk(KERN_INFO "%s: rpc connect success vers = %lx\n",
				__func__, usb_rpc_ids.vers_comp);

	return 0;
}
Example #11
0
/* rpc connect for nv */
int msm_nv_rpc_connect(void)
{

	if (nv_ep && !IS_ERR(nv_ep)) {
		printk(KERN_INFO "%s: nv_ep already connected\n", __func__);
		return 0;
	}

	/* Initialize rpc ids */
	if (msm_nv_init_rpc_ids(NV_VERS_9_2)) {
		printk(KERN_ERR "%s: rpc ids(0x%x) initialization failed\n",
			__func__, NV_VERS_9_2);
		return -ENODATA;
	}

	nv_ep = msm_rpc_connect_compatible(nv_rpc_ids.prog,
					nv_rpc_ids.vers_comp,
					MSM_RPC_UNINTERRUPTIBLE);

	if (IS_ERR(nv_ep)) {
		printk(KERN_ERR "%s: connect compatible failed vers = %lx\n",
			 __func__, nv_rpc_ids.vers_comp);

		/* Initialize rpc ids */
		if (msm_nv_init_rpc_ids(NV_VERS_1_1)) {
			printk(KERN_ERR "%s: rpc ids(0x%x) initialization failed\n",
				__func__, NV_VERS_1_1);
			return -ENODATA;
		}
		nv_ep = msm_rpc_connect_compatible(nv_rpc_ids.prog,
					nv_rpc_ids.vers_comp,
					MSM_RPC_UNINTERRUPTIBLE);
	}

	if (IS_ERR(nv_ep)) {
		printk(KERN_ERR "%s: connect compatible failed vers = %lx\n",
				__func__, nv_rpc_ids.vers_comp);
		return -EAGAIN;
	} else
		printk(KERN_INFO "%s: rpc connect success vers = %lx\n",
				__func__, nv_rpc_ids.vers_comp);

	return 0;
}
Example #12
0
static int elini_gpio_earsense_work_func(void)
{
    int state;
    int gpio_value;

    struct snd_set_hook_param_rep {
        struct rpc_reply_hdr hdr;
        uint32_t get_mode;
    } hkrep;
    struct snd_set_hook_mode_msg {
        struct rpc_request_hdr hdr;
        struct rpc_snd_set_hook_mode_args args;
    } hookmsg;
    int rc;

    struct msm_rpc_endpoint *ept = msm_rpc_connect_compatible(RPC_SND_PROG,
                                   RPC_SND_VERS, 0);
    if (IS_ERR(ept)) {
        rc = PTR_ERR(ept);
        ept = NULL;
        printk(KERN_ERR"failed to connect snd svc, error %d\n", rc);
    }

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


    gpio_value = gpio_get_value(GPIO_EAR_SENSE);
    printk(KERN_INFO"%s: ear sense detected : %s\n", __func__,
           gpio_value?"injected":"ejected");
    if (gpio_value == EAR_EJECT) {
        state = EAR_STATE_EJECT;
        gpio_set_value(GPIO_HS_MIC_BIAS_EN, 0);
        hookmsg.args.mode = cpu_to_be32(0);
    } else {
        state = EAR_STATE_INJECT;
        gpio_set_value(GPIO_HS_MIC_BIAS_EN, 1);
        hookmsg.args.mode = cpu_to_be32(1);
    }
    if(ept) {
        rc = msm_rpc_call_reply(ept,
                                SND_SET_HOOK_MODE_PROC,
                                &hookmsg, sizeof(hookmsg),&hkrep, sizeof(hkrep), 5 * HZ);
        if (rc < 0) {
            printk(KERN_ERR "%s:rpc err because of %d\n", __func__, rc);
        }
    } else {
        printk(KERN_ERR "%s:ext_snd is NULL\n", __func__);
    }
    rc = msm_rpc_close(ept);
    if (rc < 0)
        printk(KERN_ERR"msm_rpc_close failed\n");

    return state;
}
Example #13
0
static int vocpcm_open(struct inode *inode, struct file *file)
{
	struct voc_ctxt *ctxt = voc_minor_to_ctxt(MINOR(inode->i_rdev));

	if (!ctxt) {
		pr_err("voc: unknown voc misc %d\n", MINOR(inode->i_rdev));
		return -ENODEV;
	}

	mutex_lock(&the_voc.lock);
	if (the_voc.task == NULL) {
		if (the_voc.ept == NULL) 
			the_voc.ept = msm_rpc_connect_compatible(RPC_SND_PROG, RPC_SND_VERS,
					MSM_RPC_UNINTERRUPTIBLE | MSM_RPC_ENABLE_RECEIVE);
		if (IS_ERR(the_voc.ept)) {
			the_voc.ept = NULL;
			pr_err("voc: failed to connect voc svc\n");
			mutex_unlock(&the_voc.lock);
			return -ENODEV;
		}
		the_voc.task = kthread_run(voc_rpc_thread, NULL, "voc_rpc_thread");
		if (IS_ERR(the_voc.task)) {
			the_voc.task = NULL;
			if (the_voc.ept) msm_rpc_close(the_voc.ept);
			the_voc.ept = NULL;
			mutex_unlock(&the_voc.lock);
			return -EFAULT;
		}
	}
	mutex_unlock(&the_voc.lock);

	mutex_lock(&ctxt->lock);
	if (ctxt->opened) {
		pr_err("vocpcm already opened.\n");
		mutex_unlock(&ctxt->lock);
		return -EBUSY;
	}

	file->private_data = ctxt;
	ctxt->head = 0;
	ctxt->tail = 0;
	ctxt->client = 0;

	memset(ctxt->buf[0].data, 0, sizeof(ctxt->buf[0].data));
	memset(ctxt->buf[1].data, 0, sizeof(ctxt->buf[1].data));
	ctxt->buf[0].index = 0;
	ctxt->buf[1].index = 0;
	ctxt->opened = 1;
	ctxt->count = 0;
	ctxt->s_ptr = 0;
	ctxt->final_input = 0;

	mutex_unlock(&ctxt->lock);
	return 0;
}
static int msm_chg_init_rpc(unsigned long vers)
{
	if (((vers & RPC_VERSION_MAJOR_MASK) == 0x00010000) ||
	    ((vers & RPC_VERSION_MAJOR_MASK) == 0x00020000)) {
		chg_ep = msm_rpc_connect_compatible(MSM_RPC_CHG_PROG, vers,
						     MSM_RPC_UNINTERRUPTIBLE);
		if (IS_ERR(chg_ep))
			return -ENODATA;
		chg_rpc_ids.vers_comp				= vers;
		chg_rpc_ids.chg_usb_charger_connected_proc 	= 7;
		chg_rpc_ids.chg_usb_charger_disconnected_proc 	= 8;
		chg_rpc_ids.chg_usb_i_is_available_proc 	= 9;
		chg_rpc_ids.chg_usb_i_is_not_available_proc 	= 10;
		return 0;
	} else
		return -ENODATA;
}
Example #15
0
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;
}
Example #16
0
static int adsp_rpc_init(struct msm_adsp_module *adsp_module)
{
    /* remove the original connect once compatible support is complete */
    adsp_module->rpc_client = msm_rpc_connect(
                                  rpc_adsp_rtos_atom_prog,
                                  rpc_adsp_rtos_atom_vers,
                                  MSM_RPC_UNINTERRUPTIBLE);
    if (IS_ERR(adsp_module->rpc_client))
        adsp_module->rpc_client = msm_rpc_connect_compatible(
                                      rpc_adsp_rtos_atom_prog,
                                      rpc_adsp_rtos_atom_vers_comp,
                                      MSM_RPC_UNINTERRUPTIBLE);

    if (IS_ERR(adsp_module->rpc_client)) {
        int rc = PTR_ERR(adsp_module->rpc_client);
        adsp_module->rpc_client = 0;
        MM_ERR("could not open rpc client: %d\n", rc);
        return rc;
    }

    return 0;
}
Example #17
0
/*
 * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get
 * queue offsets and module entries (init info) as part of the event.
 */
static void  msm_get_init_info(void)
{
    int rc;
    struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
    struct rpc_reply_hdr rpc_rsp;

    adsp_info.init_info_rpc_client = msm_rpc_connect(
                                         rpc_adsp_rtos_atom_prog,
                                         rpc_adsp_rtos_atom_vers,
                                         MSM_RPC_UNINTERRUPTIBLE);
    if (IS_ERR(adsp_info.init_info_rpc_client)) {
        adsp_info.init_info_rpc_client = msm_rpc_connect_compatible(
                                             rpc_adsp_rtos_atom_prog,
                                             rpc_adsp_rtos_atom_vers_comp,
                                             MSM_RPC_UNINTERRUPTIBLE);
        if (IS_ERR(adsp_info.init_info_rpc_client)) {
            rc = PTR_ERR(adsp_info.init_info_rpc_client);
            adsp_info.init_info_rpc_client = 0;
            MM_ERR("could not open rpc client: %d\n", rc);
            return;
        }
    }

    rpc_req.gotit = cpu_to_be32(1);
    rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO);
    rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
    rpc_req.module = 0;

    rc = msm_rpc_call_reply(adsp_info.init_info_rpc_client,
                            RPC_ADSP_RTOS_APP_TO_MODEM_PROC,
                            &rpc_req, sizeof(rpc_req),
                            &rpc_rsp, sizeof(rpc_rsp),
                            5 * HZ);

    if (rc < 0)
        MM_ERR("could not send RPC request: %d\n", rc);
}
static int htc_headset_pmic_probe(struct platform_device *pdev)
{
	int ret = 0;
	uint32_t vers = 0;
	struct htc_headset_pmic_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	pmic_info = kzalloc(sizeof(struct htc_35mm_pmic_info), GFP_KERNEL);
	if (!pmic_info)
		return -ENOMEM;

	pmic_info->pdata.driver_flag = pdata->driver_flag;
	pmic_info->pdata.hpin_gpio = pdata->hpin_gpio;
	pmic_info->pdata.hpin_irq = pdata->hpin_irq;
	pmic_info->pdata.key_enable_gpio = pdata->key_enable_gpio;
	pmic_info->pdata.hs_controller = pdata->hs_controller;
	pmic_info->pdata.hs_switch = pdata->hs_switch;
	pmic_info->pdata.adc_mic = pdata->adc_mic;

	if (!pmic_info->pdata.adc_mic)
		pmic_info->pdata.adc_mic = HS_DEF_MIC_ADC_16_BIT;

	if (pdata->adc_remote[5])
		memcpy(pmic_info->pdata.adc_remote, pdata->adc_remote,
		       sizeof(pmic_info->pdata.adc_remote));

	if (pdata->adc_metrico[0] && pdata->adc_metrico[1])
		memcpy(pmic_info->pdata.adc_metrico, pdata->adc_metrico,
		       sizeof(pmic_info->pdata.adc_metrico));

	pmic_info->hpin_irq_type = IRQF_TRIGGER_LOW;
	pmic_info->hpin_debounce = HS_JIFFIES_INSERT;

	wake_lock_init(&pmic_info->hs_wake_lock, WAKE_LOCK_SUSPEND,
		       DRIVER_NAME);

	detect_wq = create_workqueue("detection");
	if (detect_wq  == NULL) {
		ret = -ENOMEM;
		goto err_create_detect_work_queue;
	}

	if (pmic_info->pdata.hpin_irq) {
		ret = request_irq(pmic_info->pdata.hpin_irq, htc_35mm_pmic_irq,
				  pmic_info->hpin_irq_type, "HS_PMIC_DETECT",
				  NULL);
		if (ret < 0) {
			HS_LOG("Failed to request PMIC HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}

		ret = set_irq_wake(pmic_info->pdata.hpin_irq, 1);
		if (ret < 0)
			HS_LOG("Failed to set PMIC HPIN IRQ wake");
	}

	if (pmic_info->pdata.driver_flag & DRIVER_HS_PMIC_RPC_KEY) {
		/* Register ADC RPC client */
		endpoint_adc = msm_rpc_connect(HS_RPC_CLIENT_PROG,
					       HS_RPC_CLIENT_VERS, 0);
		if (IS_ERR(endpoint_adc)) {
			pmic_info->pdata.driver_flag &= ~DRIVER_HS_PMIC_RPC_KEY;
			HS_LOG("Failed to register ADC RPC client");
		} else
			HS_LOG("Register ADC RPC client successfully");
	}

	if (pmic_info->pdata.driver_flag & DRIVER_HS_PMIC_DYNAMIC_THRESHOLD) {
		/* Register threshold RPC client */
		vers = HS_PMIC_RPC_CLIENT_VERS_3_1;
		endpoint_current = msm_rpc_connect_compatible(
				   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_2_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_1_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (IS_ERR(endpoint_current)) {
			pmic_info->pdata.driver_flag &=
				~DRIVER_HS_PMIC_DYNAMIC_THRESHOLD;
			HS_LOG("Failed to register threshold RPC client");
		} else
			HS_LOG("Register threshold RPC client successfully"
			       " (0x%X)", vers);
	}

	hs_pmic_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_request_detect_irq:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	wake_lock_destroy(&pmic_info->hs_wake_lock);
	kfree(pmic_info);

	HS_LOG("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_pmic_probe(struct platform_device *pdev)
{
	int ret = 0;
	uint32_t vers = 0;
	struct htc_headset_pmic_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_35mm_pmic_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->pdata.driver_flag = pdata->driver_flag;
	hi->pdata.hpin_gpio = pdata->hpin_gpio;
	hi->pdata.hpin_irq = pdata->hpin_irq;
	hi->pdata.key_gpio = pdata->key_gpio;
	hi->pdata.key_irq = pdata->key_irq;
	hi->pdata.key_enable_gpio = pdata->key_enable_gpio;
	hi->pdata.hs_controller = pdata->hs_controller;
	hi->pdata.hs_switch = pdata->hs_switch;
	hi->pdata.adc_mic = pdata->adc_mic;

	if (!hi->pdata.adc_mic)
		hi->pdata.adc_mic = HS_DEF_MIC_ADC_16_BIT_MIN;

	if (pdata->adc_mic_bias[0] && pdata->adc_mic_bias[1]) {
		memcpy(hi->pdata.adc_mic_bias, pdata->adc_mic_bias,
		       sizeof(hi->pdata.adc_mic_bias));
		hi->pdata.adc_mic = hi->pdata.adc_mic_bias[0];
	} else {
		hi->pdata.adc_mic_bias[0] = hi->pdata.adc_mic;
		hi->pdata.adc_mic_bias[1] = HS_DEF_MIC_ADC_16_BIT_MAX;
	}

	if (pdata->adc_remote[5])
		memcpy(hi->pdata.adc_remote, pdata->adc_remote,
		       sizeof(hi->pdata.adc_remote));

	if (pdata->adc_metrico[0] && pdata->adc_metrico[1])
		memcpy(hi->pdata.adc_metrico, pdata->adc_metrico,
		       sizeof(hi->pdata.adc_metrico));

	hi->hpin_irq_type = IRQF_TRIGGER_LOW;
	hi->hpin_debounce = HS_JIFFIES_ZERO;
	hi->key_irq_type = IRQF_TRIGGER_LOW;

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	detect_wq = create_workqueue("HS_PMIC_DETECT");
	if (detect_wq  == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("HS_PMIC_BUTTON");
	if (button_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	if (hi->pdata.hpin_gpio) {
		ret = hs_pmic_request_irq(hi->pdata.hpin_gpio,
				&hi->pdata.hpin_irq, detect_irq_handler,
				hi->hpin_irq_type, "HS_PMIC_DETECT", 1);
		if (ret < 0) {
			HS_ERR("Failed to request PMIC HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}
	}

	if (hi->pdata.key_gpio) {
		ret = hs_pmic_request_irq(hi->pdata.key_gpio,
				&hi->pdata.key_irq, button_irq_handler,
				hi->key_irq_type, "HS_PMIC_BUTTON", 1);
		if (ret < 0) {
			HS_ERR("Failed to request PMIC button IRQ (0x%X)", ret);
			goto err_request_button_irq;
		}
	}

	if (hi->pdata.driver_flag & DRIVER_HS_PMIC_RPC_KEY) {
		/* Register ADC RPC client */
		endpoint_adc = msm_rpc_connect(HS_RPC_CLIENT_PROG,
					       HS_RPC_CLIENT_VERS, 0);
		if (IS_ERR(endpoint_adc)) {
			hi->pdata.driver_flag &= ~DRIVER_HS_PMIC_RPC_KEY;
			HS_LOG("Failed to register ADC RPC client");
		} else
			HS_LOG("Register ADC RPC client successfully");
	}

	if (hi->pdata.driver_flag & DRIVER_HS_PMIC_DYNAMIC_THRESHOLD) {
		/* Register threshold RPC client */
		vers = HS_PMIC_RPC_CLIENT_VERS_3_1;
		endpoint_current = msm_rpc_connect_compatible(
				   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_2_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_1_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (IS_ERR(endpoint_current)) {
			hi->pdata.driver_flag &=
				~DRIVER_HS_PMIC_DYNAMIC_THRESHOLD;
			HS_LOG("Failed to register threshold RPC client");
		} else
			HS_LOG("Register threshold RPC client successfully"
			       " (0x%X)", vers);
	}

	hs_pmic_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_request_button_irq:
	if (hi->pdata.hpin_gpio) {
		free_irq(hi->pdata.hpin_irq, 0);
		gpio_free(hi->pdata.hpin_gpio);
	}

err_request_detect_irq:
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	wake_lock_destroy(&hi->hs_wake_lock);
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
Example #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;
	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;
}