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; } }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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 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; }
/* * 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; }
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; }