/** * intel_mid_i2s_open - reserve and start a SSP depending of it's usage * @usage : select which ssp i2s you need by giving usage (BT,MODEM...) * @ps_settings : hardware settings to configure the SSP module * * May sleep (driver_find_device) : no lock permitted when called. * * Output parameters * handle : handle of the selected SSP, or NULL if not found */ struct intel_mid_i2s_hdl *intel_mid_i2s_open(enum intel_mid_i2s_ssp_usage usage, const struct intel_mid_i2s_settings *ps_settings) { struct pci_dev *pdev; struct intel_mid_i2s_hdl *drv_data = NULL; struct device *found_device = NULL; pr_debug("%s : open called,searching for device with usage=%x !\n", DRIVER_NAME, usage); found_device = driver_find_device(&(intel_mid_i2s_driver.driver), NULL, &usage, check_device); if (!found_device) { pr_debug("%s : open can not found with usage=0x%02X\n", DRIVER_NAME, (int)usage); return NULL; } pdev = to_pci_dev(found_device); drv_data = pci_get_drvdata(pdev); drv_data->current_settings = *ps_settings; if (!drv_data) { dev_err(found_device, "no drv_data in open pdev=%p\n", pdev); put_device(found_device); return NULL; } mutex_lock(&drv_data->mutex); dev_dbg(found_device, "Open found pdevice=0x%p\n", pdev); /* pm_runtime */ pm_runtime_get_sync(&drv_data->pdev->dev); /* dmac1 is already set during probe */ if (i2s_dma_start(drv_data) != 0) { dev_err(found_device, "Can not start DMA\n"); goto open_error; } /* if we restart after stop without suspend, we start ssp faster */ set_ssp_i2s_hw(drv_data, ps_settings); drv_data->mask_sr = ((SSSR_BCE_MASK << SSSR_BCE_SHIFT) | (SSSR_EOC_MASK << SSSR_EOC_SHIFT) | (SSSR_ROR_MASK << SSSR_ROR_SHIFT) | (SSSR_TUR_MASK << SSSR_TUR_SHIFT) | (SSSR_TINT_MASK << SSSR_TINT_SHIFT) | (SSSR_PINT_MASK << SSSR_PINT_SHIFT)); if (test_bit(I2S_PORT_CLOSING, &drv_data->flags)) { dev_err(&drv_data->pdev->dev, "Opening a closing I2S!"); goto open_error; } /* there is no need to "wake up" as we can not close an opening i2s */ clear_bit(I2S_PORT_WRITE_BUSY, &drv_data->flags); clear_bit(I2S_PORT_READ_BUSY, &drv_data->flags); mutex_unlock(&drv_data->mutex); return drv_data; open_error: pm_runtime_put(&drv_data->pdev->dev); put_device(found_device); mutex_unlock(&drv_data->mutex); return NULL; }
/* * apl_i2s_init - Initialize I2s. * @bus: i2s config structure * * Initialize I2s. */ static int apl_i2s_init(AplI2s *bus) { if (enable_DSP_SSP(bus)) return -1; i2s_disable(bus->regs); set_ssp_i2s_hw(bus->regs, bus->shim, bus->settings, bus->bits_per_sample); return 0; }