Loading arch/arm/boot/dts/qcom/msm8996.dtsi +5 −0 Original line number Diff line number Diff line Loading @@ -958,6 +958,11 @@ qcom,apps-ch-pipes = <0x60000000>; qcom,ea-pc = <0x160>; msm_dai_slim { compatible = "qcom,msm-dai-slim"; elemental-addr = [ff ff ff fe 17 02]; }; tomtom_codec { compatible = "qcom,tomtom-slim-pgd"; elemental-addr = [00 01 30 01 17 02]; Loading drivers/mfd/wcd9xxx-slimslave.c +0 −306 Original line number Diff line number Diff line Loading @@ -14,31 +14,6 @@ #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> #define WCD_SLIM_INVALID_SAMPLE_RATE(r) \ ((r/4000)%4) struct wcd9xxx_slim_master_prop { u16 chanh; u16 grph; u32 ph1; struct slim_ch prop; }; struct slim_session { struct completion sb_comp; void *handle; }; struct wcd9xxx_master_cfg { struct wcd9xxx_slim_master_prop *slim_cfg; u16 sample_rate; u16 sample_size; u32 ref_count; struct slim_session slim_s; struct mutex lock; }; static struct wcd9xxx_master_cfg slim_tx_master; struct wcd9xxx_slim_sch { u16 rx_port_ch_reg_base; u16 port_tx_cfg_reg_base; Loading Loading @@ -130,8 +105,6 @@ int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la, pr_err("Not able to allocate memory for %d slimbus tx ports\n", wcd9xxx->num_tx_port); } mutex_init(&slim_tx_master.lock); init_completion(&slim_tx_master.slim_s.sb_comp); return 0; err: return ret; Loading Loading @@ -588,282 +561,3 @@ int wcd9xxx_tx_vport_validation(u32 table, u32 port_id, return ret; } EXPORT_SYMBOL_GPL(wcd9xxx_tx_vport_validation); int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, u16 rate, u16 bit_sz, void **handle, u16 slim_channel) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; struct slim_ch *prop; pr_debug("%s: rate 0x%x bit_sz 0x%x\n", __func__, rate, bit_sz); if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", __func__, wcd9xxx, handle); return -EINVAL; } if (WCD_SLIM_INVALID_SAMPLE_RATE(rate)) { pr_err("%s: Invalid sample rate 0x%x\n", __func__, rate); return -EINVAL; } tx_master = &slim_tx_master; tx_master->ref_count++; if (tx_master->ref_count > 1) { pr_err("%s: Slim channel already open, ref_count = %u\n", __func__, tx_master->ref_count); return -EINVAL; } slim_cfg = kzalloc(sizeof(struct wcd9xxx_slim_master_prop), GFP_KERNEL); if (slim_cfg == NULL) { pr_err("%s:Memory allocation for slim_cfg fail\n", __func__); return -ENOMEM; } mutex_lock(&tx_master->lock); tx_master->sample_rate = rate; tx_master->sample_size = bit_sz; tx_master->slim_cfg = slim_cfg; prop = &slim_cfg->prop; prop->prot = SLIM_AUTO_ISO; prop->baser = SLIM_RATE_4000HZ; prop->dataf = SLIM_CH_DATAF_NOT_DEFINED; prop->auxf = SLIM_CH_AUXF_NOT_APPLICABLE; prop->ratem = tx_master->sample_rate/4000; prop->sampleszbits = bit_sz; rc = slim_query_ch(wcd9xxx->slim, slim_channel, &(slim_cfg->chanh)); if (rc) { pr_err("%s:Err query ch ret:%d, chanh:0x%x\n", __func__ , rc, slim_cfg->chanh); goto fail; } rc = slim_define_ch(wcd9xxx->slim, &(slim_cfg->prop), &(slim_cfg->chanh), 1, true, &(slim_cfg->grph)); if (rc) { pr_err("%s:Err slim_define_ch ch ret:%d, grph:0x%x\n", __func__, rc, slim_cfg->grph); goto fail; } rc = slim_alloc_mgrports(wcd9xxx->slim, SLIM_REQ_DEFAULT, 1, &(slim_cfg->ph1), sizeof(slim_cfg->ph1)); if (rc) { pr_err("%s:alloc mgr port:ret:%d\n", __func__, rc); goto fail; } *handle = (struct wcd9xxx_master_cfg *)tx_master; tx_master->slim_s.handle = *handle; init_completion(&tx_master->slim_s.sb_comp); pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp handle %x\n" "chanh %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, tx_master->slim_cfg->grph, tx_master->slim_cfg->chanh); mutex_unlock(&tx_master->lock); pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp\n" "handle %x chanh %x ref count %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, tx_master->slim_cfg->grph, tx_master->slim_cfg->chanh, tx_master->ref_count); return 0; fail: mutex_unlock(&tx_master->lock); kfree(slim_cfg); slim_control_ch(wcd9xxx->slim, slim_cfg->grph, SLIM_CH_REMOVE, true); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_open); int wcd9xxx_slim_ch_master_close(struct wcd9xxx *wcd9xxx, void **handle) { int rc = 0, err = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (*handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, *handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; rc = slim_control_ch(wcd9xxx->slim, slim_cfg->grph, SLIM_CH_REMOVE, true); if (rc) { pr_err("%s:dealloc mgrport returned :%d\n", __func__, rc); err = rc; } rc = slim_dealloc_mgrports(wcd9xxx->slim, &slim_cfg->ph1, 1); if (rc) { pr_err("%s:dealloc mgrport returned :%d\n", __func__, rc); if (!err) err = rc; } rc = slim_dealloc_ch(wcd9xxx->slim, slim_cfg->chanh); if (rc) { pr_err("%s:dealloc ch ret:%d, chanh:0x%x\n", __func__, rc, slim_cfg->chanh); if (!err) err = rc; } if (err) { rc = err; goto fail; } tx_master->slim_s.handle = NULL; tx_master->ref_count--; *handle = NULL; fail: mutex_unlock(&tx_master->lock); kfree(tx_master->slim_cfg); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_close); int wcd9xxx_slim_ch_master_status(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u32 *len) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; struct completion *sb_comp; if (wcd9xxx == NULL || len == NULL) { pr_err("%s: Invlaid len/wcd9xxx pointer\n", __func__); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; sb_comp = &tx_master->slim_s.sb_comp; rc = wait_for_completion_timeout(sb_comp, (2 * (HZ/10))); rc = slim_port_get_xfer_status(wcd9xxx->slim, slim_cfg->ph1, &phys, len); if (rc || *len == 0) { pr_err("%s: Get Xfer status rc %x, len %x\n", __func__, rc, *(len)); } if (!rc && *len == 0) { /* * If timeout occurred and the length of * buffer returned is 0, then there is a * error on the bus, return error to caller * to avoid queuing more buffers. */ pr_err("%s: no buffer returned after timeout\n", __func__); rc = -EIO; } mutex_unlock(&tx_master->lock); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_status); int wcd9xxx_slim_ch_master_enable_read(struct wcd9xxx *wcd9xxx, void *handle) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; pr_debug("%s:handle = %p\n", __func__, handle); if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; rc = slim_connect_sink(wcd9xxx->slim, &slim_cfg->ph1, 1 , slim_cfg->chanh); if (rc) { pr_err("%s:connect src ret:%d\n", __func__, rc); goto error_exit; } rc = slim_control_ch(wcd9xxx->slim, slim_cfg->grph, SLIM_CH_ACTIVATE, true); if (rc) { pr_err("%s:activate ch ret:%d\n", __func__, rc); goto error_exit; } mutex_unlock(&tx_master->lock); return 0; error_exit: mutex_unlock(&tx_master->lock); /*Client has to close if error, do not clean up here*/ return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_enable_read); int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u8 *mem, u32 read_len) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; struct completion *sb_comp; pr_debug("%s: handle %p len %x\n", __func__, handle, read_len); if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invlaid handle/wcd9xxx pointer\n", __func__); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; sb_comp = &tx_master->slim_s.sb_comp; rc = slim_port_xfer(wcd9xxx->slim, slim_cfg->ph1, phys, read_len, sb_comp); if (rc) { pr_err("%s:Slimbus master read failure rc %d\n", __func__, rc); } mutex_unlock(&tx_master->lock); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_read); include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h +0 −10 Original line number Diff line number Diff line Loading @@ -116,14 +116,4 @@ int wcd9xxx_rx_vport_validation(u32 port_id, int wcd9xxx_tx_vport_validation(u32 vtable, u32 port_id, struct wcd9xxx_codec_dai_data *codec_dai, u32 num_codec_dais); int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, u16 rate, u16 bit_sz, void **handle, u16 slim_channel); int wcd9xxx_slim_ch_master_close(struct wcd9xxx *wcd9xxx, void **handle); int wcd9xxx_slim_ch_master_status(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u32 *len); int wcd9xxx_slim_ch_master_enable_read(struct wcd9xxx *wcd9xxx, void *handle); int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u8 *mem, u32 read_len); #endif /* __WCD9310_SLIMSLAVE_H_ */ include/sound/cpe_core.h +15 −53 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, Linux Foundation. All rights reserved. * Copyright (c) 2013-2015, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -16,10 +16,8 @@ #include <linux/types.h> #include <linux/wait.h> #include <linux/msm_ion.h> #include <linux/dma-mapping.h> #include <sound/lsm_params.h> #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h> enum { CMD_INIT_STATE = 0, Loading @@ -27,6 +25,13 @@ enum { CMD_RESP_RCVD, }; enum wcd_cpe_event { WCD_CPE_PRE_ENABLE = 1, WCD_CPE_POST_ENABLE, WCD_CPE_PRE_DISABLE, WCD_CPE_POST_DISABLE, }; struct wcd_cpe_afe_port_cfg { u8 port_id; u16 bit_width; Loading @@ -34,47 +39,13 @@ struct wcd_cpe_afe_port_cfg { u32 sample_rate; }; enum wcd_cpe_lab_thread { MSM_LSM_LAB_THREAD_STOP, MSM_LSM_LAB_THREAD_RUNNING, MSM_LSM_LAB_THREAD_ERROR, }; struct wcd_cpe_data_pcm_buf { u8 *mem; phys_addr_t phys; }; struct wcd_cpe_lab_hw_params { u16 sample_rate; u16 sample_size; u32 buf_sz; u32 period_count; }; struct wcd_cpe_lsm_lab { u32 lab_enable; void *slim_handle; void *core_handle; atomic_t in_count; atomic_t abort_read; u32 dma_write; u32 buf_idx; u32 pcm_size; enum wcd_cpe_lab_thread thread_status; struct cpe_lsm_session *lsm_s; struct snd_pcm_substream *substream; struct wcd_cpe_lab_hw_params hw_params; struct wcd_cpe_data_pcm_buf *pcm_buf; wait_queue_head_t period_wait; struct completion thread_complete; }; struct cpe_lsm_session { /* sound model related */ void *snd_model_data; u8 *conf_levels; void *cmi_reg_handle; /* Clients private data */ void *priv_d; void (*event_cb) (void *priv_data, Loading @@ -91,8 +62,9 @@ struct cpe_lsm_session { u8 id; u8 num_confidence_levels; struct task_struct *lsm_lab_thread; struct wcd_cpe_lsm_lab lab; bool started; u32 lab_enable; }; struct wcd_cpe_afe_ops { Loading Loading @@ -150,21 +122,11 @@ struct wcd_cpe_lsm_ops { int (*lsm_lab_control)(void *core_handle, struct cpe_lsm_session *session, u32 bufsz, u32 bufcnt, bool enable); int (*lsm_lab_stop)(void *core_handle, struct cpe_lsm_session *session); int (*lsm_lab_data_channel_open)(void *core_handle, struct cpe_lsm_session *session); int (*lsm_lab_data_channel_read_status)(void *core_handle, struct cpe_lsm_session *session, phys_addr_t phys, u32 *len); int (*lsm_lab_data_channel_read)(void *core_handle, int (*lab_ch_setup)(void *core_handle, struct cpe_lsm_session *session, phys_addr_t phys, u8 *mem, u32 read_len); enum wcd_cpe_event event); int (*lsm_set_data) (void *core_handle, struct cpe_lsm_session *session, Loading sound/soc/codecs/wcd9335.c +9 −1 Original line number Diff line number Diff line Loading @@ -6359,6 +6359,7 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, { struct tasha_priv *tasha; struct wcd9xxx *core; struct wcd9xxx_codec_dai_data *dai_data = NULL; if (!dai) { pr_err("%s: dai is empty\n", __func__); Loading @@ -6380,6 +6381,12 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { wcd9xxx_init_slimslave(core, core->slim->laddr, tx_num, tx_slot, rx_num, rx_slot); /* Reserve TX12 for MAD data channel */ dai_data = &tasha->dai[AIF4_MAD_TX]; if (dai_data) { list_add_tail(&core->tx_chs[TASHA_TX12].list, &dai_data->wcd9xxx_ch_list); } } return 0; } Loading Loading @@ -6688,7 +6695,8 @@ static int tasha_hw_params(struct snd_pcm_substream *substream, __func__, tx_fs_rate); return -EINVAL; } if (dai->id != AIF4_VIFEED) { if (dai->id != AIF4_VIFEED && dai->id != AIF4_MAD_TX) { ret = tasha_set_decimator_rate(dai, tx_fs_rate, params_rate(params)); if (ret < 0) { Loading Loading
arch/arm/boot/dts/qcom/msm8996.dtsi +5 −0 Original line number Diff line number Diff line Loading @@ -958,6 +958,11 @@ qcom,apps-ch-pipes = <0x60000000>; qcom,ea-pc = <0x160>; msm_dai_slim { compatible = "qcom,msm-dai-slim"; elemental-addr = [ff ff ff fe 17 02]; }; tomtom_codec { compatible = "qcom,tomtom-slim-pgd"; elemental-addr = [00 01 30 01 17 02]; Loading
drivers/mfd/wcd9xxx-slimslave.c +0 −306 Original line number Diff line number Diff line Loading @@ -14,31 +14,6 @@ #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> #define WCD_SLIM_INVALID_SAMPLE_RATE(r) \ ((r/4000)%4) struct wcd9xxx_slim_master_prop { u16 chanh; u16 grph; u32 ph1; struct slim_ch prop; }; struct slim_session { struct completion sb_comp; void *handle; }; struct wcd9xxx_master_cfg { struct wcd9xxx_slim_master_prop *slim_cfg; u16 sample_rate; u16 sample_size; u32 ref_count; struct slim_session slim_s; struct mutex lock; }; static struct wcd9xxx_master_cfg slim_tx_master; struct wcd9xxx_slim_sch { u16 rx_port_ch_reg_base; u16 port_tx_cfg_reg_base; Loading Loading @@ -130,8 +105,6 @@ int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la, pr_err("Not able to allocate memory for %d slimbus tx ports\n", wcd9xxx->num_tx_port); } mutex_init(&slim_tx_master.lock); init_completion(&slim_tx_master.slim_s.sb_comp); return 0; err: return ret; Loading Loading @@ -588,282 +561,3 @@ int wcd9xxx_tx_vport_validation(u32 table, u32 port_id, return ret; } EXPORT_SYMBOL_GPL(wcd9xxx_tx_vport_validation); int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, u16 rate, u16 bit_sz, void **handle, u16 slim_channel) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; struct slim_ch *prop; pr_debug("%s: rate 0x%x bit_sz 0x%x\n", __func__, rate, bit_sz); if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", __func__, wcd9xxx, handle); return -EINVAL; } if (WCD_SLIM_INVALID_SAMPLE_RATE(rate)) { pr_err("%s: Invalid sample rate 0x%x\n", __func__, rate); return -EINVAL; } tx_master = &slim_tx_master; tx_master->ref_count++; if (tx_master->ref_count > 1) { pr_err("%s: Slim channel already open, ref_count = %u\n", __func__, tx_master->ref_count); return -EINVAL; } slim_cfg = kzalloc(sizeof(struct wcd9xxx_slim_master_prop), GFP_KERNEL); if (slim_cfg == NULL) { pr_err("%s:Memory allocation for slim_cfg fail\n", __func__); return -ENOMEM; } mutex_lock(&tx_master->lock); tx_master->sample_rate = rate; tx_master->sample_size = bit_sz; tx_master->slim_cfg = slim_cfg; prop = &slim_cfg->prop; prop->prot = SLIM_AUTO_ISO; prop->baser = SLIM_RATE_4000HZ; prop->dataf = SLIM_CH_DATAF_NOT_DEFINED; prop->auxf = SLIM_CH_AUXF_NOT_APPLICABLE; prop->ratem = tx_master->sample_rate/4000; prop->sampleszbits = bit_sz; rc = slim_query_ch(wcd9xxx->slim, slim_channel, &(slim_cfg->chanh)); if (rc) { pr_err("%s:Err query ch ret:%d, chanh:0x%x\n", __func__ , rc, slim_cfg->chanh); goto fail; } rc = slim_define_ch(wcd9xxx->slim, &(slim_cfg->prop), &(slim_cfg->chanh), 1, true, &(slim_cfg->grph)); if (rc) { pr_err("%s:Err slim_define_ch ch ret:%d, grph:0x%x\n", __func__, rc, slim_cfg->grph); goto fail; } rc = slim_alloc_mgrports(wcd9xxx->slim, SLIM_REQ_DEFAULT, 1, &(slim_cfg->ph1), sizeof(slim_cfg->ph1)); if (rc) { pr_err("%s:alloc mgr port:ret:%d\n", __func__, rc); goto fail; } *handle = (struct wcd9xxx_master_cfg *)tx_master; tx_master->slim_s.handle = *handle; init_completion(&tx_master->slim_s.sb_comp); pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp handle %x\n" "chanh %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, tx_master->slim_cfg->grph, tx_master->slim_cfg->chanh); mutex_unlock(&tx_master->lock); pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp\n" "handle %x chanh %x ref count %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, tx_master->slim_cfg->grph, tx_master->slim_cfg->chanh, tx_master->ref_count); return 0; fail: mutex_unlock(&tx_master->lock); kfree(slim_cfg); slim_control_ch(wcd9xxx->slim, slim_cfg->grph, SLIM_CH_REMOVE, true); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_open); int wcd9xxx_slim_ch_master_close(struct wcd9xxx *wcd9xxx, void **handle) { int rc = 0, err = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (*handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, *handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; rc = slim_control_ch(wcd9xxx->slim, slim_cfg->grph, SLIM_CH_REMOVE, true); if (rc) { pr_err("%s:dealloc mgrport returned :%d\n", __func__, rc); err = rc; } rc = slim_dealloc_mgrports(wcd9xxx->slim, &slim_cfg->ph1, 1); if (rc) { pr_err("%s:dealloc mgrport returned :%d\n", __func__, rc); if (!err) err = rc; } rc = slim_dealloc_ch(wcd9xxx->slim, slim_cfg->chanh); if (rc) { pr_err("%s:dealloc ch ret:%d, chanh:0x%x\n", __func__, rc, slim_cfg->chanh); if (!err) err = rc; } if (err) { rc = err; goto fail; } tx_master->slim_s.handle = NULL; tx_master->ref_count--; *handle = NULL; fail: mutex_unlock(&tx_master->lock); kfree(tx_master->slim_cfg); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_close); int wcd9xxx_slim_ch_master_status(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u32 *len) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; struct completion *sb_comp; if (wcd9xxx == NULL || len == NULL) { pr_err("%s: Invlaid len/wcd9xxx pointer\n", __func__); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; sb_comp = &tx_master->slim_s.sb_comp; rc = wait_for_completion_timeout(sb_comp, (2 * (HZ/10))); rc = slim_port_get_xfer_status(wcd9xxx->slim, slim_cfg->ph1, &phys, len); if (rc || *len == 0) { pr_err("%s: Get Xfer status rc %x, len %x\n", __func__, rc, *(len)); } if (!rc && *len == 0) { /* * If timeout occurred and the length of * buffer returned is 0, then there is a * error on the bus, return error to caller * to avoid queuing more buffers. */ pr_err("%s: no buffer returned after timeout\n", __func__); rc = -EIO; } mutex_unlock(&tx_master->lock); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_status); int wcd9xxx_slim_ch_master_enable_read(struct wcd9xxx *wcd9xxx, void *handle) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; pr_debug("%s:handle = %p\n", __func__, handle); if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; rc = slim_connect_sink(wcd9xxx->slim, &slim_cfg->ph1, 1 , slim_cfg->chanh); if (rc) { pr_err("%s:connect src ret:%d\n", __func__, rc); goto error_exit; } rc = slim_control_ch(wcd9xxx->slim, slim_cfg->grph, SLIM_CH_ACTIVATE, true); if (rc) { pr_err("%s:activate ch ret:%d\n", __func__, rc); goto error_exit; } mutex_unlock(&tx_master->lock); return 0; error_exit: mutex_unlock(&tx_master->lock); /*Client has to close if error, do not clean up here*/ return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_enable_read); int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u8 *mem, u32 read_len) { int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; struct completion *sb_comp; pr_debug("%s: handle %p len %x\n", __func__, handle, read_len); if (wcd9xxx == NULL || handle == NULL) { pr_err("%s: Invlaid handle/wcd9xxx pointer\n", __func__); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } mutex_lock(&tx_master->lock); slim_cfg = tx_master->slim_cfg; sb_comp = &tx_master->slim_s.sb_comp; rc = slim_port_xfer(wcd9xxx->slim, slim_cfg->ph1, phys, read_len, sb_comp); if (rc) { pr_err("%s:Slimbus master read failure rc %d\n", __func__, rc); } mutex_unlock(&tx_master->lock); return rc; } EXPORT_SYMBOL(wcd9xxx_slim_ch_master_read);
include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h +0 −10 Original line number Diff line number Diff line Loading @@ -116,14 +116,4 @@ int wcd9xxx_rx_vport_validation(u32 port_id, int wcd9xxx_tx_vport_validation(u32 vtable, u32 port_id, struct wcd9xxx_codec_dai_data *codec_dai, u32 num_codec_dais); int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, u16 rate, u16 bit_sz, void **handle, u16 slim_channel); int wcd9xxx_slim_ch_master_close(struct wcd9xxx *wcd9xxx, void **handle); int wcd9xxx_slim_ch_master_status(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u32 *len); int wcd9xxx_slim_ch_master_enable_read(struct wcd9xxx *wcd9xxx, void *handle); int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, phys_addr_t phys, u8 *mem, u32 read_len); #endif /* __WCD9310_SLIMSLAVE_H_ */
include/sound/cpe_core.h +15 −53 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, Linux Foundation. All rights reserved. * Copyright (c) 2013-2015, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -16,10 +16,8 @@ #include <linux/types.h> #include <linux/wait.h> #include <linux/msm_ion.h> #include <linux/dma-mapping.h> #include <sound/lsm_params.h> #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h> enum { CMD_INIT_STATE = 0, Loading @@ -27,6 +25,13 @@ enum { CMD_RESP_RCVD, }; enum wcd_cpe_event { WCD_CPE_PRE_ENABLE = 1, WCD_CPE_POST_ENABLE, WCD_CPE_PRE_DISABLE, WCD_CPE_POST_DISABLE, }; struct wcd_cpe_afe_port_cfg { u8 port_id; u16 bit_width; Loading @@ -34,47 +39,13 @@ struct wcd_cpe_afe_port_cfg { u32 sample_rate; }; enum wcd_cpe_lab_thread { MSM_LSM_LAB_THREAD_STOP, MSM_LSM_LAB_THREAD_RUNNING, MSM_LSM_LAB_THREAD_ERROR, }; struct wcd_cpe_data_pcm_buf { u8 *mem; phys_addr_t phys; }; struct wcd_cpe_lab_hw_params { u16 sample_rate; u16 sample_size; u32 buf_sz; u32 period_count; }; struct wcd_cpe_lsm_lab { u32 lab_enable; void *slim_handle; void *core_handle; atomic_t in_count; atomic_t abort_read; u32 dma_write; u32 buf_idx; u32 pcm_size; enum wcd_cpe_lab_thread thread_status; struct cpe_lsm_session *lsm_s; struct snd_pcm_substream *substream; struct wcd_cpe_lab_hw_params hw_params; struct wcd_cpe_data_pcm_buf *pcm_buf; wait_queue_head_t period_wait; struct completion thread_complete; }; struct cpe_lsm_session { /* sound model related */ void *snd_model_data; u8 *conf_levels; void *cmi_reg_handle; /* Clients private data */ void *priv_d; void (*event_cb) (void *priv_data, Loading @@ -91,8 +62,9 @@ struct cpe_lsm_session { u8 id; u8 num_confidence_levels; struct task_struct *lsm_lab_thread; struct wcd_cpe_lsm_lab lab; bool started; u32 lab_enable; }; struct wcd_cpe_afe_ops { Loading Loading @@ -150,21 +122,11 @@ struct wcd_cpe_lsm_ops { int (*lsm_lab_control)(void *core_handle, struct cpe_lsm_session *session, u32 bufsz, u32 bufcnt, bool enable); int (*lsm_lab_stop)(void *core_handle, struct cpe_lsm_session *session); int (*lsm_lab_data_channel_open)(void *core_handle, struct cpe_lsm_session *session); int (*lsm_lab_data_channel_read_status)(void *core_handle, struct cpe_lsm_session *session, phys_addr_t phys, u32 *len); int (*lsm_lab_data_channel_read)(void *core_handle, int (*lab_ch_setup)(void *core_handle, struct cpe_lsm_session *session, phys_addr_t phys, u8 *mem, u32 read_len); enum wcd_cpe_event event); int (*lsm_set_data) (void *core_handle, struct cpe_lsm_session *session, Loading
sound/soc/codecs/wcd9335.c +9 −1 Original line number Diff line number Diff line Loading @@ -6359,6 +6359,7 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, { struct tasha_priv *tasha; struct wcd9xxx *core; struct wcd9xxx_codec_dai_data *dai_data = NULL; if (!dai) { pr_err("%s: dai is empty\n", __func__); Loading @@ -6380,6 +6381,12 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { wcd9xxx_init_slimslave(core, core->slim->laddr, tx_num, tx_slot, rx_num, rx_slot); /* Reserve TX12 for MAD data channel */ dai_data = &tasha->dai[AIF4_MAD_TX]; if (dai_data) { list_add_tail(&core->tx_chs[TASHA_TX12].list, &dai_data->wcd9xxx_ch_list); } } return 0; } Loading Loading @@ -6688,7 +6695,8 @@ static int tasha_hw_params(struct snd_pcm_substream *substream, __func__, tx_fs_rate); return -EINVAL; } if (dai->id != AIF4_VIFEED) { if (dai->id != AIF4_VIFEED && dai->id != AIF4_MAD_TX) { ret = tasha_set_decimator_rate(dai, tx_fs_rate, params_rate(params)); if (ret < 0) { Loading