Esempio n. 1
0
/*
 * lpss_ssp_setup - perform LPSS SSP specific setup
 * @drv_data: pointer to the driver private data
 *
 * Perform LPSS SSP specific setup. This function must be called first if
 * one is going to use LPSS SSP private registers.
 */
static void lpss_ssp_setup(struct driver_data *drv_data)
{
	unsigned offset = 0x400;
	u32 value, orig;

	if (!is_lpss_ssp(drv_data))
		return;

	/*
	 * Perform auto-detection of the LPSS SSP private registers. They
	 * can be either at 1k or 2k offset from the base address.
	 */
	orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);

	/* Test SPI_CS_CONTROL_SW_MODE bit enabling */
	value = orig | SPI_CS_CONTROL_SW_MODE;
	writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
	value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
	if (value != (orig | SPI_CS_CONTROL_SW_MODE)) {
		offset = 0x800;
		goto detection_done;
	}

	orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);

	/* Test SPI_CS_CONTROL_SW_MODE bit disabling */
	value = orig & ~SPI_CS_CONTROL_SW_MODE;
	writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
	value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
	if (value != (orig & ~SPI_CS_CONTROL_SW_MODE)) {
		offset = 0x800;
		goto detection_done;
	}

detection_done:
	/* Now set the LPSS base */
	drv_data->lpss_base = drv_data->ioaddr + offset;

	/* Enable software chip select control */
	value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH;
	__lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);

	/* Enable multiblock DMA transfers */
	if (drv_data->master_info->enable_dma) {
		__lpss_ssp_write_priv(drv_data, SSP_REG, 1);

		value = __lpss_ssp_read_priv(drv_data, GENERAL_REG);
		value |= GENERAL_REG_RXTO_HOLDOFF_DISABLE;
		__lpss_ssp_write_priv(drv_data, GENERAL_REG, value);
	}
}
Esempio n. 2
0
static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
{
	u32 value;

	value = __lpss_ssp_read_priv(drv_data, SPI_CS_CONTROL);
	if (enable)
		value &= ~SPI_CS_CONTROL_CS_HIGH;
	else
		value |= SPI_CS_CONTROL_CS_HIGH;
	__lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);
}
static void lpss_ssp_restore(struct driver_data *drv_data)
{
	u32 update_bit, param;
	u32 m = 1, n = 1;
	u32 value;

	if (!is_lpss_ssp(drv_data))
		return;

	/* Reset LPSS SSP Controller */
	__lpss_ssp_write_priv(drv_data, SSP_RESETS, 0x0);
	usleep_range(10, 100);
	__lpss_ssp_write_priv(drv_data, SSP_RESETS, 0x3);
	usleep_range(10, 100);

	/* Setting the clock divisor */
	update_bit = 1 << 31;
	param = (m << 1) | (n << 16) | 0x1;
	__lpss_ssp_write_priv(drv_data, PRV_CLK_PARAMS, param);
	__lpss_ssp_write_priv(drv_data, PRV_CLK_PARAMS, param | update_bit);
	drv_data->max_clk_rate = 100000000;
	dev_dbg(&drv_data->pdev->dev, "ssp_clk=%dMHz\n", (100*m/n));

	/* Enable software chip select control */
	value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH;
	__lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);

	/* Enable multiblock DMA transfers */
	if (drv_data->master_info->enable_dma)
		__lpss_ssp_write_priv(drv_data, SSP_REG, 1);
}
static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
{
	struct chip_data *chip = drv_data->cur_chip;
	u32 value;

	if (!is_lpss_ssp(drv_data))
		return;

	value = __lpss_ssp_read_priv(drv_data, SPI_CS_CONTROL);
	if (enable)
		value &= ~SPI_CS_CONTROL_CS_HIGH;
	else
		value |= SPI_CS_CONTROL_CS_HIGH;

	if (chip->chip_select)
		value |= SPI_CS_CONTROL_CS_SEL;
	else
		value &= ~SPI_CS_CONTROL_CS_SEL;

	__lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);
}
Esempio n. 5
0
/*
 * lpss_ssp_setup - perform LPSS SSP specific setup
 * @drv_data: pointer to the driver private data
 *
 * Perform LPSS SSP specific setup. This function must be called first if
 * one is going to use LPSS SSP private registers.
 */
static void lpss_ssp_setup(struct driver_data *drv_data)
{
	unsigned offset = 0x400;
	u32 value, orig;

	if (!is_lpss_ssp(drv_data))
		return;

	/*
	 * Perform auto-detection of the LPSS SSP private registers. They
	 * can be either at 1k or 2k offset from the base address.
	 */
	orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);

	value = orig | SPI_CS_CONTROL_SW_MODE;
	writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
	value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
	if (value != (orig | SPI_CS_CONTROL_SW_MODE)) {
		offset = 0x800;
		goto detection_done;
	}

	value &= ~SPI_CS_CONTROL_SW_MODE;
	writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
	value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
	if (value != orig) {
		offset = 0x800;
		goto detection_done;
	}

detection_done:
	/* Now set the LPSS base */
	drv_data->lpss_base = drv_data->ioaddr + offset;

	/* Enable software chip select control */
	value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH;
	__lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);
}