bool mi2s_set_codec_input_path(uint8_t channels, uint8_t size)
{
	bool ret_val = MI2S_TRUE;
	struct mi2s_state *mi2s = &the_mi2s_state;

	mutex_lock(&the_mi2s_state.mutex_lock);
	/* Put device in reset */
	mi2s_reset(mi2s, CODEC_RX);

	mi2s_master(mi2s, CODEC_RX, 1);

	/* Enable clock crossing synchronization of WR DMA ACK */
	mi2s_set_input_clk_synch(mi2s, CODEC_RX);

	/* Set word type */
	if (size <= WT_MAX)
		mi2s_set_word_type(mi2s, CODEC_RX, size);
	else
		ret_val = MI2S_FALSE;

	mi2s_set_input_num_channels(mi2s, CODEC_RX, channels);

	/* Enable SD line */
	mi2s_set_sd(mi2s, CODEC_RX, MI2S_SD_0_EN_MAP);

	/* Release device from reset */
	mi2s_release(mi2s, CODEC_RX);

	mutex_unlock(&mi2s->mutex_lock);
	mb();
	return ret_val;
}
示例#2
0
bool mi2s_set_hdmi_input_path(uint8_t channels, uint8_t size, uint8_t sd_line)
{
	bool ret_val = MI2S_TRUE;
	struct mi2s_state *mi2s = &the_mi2s_state;

	mutex_lock(&mi2s->mutex_lock);
	/* Put device in reset */
	mi2s_reset(mi2s, HDMI);

	mi2s_master(mi2s, HDMI, 1);

	/* Set word type */
	if (size <= WT_MAX)
		mi2s_set_word_type(mi2s, HDMI, size);
	else
		ret_val = MI2S_FALSE;

	/* Enable clock crossing synchronization of WR DMA ACK */
	mi2s_set_input_clk_synch(mi2s, HDMI);

	/* Ensure channels parameter is valid (non-zero, less than max,
	 * and even or mono)
	 */
	if ((channels > 0) && (channels <= MAX_NUM_CHANNELS_IN) &&
		((channels == 1) || (channels % 2 == 0))) {
		mi2s_set_input_num_channels(mi2s, HDMI, channels);
	} else {
		ret_val = MI2S_FALSE;
	}

	/* Ensure sd_line parameter is valid (0-max) */
	if (sd_line < MAX_SD_LINES) {
		/* Enable single SD line for Rx */
		mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP << sd_line));
	} else {
		ret_val = MI2S_FALSE;
	}

	/* Release device from reset */
	mi2s_release(mi2s, HDMI);

	mutex_unlock(&mi2s->mutex_lock);
	return ret_val;
}
bool mi2s_set_hdmi_input_path(uint8_t channels, uint8_t size,
		uint8_t sd_line_mask)
{
	bool ret_val = MI2S_TRUE;
	struct mi2s_state *mi2s = &the_mi2s_state;
	u8 sd_line, num_of_sd_lines = 0;
	void __iomem *baddr;
	uint32_t val;

	pr_debug("%s: channels = %u size = %u sd_line_mask = 0x%x\n", __func__,
		channels, size, sd_line_mask);

	if ((channels != 1) && (channels != MAX_NUM_CHANNELS_IN)) {

		pr_err("%s: invalid number of channels. channels = %u\n",
				__func__, channels);
		return  MI2S_FALSE;
	}

	if (size > WT_MAX) {

		pr_err("%s: mi2s word size can not be greater than 32 bits\n",
				__func__);
		return MI2S_FALSE;
	}

	sd_line_mask &=  MI2S_SD_LINE_MASK;

	if (!sd_line_mask) {
		pr_err("%s: Did not set any data lines to use "
			" sd_line_mask =0x%x\n", __func__, sd_line_mask);
		return  MI2S_FALSE;
	}

	num_of_sd_lines = num_of_bits_set(sd_line_mask);

	if (num_of_sd_lines != 1) {
		pr_err("%s: for two channel input only one SD lines is"
			" needed. num_of_sd_lines = %u sd_line_mask = 0x%x\n",
			__func__, num_of_sd_lines, sd_line_mask);
		return MI2S_FALSE;
	}

	/*Second argument to find_first_bit should be maximum number of
	bits interested*/
	sd_line = find_first_bit((unsigned long *)&sd_line_mask,
			sizeof(sd_line_mask) * 8);
	pr_debug("sd_line = %d\n", sd_line);

	/* Ensure sd_line parameter is valid (0-max) */
	if (sd_line > MAX_SD_LINES) {
		pr_err("%s: Line number can not be greater than = %u\n",
			__func__, MAX_SD_LINES);
		return MI2S_FALSE;
	}

	mutex_lock(&mi2s->mutex_lock);
	/* Put device in reset */
	mi2s_reset(mi2s, HDMI);

	mi2s_master(mi2s, HDMI, 1);

	/* Set word type */
	mi2s_set_word_type(mi2s, HDMI, size);

	/* Enable clock crossing synchronization of WR DMA ACK */
	mi2s_set_input_clk_synch(mi2s, HDMI);

	/* Ensure channels parameter is valid (non-zero, less than max,
	 * and even or mono)
	 */
	mi2s_set_input_num_channels(mi2s, HDMI, channels);

	mi2s_set_input_sd_line(mi2s, HDMI, sd_line);

	mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP << sd_line));

	baddr = get_base_addr(mi2s, HDMI);

	val = readl(baddr + MI2S_MODE_OFFSET);
	pr_debug("%s(): MI2S_MODE = 0x%x\n", __func__, val);

	val = readl(baddr + MI2S_RX_MODE_OFFSET);
	pr_debug("%s(): MI2S_RX_MODE = 0x%x\n", __func__, val);

	/* Release device from reset */
	mi2s_release(mi2s, HDMI);

	mutex_unlock(&mi2s->mutex_lock);
	mb();
	return ret_val;
}