/* * calculate_sscr0: Calculate sscr0 register * @settings: config settings * @bps: bits per sample * * Calculate sscr0 register */ static uint32_t calculate_sscr0(const AplI2sSettings *settings, int bps) { uint32_t sscr0 = 0; if (bps > 16) sscr0 = SSCR0_reg(DSS, SSCR0_DataSize(bps - 16)) | SSCR0_reg(EDSS, EDSS_17_32_BITS); else sscr0 = SSCR0_reg(DSS, SSCR0_DataSize(bps)) | SSCR0_reg(EDSS, EDSS_4_16_BITS); sscr0 |= SSCR0_reg(MOD, settings->mode) | SSCR0_reg(FRF, PSP_FORMAT) | SSCR0_reg(SCR, 0x7) | SSCR0_reg(RIM, SSP_FIFO_INT_DISABLE) | SSCR0_reg(TIM, SSP_FIFO_INT_DISABLE) | SSCR0_reg(ECS, DIV_DISABLE) | SSCR0_reg(NCS, NETWORK_CLOCK_DISABLE) | SSCR0_reg(FRDC, SSCR0_SlotsPerFrm(settings->frame_rate_divider_ctrl)); return sscr0; }
/** * set_ssp_i2s_hw - configure the SSP driver according to the ps_settings * @drv_data : structure that contains all details about the SSP Driver * @ps_settings : structure that contains SSP Hardware settings * * it also store ps_settings the drv_data * * Output parameters * NA */ static void set_ssp_i2s_hw(struct intel_mid_i2s_hdl *drv_data, const struct intel_mid_i2s_settings *ps_settings) { u32 sscr0 = 0; u32 sscr1 = 0; u32 sstsa = 0; u32 ssrsa = 0; u32 sspsp = 0; u32 sssr = 0; /* Get the SSP Settings */ u16 l_ssp_clk_frm_mode = 0xFF; void __iomem *reg = drv_data->ioaddr; struct device *ddbg = &(drv_data->pdev->dev); dev_dbg(ddbg, "setup SSP I2S PCM1 configuration\n"); if ((ps_settings->sspsfrm_direction == SSPSFRM_MASTER_MODE) && (ps_settings->sspslclk_direction == SSPSCLK_MASTER_MODE)) { l_ssp_clk_frm_mode = SSP_IN_MASTER_MODE; } else if ((ps_settings->sspsfrm_direction == SSPSFRM_SLAVE_MODE) && (ps_settings->sspslclk_direction == SSPSCLK_SLAVE_MODE)) { l_ssp_clk_frm_mode = SSP_IN_SLAVE_MODE; } else { dev_err(ddbg, "Unsupported I2S PCM1 configuration\n"); goto leave; } dev_dbg(ddbg, "SSPSFRM_DIRECTION:%d:\n", ps_settings->sspsfrm_direction); dev_dbg(ddbg, "SSPSCLK_DIRECTION:%d:\n", ps_settings->sspslclk_direction); if (ps_settings->frame_format != PSP_FORMAT) { dev_err(ddbg, "UNSUPPORTED FRAME FORMAT:%d:\n", ps_settings->frame_format); goto leave; } if ((ps_settings->ssp_tx_dma != SSP_TX_DMA_ENABLE) || (ps_settings->ssp_rx_dma != SSP_RX_DMA_ENABLE)) { dev_err(ddbg, "ONLY DMA MODE IS SUPPORTED"); goto leave; } /*********** DMA Transfer Mode ***********/ dev_dbg(ddbg, "FORMAT :%d:\n", ps_settings->frame_format); sscr0 = calculate_sscr0_psp(ps_settings); dev_dbg(ddbg, " sscr0 :0x%08X\n", sscr0); sscr1 = calculate_sscr1_psp(ps_settings); dev_dbg(ddbg, " sscr1 :0x%08X\n", sscr1); if (ps_settings->mode == SSP_IN_NETWORK_MODE) { dev_dbg(ddbg, "MODE :%d:\n", ps_settings->mode); sscr0 |= SSCR0_reg(FRDC, SSCR0_SlotsPerFrm(ps_settings-> frame_rate_divider_control)); dev_dbg(ddbg, "sscr0 :0x%08X\n", sscr0); sspsp = calculate_sspsp_psp(ps_settings); dev_dbg(ddbg, "sspsp :0x%08X\n", sspsp); /* set the active TX time slot (bitmap) */ sstsa = SSTSA_reg(TTSA, ps_settings->ssp_active_tx_slots_map); /* set the active RX time slot (bitmap) */ ssrsa = SSRSA_reg(RTSA, ps_settings->ssp_active_rx_slots_map); if (l_ssp_clk_frm_mode == SSP_IN_MASTER_MODE) { switch (ps_settings->master_mode_clk_selection) { case SSP_ONCHIP_CLOCK: break; case SSP_NETWORK_CLOCK: sscr0 |= SSCR0_reg(NCS, 1); break; case SSP_EXTERNAL_CLOCK: sscr0 |= SSCR0_reg(ECS, 1); break; case SSP_ONCHIP_AUDIO_CLOCK: sscr0 |= SSCR0_reg(ACS, 1); break; default: dev_err(ddbg, "Master Mode clk selection UNKNOWN"); break; } sspsp |= SSPSP_reg(STRTDLY, ps_settings->ssp_psp_T1) |SSPSP_reg(DMYSTRT, ps_settings->ssp_psp_T2); } else { /* Set the Slave Clock Free Running Status */ sscr1 |= SSCR1_reg(SCFR, ps_settings->slave_clk_free_running_status); } } else { /* SSP_IN_NORMAL_MODE */ dev_err(ddbg, "UNSUPPORTED MODE"); goto leave; } /* Clear status */ sssr = (SSSR_BCE_MASK << SSSR_BCE_SHIFT) | (SSSR_TUR_MASK << SSSR_TUR_SHIFT) | (SSSR_TINT_MASK << SSSR_TINT_SHIFT) | (SSSR_PINT_MASK << SSSR_PINT_SHIFT) | (SSSR_ROR_MASK << SSSR_ROR_SHIFT); /* disable SSP */ clear_SSCR0_reg(reg, SSE); dev_dbg(ddbg, "WRITE SSCR0 DISABLE\n"); /* Clear status */ write_SSSR(sssr, reg); dev_dbg(ddbg, "WRITE SSSR: 0x%08X\n", sssr); write_SSCR0(sscr0, reg); dev_dbg(ddbg, "WRITE SSCR0\n"); /* first set CR1 without interrupt and service enables */ write_SSCR1(sscr1, reg); write_SSPSP(sspsp, reg); write_SSTSA(sstsa, reg); write_SSRSA(ssrsa, reg); /* set the time out for the reception */ write_SSTO(0, reg); ssp1_dump_registers(drv_data); leave: return; }