int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, unsigned int ch_cnt) { u16 grph = 0; int ret = 0; int i = 0 , idx = 0; struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt); for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM); if (idx < 0) { pr_err("%s: Error:- Invalid index found = %d\n", __func__, idx); ret = -EINVAL; goto err; } grph = tx[idx].grph; } /* slim_control_ch (REMOVE) */ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true); if (ret < 0) { pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret); goto err; } for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM); tx[idx].grph = 0; } err: return ret; }
int escore_close_slim_tx(struct slim_device *sbdev, unsigned int *ch_num, unsigned int ch_cnt) { struct escore_priv *escore_priv = slim_get_devicedata(sbdev); struct escore_slim_ch *tx = escore_priv->slim_tx; u16 grph = 0; u32 *sph; int i; int idx; int rc; sph = kmalloc(sizeof(u32)*escore_priv->slim_tx_ports, GFP_KERNEL); if (!sph) return -ENOMEM; dev_dbg(&sbdev->dev, "%s(ch_cnt = %d)\n", __func__, ch_cnt); for (i = 0; i < ch_cnt; i++) { idx = escore_tx_ch_num_to_idx(escore_priv, ch_num[i]); sph[i] = tx[idx].sph; grph = tx[idx].grph; } rc = slim_control_ch(sbdev, grph, SLIM_CH_REMOVE, true); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_control_ch() failed: %d\n", __func__, rc); goto slim_control_ch_error; } for (i = 0; i < ch_cnt; i++) { idx = escore_tx_ch_num_to_idx(escore_priv, ch_num[i]); tx[idx].grph = 0; } rc = slim_disconnect_ports(sbdev, sph, ch_cnt); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_disconnect_ports() failed: %d\n", __func__, rc); } slim_control_ch_error: kfree(sph); return rc; }
int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, unsigned int ch_cnt) { u16 grph = 0; u32 sph[SLIM_MAX_RX_PORTS] = {0}; int i = 0 , idx = 0; int ret = 0; struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt); for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); if (idx < 0) { pr_err("%s: Error:-Invalid index found = %d\n", __func__, idx); ret = -EINVAL; goto err; } sph[i] = rx[idx].sph; grph = rx[idx].grph; pr_debug("%s: ch_num[%d] %d, idx %d, sph[%d] %x, grph %x\n", __func__, i, ch_num[i], idx, i, sph[i], grph); } /* slim_control_ch (REMOVE) */ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true); if (ret < 0) { pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret); goto err; } /* slim_disconnect_port */ ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt); if (ret < 0) { pr_err("%s: slim_disconnect_ports failed ret[%d]\n", __func__, ret); } for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); rx[idx].grph = 0; } err: return ret; }
static int es705_close_slim_tx(struct slim_device *sbdev, unsigned int *ch_num, unsigned int ch_cnt) { struct es705_priv *es705_priv = slim_get_devicedata(sbdev); struct es705_slim_ch *tx = es705_priv->slim_tx; u16 grph = 0; u32 sph[ES705_SLIM_TX_PORTS] = {0}; int i; int idx; int rc; dev_dbg(&sbdev->dev, "%s(): ch_cnt = %d\n", __func__, ch_cnt); for (i = 0; i < ch_cnt; i++) { dev_dbg(&sbdev->dev, "%s(): ch_num = %d\n", __func__, ch_num[i]); idx = es705_tx_ch_num_to_idx(ch_num[i]); sph[i] = tx[idx].sph; grph = tx[idx].grph; } rc = slim_control_ch(sbdev, grph, SLIM_CH_REMOVE, true); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_connect_sink() failed: %d\n", __func__, rc); goto slim_control_ch_error; } for (i = 0; i < ch_cnt; i++) { dev_dbg(&sbdev->dev, "%s(): ch_num = %d\n", __func__, ch_num[i]); idx = es705_tx_ch_num_to_idx(ch_num[i]); tx[idx].grph = 0; } rc = slim_disconnect_ports(sbdev, sph, ch_cnt); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_disconnect_ports() failed: %d\n", __func__, rc); } slim_control_ch_error: return rc; }
static int es705_cfg_slim_tx(struct slim_device *sbdev, unsigned int *ch_num, unsigned int ch_cnt, unsigned int rate) { struct es705_priv *es705_priv = slim_get_devicedata(sbdev); struct es705_slim_ch *tx = es705_priv->slim_tx; u16 grph; u32 sph[ES705_SLIM_TX_PORTS] = {0}; u16 ch_h[ES705_SLIM_TX_PORTS] = {0}; struct slim_ch prop; int i; int idx; int rc; dev_dbg(&sbdev->dev, "%s(): ch_cnt = %d, rate = %d\n", __func__, ch_cnt, rate); for (i = 0; i < ch_cnt; i++) { dev_dbg(&sbdev->dev, "%s(): ch_num = %d\n", __func__, ch_num[i]); idx = es705_tx_ch_num_to_idx(ch_num[i]); ch_h[i] = tx[idx].ch_h; sph[i] = tx[idx].sph; } 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 = (rate/4000); prop.sampleszbits = 16; rc = slim_define_ch(sbdev, &prop, ch_h, ch_cnt, true, &grph); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_define_ch() failed: %d\n", __func__, rc); goto slim_define_ch_error; } for (i = 0; i < ch_cnt; i++) { rc = slim_connect_src(sbdev, sph[i], ch_h[i]); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_connect_src() failed: %d\n", __func__, rc); dev_err(&sbdev->dev, "%s(): ch_num[0] = %d\n", __func__, ch_num[0]); goto slim_connect_src_error; } } rc = slim_control_ch(sbdev, grph, SLIM_CH_ACTIVATE, true); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_control_ch() failed: %d\n", __func__, rc); goto slim_control_ch_error; } for (i = 0; i < ch_cnt; i++) { dev_info(&sbdev->dev, "%s(): ch_num = %d\n", __func__, ch_num[i]); idx = es705_tx_ch_num_to_idx(ch_num[i]); tx[idx].grph = grph; } return rc; slim_control_ch_error: slim_connect_src_error: es705_close_slim_tx(sbdev, ch_num, ch_cnt); slim_define_ch_error: return rc; }
/* Enable slimbus slave device for RX path */ int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, unsigned int ch_cnt, unsigned int rate) { u8 i = 0; u8 payload_tx_0 = 0, payload_tx_1 = 0, wm_payload = 0; u16 grph; u32 sph[SLIM_MAX_TX_PORTS] = {0}; u16 ch_h[SLIM_MAX_TX_PORTS] = {0}; u16 idx = 0, slave_port_id; int ret = 0; unsigned short multi_chan_cfg_reg_addr; struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; struct slim_ch prop; pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate); for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM); ch_h[i] = tx[idx].ch_h; sph[i] = tx[idx].sph; slave_port_id = idx ; if (slave_port_id > SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS) { pr_err("SLIMbus: invalid slave port id: %d", slave_port_id); ret = -EINVAL; goto err; } /* look for the valid port range and chose the * payload accordingly */ if (slave_port_id <= SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) { payload_tx_0 = payload_tx_0 | (1 << slave_port_id); } else if (slave_port_id <= SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) { payload_tx_1 = payload_tx_1 | (1 << (slave_port_id - SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID)); } else { ret = -EINVAL; goto err; } multi_chan_cfg_reg_addr = SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id); /* write to interface device */ ret = wcd9xxx_interface_reg_write(wcd9xxx, multi_chan_cfg_reg_addr, payload_tx_0); if (ret < 0) { pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", __func__, multi_chan_cfg_reg_addr, payload_tx_0, ret); goto err; } multi_chan_cfg_reg_addr = SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id); /* ports 8,9 */ ret = wcd9xxx_interface_reg_write(wcd9xxx, multi_chan_cfg_reg_addr, payload_tx_1); if (ret < 0) { pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", __func__, multi_chan_cfg_reg_addr, payload_tx_1, ret); goto err; } /* configure the slave port for water mark and enable*/ wm_payload = (SLAVE_PORT_WATER_MARK_VALUE << SLAVE_PORT_WATER_MARK_SHIFT) + SLAVE_PORT_ENABLE; ret = wcd9xxx_interface_reg_write(wcd9xxx, SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id), wm_payload); if (ret < 0) { pr_err("%s:watermark set failure for port[%d] ret[%d]", __func__, slave_port_id, ret); } } /* slim_define_ch api */ 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 = (rate/4000); prop.sampleszbits = 16; ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, true, &grph); if (ret < 0) { pr_err("%s: slim_define_ch failed ret[%d]\n", __func__, ret); goto err; } for (i = 0; i < ch_cnt; i++) { ret = slim_connect_src(wcd9xxx->slim, sph[i], ch_h[i]); if (ret < 0) { pr_err("%s: slim_connect_src failed ret[%d]\n", __func__, ret); goto err; } } /* slim_control_ch */ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE, true); if (ret < 0) { pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret); goto err; } for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM); tx[idx].grph = grph; } return 0; err: /* release all acquired handles */ wcd9xxx_close_slim_sch_tx(wcd9xxx, ch_num, ch_cnt); return ret; }
static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data, struct snd_soc_dai *dai, enum msm_dai_slim_event event) { struct slim_device *sdev; struct msm_dai_slim_drv_data *drv_data; struct msm_slim_dai_data *dai_data; int rc, rc1, i; if (!dma_data || !dma_data->sdev) { pr_err("%s: Invalid %s\n", __func__, (!dma_data) ? "dma_data" : "slim_device"); return -EINVAL; } sdev = dma_data->sdev; drv_data = dev_get_drvdata(&sdev->dev); dai_data = msm_slim_get_dai_data(drv_data, dai); if (!dai_data) { dev_err(dai->dev, "%s: Invalid dai_data for dai_id %d\n", __func__, dai->id); return -EINVAL; } dev_dbg(&sdev->dev, "%s: event = 0x%x, rate = %u\n", __func__, event, dai_data->rate); switch (event) { case MSM_DAI_SLIM_ENABLE: if (!(dai_data->status & DAI_STATE_PREPARED)) { dev_err(&sdev->dev, "%s: dai id (%d) has invalid state 0x%x\n", __func__, dai->id, dai_data->status); return -EINVAL; } rc = slim_alloc_mgrports(sdev, SLIM_REQ_DEFAULT, dai_data->ch_cnt, &(dma_data->ph), sizeof(dma_data->ph)); if (IS_ERR_VALUE(rc)) { dev_err(&sdev->dev, "%s:alloc mgrport failed rc %d\n", __func__ , rc); goto done; } rc = slim_config_mgrports(sdev, &(dma_data->ph), dai_data->ch_cnt, &(dai_data->port_cfg)); if (IS_ERR_VALUE(rc)) { dev_err(&sdev->dev, "%s: config mgrport failed rc %d\n", __func__ , rc); goto err_done; } for (i = 0; i < dai_data->ch_cnt; i++) { rc = slim_connect_sink(sdev, &dma_data->ph, 1, dai_data->chan_h[i]); if (IS_ERR_VALUE(rc)) { dev_err(&sdev->dev, "%s: slim_connect_sink failed, ch = %d, err = %d\n", __func__, i, rc); goto err_done; } } rc = slim_control_ch(sdev, dai_data->grph, SLIM_CH_ACTIVATE, true); if (IS_ERR_VALUE(rc)) { dev_err(&sdev->dev, "%s: slim activate ch failed, err = %d\n", __func__, rc); goto err_done; } /* Mark dai status as running */ SET_DAI_STATE(dai_data->status, DAI_STATE_RUNNING); break; case MSM_DAI_SLIM_PRE_DISABLE: if (!(dai_data->status & DAI_STATE_RUNNING)) { dev_err(&sdev->dev, "%s: dai id (%d) has invalid state 0x%x\n", __func__, dai->id, dai_data->status); return -EINVAL; } rc = slim_control_ch(sdev, dai_data->grph, SLIM_CH_REMOVE, true); if (IS_ERR_VALUE(rc)) { dev_err(&sdev->dev, "%s: slim activate ch failed, err = %d\n", __func__, rc); goto done; } break; case MSM_DAI_SLIM_DISABLE: rc = slim_dealloc_mgrports(sdev, &dma_data->ph, 1); if (IS_ERR_VALUE(rc)) { dev_err(&sdev->dev, "%s: dealloc mgrport failed, err = %d\n", __func__, rc); goto done; } /* clear running state for dai*/ CLR_DAI_STATE(dai_data->status, DAI_STATE_RUNNING); break; default: dev_err(&sdev->dev, "%s: Unhandled event 0x%x\n", __func__, event); rc = -EINVAL; goto done; } return rc; err_done: rc1 = slim_dealloc_mgrports(sdev, &dma_data->ph, 1); if (IS_ERR_VALUE(rc1)) dev_err(&sdev->dev, "%s: dealloc mgrport failed, err = %d\n", __func__, rc1); done: return rc; }
/* Enable slimbus slave device for RX path */ int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, unsigned int ch_cnt, unsigned int rate) { u8 i; u16 grph; u32 sph[SLIM_MAX_RX_PORTS] = {0}; u16 ch_h[SLIM_MAX_RX_PORTS] = {0}; u16 slave_port_id; u8 payload_rx = 0, wm_payload = 0; int ret, idx = 0; unsigned short multi_chan_cfg_reg_addr; struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; struct slim_ch prop; /* Configure slave interface device */ pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate); for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); ch_h[i] = rx[idx].ch_h; sph[i] = rx[idx].sph; slave_port_id = idx; pr_debug("%s: idx %d, ch_h %d, sph %d\n", __func__, idx, ch_h[i], sph[i]); if ((slave_port_id > sh_ch.num_rx_slave_port)) { pr_err("Slimbus: invalid slave port id: %d", slave_port_id); ret = -EINVAL; goto err; } slave_port_id += sh_ch.rx_port_start_offset; pr_debug("%s: slave_port_id %d\n", __func__, slave_port_id); /* look for the valid port range and chose the * payload accordingly */ if ((slave_port_id > sh_ch.pgd_tx_port_ch_1_end_port_id) && (slave_port_id <= sh_ch.port_ch_0_end_port_id)) { payload_rx = payload_rx | (1 << (slave_port_id - sh_ch.port_ch_0_start_port_id)); } else { ret = -EINVAL; goto err; } multi_chan_cfg_reg_addr = SB_PGD_RX_PORT_MULTI_CHANNEL_0(sh_ch.rx_port_ch_reg_base, idx); pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__, multi_chan_cfg_reg_addr); /* write to interface device */ ret = wcd9xxx_interface_reg_write(wcd9xxx, multi_chan_cfg_reg_addr, payload_rx); if (ret < 0) { pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", __func__, multi_chan_cfg_reg_addr, payload_rx, ret); goto err; } /* configure the slave port for water mark and enable*/ wm_payload = (SLAVE_PORT_WATER_MARK_VALUE << SLAVE_PORT_WATER_MARK_SHIFT) + SLAVE_PORT_ENABLE; ret = wcd9xxx_interface_reg_write( wcd9xxx, SB_PGD_PORT_CFG_BYTE_ADDR( sh_ch.port_rx_cfg_reg_base, idx), wm_payload); if (ret < 0) { pr_err("%s:watermark set failure for port[%d] ret[%d]", __func__, slave_port_id, ret); } } /* slim_define_ch api */ 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 = (rate/4000); prop.sampleszbits = 16; ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, true, &grph); if (ret < 0) { pr_err("%s: slim_define_ch failed ret[%d]\n", __func__, ret); goto err; } for (i = 0; i < ch_cnt; i++) { ret = slim_connect_sink(wcd9xxx->slim, &sph[i], 1, ch_h[i]); if (ret < 0) { pr_err("%s: slim_connect_sink failed ret[%d]\n", __func__, ret); goto err_close_slim_sch; } } /* slim_control_ch */ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE, true); if (ret < 0) { pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret); goto err_close_slim_sch; } for (i = 0; i < ch_cnt; i++) { idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); rx[idx].grph = grph; } return 0; err_close_slim_sch: /* release all acquired handles */ wcd9xxx_close_slim_sch_rx(wcd9xxx, ch_num, ch_cnt); err: return ret; }
int escore_cfg_slim_tx(struct slim_device *sbdev, unsigned int *ch_num, unsigned int ch_cnt, unsigned int rate) { struct escore_priv *escore_priv = slim_get_devicedata(sbdev); struct escore_slim_ch *tx = escore_priv->slim_tx; u16 grph; u32 *sph; u16 *ch_h; struct slim_ch prop; int i; int idx; int rc; dev_dbg(&sbdev->dev, "%s(ch_cnt = %d, rate = %d)\n", __func__, ch_cnt, rate); sph = kmalloc(sizeof(u32)*escore_priv->slim_rx_ports, GFP_KERNEL); if (!sph) return -ENOMEM; ch_h = kmalloc(sizeof(u32)*escore_priv->slim_rx_ports, GFP_KERNEL); if (!ch_h) { kfree(sph); return -ENOMEM; } for (i = 0; i < ch_cnt; i++) { idx = escore_tx_ch_num_to_idx(escore_priv, ch_num[i]); ch_h[i] = tx[idx].ch_h; sph[i] = tx[idx].sph; } 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 = (rate/4000); prop.sampleszbits = 16; rc = slim_define_ch(sbdev, &prop, ch_h, ch_cnt, true, &grph); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_define_ch() failed: %d\n", __func__, rc); goto slim_define_ch_error; } for (i = 0; i < ch_cnt; i++) { rc = slim_connect_src(sbdev, sph[i], ch_h[i]); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_connect_src() failed: %d\n", __func__, rc); dev_err(&sbdev->dev, "%s(): ch_num[0] = %d\n", __func__, ch_num[0]); goto slim_connect_src_error; } } rc = slim_control_ch(sbdev, grph, SLIM_CH_ACTIVATE, true); if (rc < 0) { dev_err(&sbdev->dev, "%s(): slim_control_ch() failed: %d\n", __func__, rc); goto slim_control_ch_error; } for (i = 0; i < ch_cnt; i++) { idx = escore_tx_ch_num_to_idx(escore_priv, ch_num[i]); tx[idx].grph = grph; } kfree(sph); kfree(ch_h); return rc; slim_control_ch_error: slim_connect_src_error: escore_close_slim_tx(sbdev, ch_num, ch_cnt); slim_define_ch_error: kfree(sph); kfree(ch_h); return rc; }