static int vocpcm_open(struct inode *inode, struct file *file) { struct voc_rpc *voc_rpc = &the_voc_proc; struct voc_ctxt *ctxt = voc_minor_to_ctxt(MINOR(inode->i_rdev)); int rc = 0; if (!ctxt) { pr_err("unknown voc misc %d\n", MINOR(inode->i_rdev)); return -ENODEV; } mutex_lock(&voc_rpc->lock); if (voc_rpc->inited == 0) { voc_rpc->ept = create_rpc_connect(RPC_SND_PROG, RPC_SND_VERS, MSM_RPC_UNINTERRUPTIBLE | MSM_RPC_ENABLE_RECEIVE); if (IS_ERR(voc_rpc->ept)) { rc = PTR_ERR(voc_rpc->ept); voc_rpc->ept = NULL; pr_err("vocpcm: failed to connect snd svc\n"); return rc; } voc_rpc->task = create_snd_rpc_kthread(); if (IS_ERR(voc_rpc->task)) { rc = PTR_ERR(voc_rpc->task); voc_rpc->task = NULL; msm_rpc_close(voc_rpc->ept); voc_rpc->ept = NULL; return rc; } voc_rpc->inited = 1; } mutex_unlock(&voc_rpc->lock); mutex_lock(&ctxt->lock); if (ctxt->opened) { pr_err("vocpcm already opened.\n"); rc = -EBUSY; goto err; } 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; err: mutex_unlock(&ctxt->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; }
void msm_adsp_put(struct msm_adsp_module *module) { unsigned long flags; mutex_lock(&module->lock); if (--module->open_count == 0 && module->clk) clk_disable(module->clk); if (module->ops) { pr_info("adsp: closing module %s\n", module->name); /* lock to ensure a dsp event cannot be delivered * during or after removal of the ops and driver_data */ spin_lock_irqsave(&adsp_cmd_lock, flags); module->ops = NULL; module->driver_data = NULL; spin_unlock_irqrestore(&adsp_cmd_lock, flags); if (module->state != ADSP_STATE_DISABLED) { pr_info("adsp: disabling module %s\n", module->name); msm_adsp_disable_locked(module); } msm_rpc_close(module->rpc_client); module->rpc_client = 0; if (--adsp_open_count == 0) { disable_irq(INT_ADSP); allow_suspend(); pr_info("adsp: disable interrupt\n"); } } else { pr_info("adsp: module %s is already closed\n", module->name); } mutex_unlock(&module->lock); }
int __init rpc_clkrgm_sec(uint32_t proc, uint32_t d) { struct msm_rpc_endpoint *mmoc_ep; int rc; struct mmoc_req { struct rpc_request_hdr hdr; uint32_t data[1]; } req; printk(KERN_INFO "%s: proc: %02x data: %02x\n", __func__, proc, d); mutex_lock(&mmoc_mutex); req.data[0] = cpu_to_be32(d); mmoc_ep = msm_rpc_connect(0x3000000f, 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; }
static int msm_fb_pm_vid_en(int on) { int rc = 0; struct msm_fb_pm_vid_en_req { struct rpc_request_hdr hdr; uint32_t on; } req; pm_vid_en_ep = msm_rpc_connect(PM_VID_EN_API_PROG, PM_VID_EN_API_VERS, 0); if (IS_ERR(pm_vid_en_ep)) { printk(KERN_ERR "%s: msm_rpc_connect failed! rc = %ld\n", __func__, PTR_ERR(pm_vid_en_ep)); return -EINVAL; } req.on = cpu_to_be32(on); rc = msm_rpc_call(pm_vid_en_ep, PM_VID_EN_CONFIG_PROC, &req, sizeof(req), 5 * HZ); if (rc) printk(KERN_ERR "%s: msm_rpc_call failed! rc = %d\n", __func__, rc); msm_rpc_close(pm_vid_en_ep); return rc; }
int __init rpc_adsprtosatom(uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4) { struct msm_rpc_endpoint *mmoc_ep; int rc; struct mmoc_req { struct rpc_request_hdr hdr; uint32_t data[4]; } req; printk(KERN_INFO "%s\n", __func__); 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); mmoc_ep = msm_rpc_connect(0x3000000a, 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*/1, &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; }
void msm_adsp_put(struct msm_adsp_module *module) { unsigned long flags; mutex_lock(&module->lock); if (module->ops) { MM_INFO("closing module %s\n", module->name); /* lock to ensure a dsp event cannot be delivered * during or after removal of the ops and driver_data */ spin_lock_irqsave(&adsp_cmd_lock, flags); module->ops = NULL; module->driver_data = NULL; spin_unlock_irqrestore(&adsp_cmd_lock, flags); if (module->state != ADSP_STATE_DISABLED) { MM_INFO("disabling module %s\n", module->name); msm_adsp_disable_locked(module); } if (module->rpc_client) msm_rpc_close(module->rpc_client); module->rpc_client = 0; } else { MM_INFO("module %s is already closed\n", module->name); } mutex_unlock(&module->lock); }
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 void vocpcm_exit(void) { mutex_lock(&the_voc.lock); if(the_voc.ept != NULL) msm_rpc_close(the_voc.ept); the_voc.ept = NULL; shut_voc(&vocpcm0); shut_voc(&vocpcm1); shut_voc(&vocpcm2); shut_voc(&vocpcm3); mutex_unlock(&the_voc.lock); }
/*--------------------------------------------------------------------------* * Function : DbgCfgSetErrorAction * * Description : * Write the ARM9 fatal error auto action setting to NV item #905. * * Parameters : * * value - the desired error auto action. * * Return value: integer * Zero - Successful * Not zero - Fail *--------------------------------------------------------------------------*/ int DbgCfgSetErrorAction(int value) { unsigned int tmp_error_fatal_option = 0; int ret = -1; struct msm_rpc_endpoint *nv_ep; error_action_req req; error_action_rep rep; nv_ep = msm_rpc_connect(NVPROG, NVVERS, 0); if (IS_ERR(nv_ep)) { printk(KERN_ERR "[dbgcfgtool] %s() LINE:%d, init rpc failed! error: %ld\n", __func__, __LINE__, PTR_ERR(nv_ep)); return -EINVAL; } tmp_error_fatal_option = (error_fatal_option & ~ACTION_MASK) |value; req.cmd = cpu_to_be32(NV_WRITE_F); req.item = cpu_to_be32(NV_ERR_FATAL_OPTIONS_I); req.more_data = cpu_to_be32(1); req.disc = cpu_to_be32(NV_ERR_FATAL_OPTIONS_I); req.data = cpu_to_be32(tmp_error_fatal_option); ret = msm_rpc_call_reply (nv_ep, ONCRPC_NV_CMD_REMOTE_PROC, &req, sizeof (req), &rep, sizeof (rep), 5 * HZ); if (ret < 0) { printk(KERN_ERR "[dbgcfgtool] %s() LINE:%d, rpc call failed! (%d)\n", __func__, __LINE__, ret); } else if (be32_to_cpu(rep.retval) != NV_DONE_S) { printk(KERN_ERR "[dbgcfgtool] %s() LINE:%d, nv cmd remote result failed! (%d)\n", __func__, __LINE__, rep.retval); } else { ret = 0; error_fatal_option = tmp_error_fatal_option; //write success, update local data printk(KERN_INFO "[dbgcfgtool] error_fatal_option = 0x%x\n", error_fatal_option); } msm_rpc_close(nv_ep); return ret; }
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_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; }
/*--------------------------------------------------------------------------* * Function : DbgCfgSetDetectHWRese * * Description : * Write the enable HW Reset detection flag to NV item #4399. * * Parameters : * * value - 0:enable ; 1:disable * * Return value: integer * Zero - Successful * Not zero - Fail *--------------------------------------------------------------------------*/ int DbgCfgSetDetectHWReset(int value) { int ret = -1; struct msm_rpc_endpoint *nv_ep; error_action_req req; error_action_rep rep; nv_ep = msm_rpc_connect(NVPROG, NVVERS, 0); if (IS_ERR(nv_ep)) { printk(KERN_ERR "[dbgcfgtool] %s() LINE:%d, init rpc failed! error: %ld\n", __func__, __LINE__, PTR_ERR(nv_ep)); return -EINVAL; } req.cmd = cpu_to_be32(NV_WRITE_F); req.item = cpu_to_be32(NV_DETECT_HW_RESET_I); req.more_data = cpu_to_be32(1); req.disc = cpu_to_be32(NV_DETECT_HW_RESET_I); req.data = cpu_to_be32(value); ret = msm_rpc_call_reply (nv_ep, ONCRPC_NV_CMD_REMOTE_PROC, &req, sizeof (req), &rep, sizeof (rep), 5 * HZ); if (ret < 0) { printk(KERN_ERR "[dbgcfgtool] %s() LINE:%d, rpc call failed! (%d)\n", __func__, __LINE__, ret); } else if (be32_to_cpu(rep.retval) != NV_DONE_S) { printk(KERN_ERR "[dbgcfgtool] %s() LINE:%d, nv cmd remote result failed! (%d)\n", __func__, __LINE__, rep.retval); } else { ret = 0; printk(KERN_INFO "[dbgcfgtool] detect_hw_reset = 0x%x\n", value); } msm_rpc_close(nv_ep); return ret; }
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->inited == 0) { snd->ept = create_rpc_connect(RPC_SND_PROG, RPC_SND_VERS, MSM_RPC_UNINTERRUPTIBLE | MSM_RPC_ENABLE_RECEIVE); if (IS_ERR(snd->ept)) { rc = PTR_ERR(snd->ept); snd->ept = NULL; pr_err("snd: failed to connect snd svc\n"); goto err; } snd->task = create_snd_rpc_kthread(); if (IS_ERR(snd->task)) { rc = PTR_ERR(snd->task); snd->task = NULL; msm_rpc_close(snd->ept); snd->ept = NULL; goto err; } snd->inited = 1; } if (snd->opened) { pr_err("snd already opened.\n"); rc = -EBUSY; goto err; } file->private_data = snd; snd->opened = 1; err: mutex_unlock(&snd->lock); return rc; }
int msm_snd_rpc_close(void) { int rc = 0; if (IS_ERR(snd_ep)) { printk(KERN_ERR "%s: snd handle unavailable, rc = %ld\n", __func__, PTR_ERR(snd_ep)); return -EAGAIN; } rc = msm_rpc_close(snd_ep); snd_ep = NULL; if (rc < 0) { printk(KERN_ERR "%s: close rpc failed! rc = %d\n", __func__, rc); return -EAGAIN; } else printk(KERN_INFO "rpc close success\n"); return rc; }
/* rpc call to close connection */ int msm_hsusb_rpc_close(void) { int rc = 0; if (IS_ERR(usb_ep)) { pr_err("%s: rpc_close failed before call, rc = %ld\n", __func__, PTR_ERR(usb_ep)); return -EAGAIN; } rc = msm_rpc_close(usb_ep); usb_ep = NULL; if (rc < 0) { pr_err("%s: close rpc failed! rc = %d\n", __func__, rc); return -EAGAIN; } else pr_debug("rpc close success\n"); return rc; }
/* rpc call to close charging connection */ int msm_chg_rpc_close(void) { int rc = 0; if (IS_ERR(chg_ep)) { printk(KERN_ERR "%s: rpc_close failed before call, rc = %ld\n", __func__, PTR_ERR(chg_ep)); return -EAGAIN; } rc = msm_rpc_close(chg_ep); chg_ep = NULL; if (rc < 0) { printk(KERN_ERR "%s: close rpc failed! rc = %d\n", __func__, rc); return -EAGAIN; } else printk(KERN_INFO "rpc close success\n"); return rc; }
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 __init rpc_tlmm_remote_atom_2(uint32_t proc, uint32_t d1, uint32_t d2) { struct msm_rpc_endpoint *mmoc_ep; int rc; struct mmoc_req { struct rpc_request_hdr hdr; uint32_t data[2]; } 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(0x30000066, 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; }
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; }