Exemplo n.º 1
0
int cx25840_loadfw(struct i2c_client *client)
{
	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
	const struct firmware *fw = NULL;
	u8 buffer[FWSEND];
	const u8 *ptr;
	const char *fwname = get_fw_name(client);
	int size, retval;
	int max_buf_size = FWSEND;
	u32 gpio_oe = 0, gpio_da = 0;

	if (is_cx2388x(state)) {
		/* Preserve the GPIO OE and output bits */
		gpio_oe = cx25840_read(client, 0x160);
		gpio_da = cx25840_read(client, 0x164);
	}

	/* cx231xx cannot accept more than 16 bytes at a time */
	if (is_cx231xx(state) && max_buf_size > 16)
		max_buf_size = 16;

	if (request_firmware(&fw, fwname, FWDEV(client)) != 0)
		return -EINVAL;

	start_fw_load(client);

	buffer[0] = 0x08;
	buffer[1] = 0x02;

	size = fw->size;
	ptr = fw->data;
	while (size > 0) {
		int len = min(max_buf_size - 2, size);

		memcpy(buffer + 2, ptr, len);

		retval = fw_write(client, buffer, len + 2);

		if (retval < 0) {
			release_firmware(fw);
			return retval;
		}

		size -= len;
		ptr += len;
	}

	end_fw_load(client);

	size = fw->size;
	release_firmware(fw);

	if (is_cx2388x(state)) {
		/* Restore GPIO configuration after f/w load */
		cx25840_write(client, 0x160, gpio_oe);
		cx25840_write(client, 0x164, gpio_da);
	}

	return check_fw_load(client, size);
}
Exemplo n.º 2
0
static const char *get_fw_name(struct i2c_client *client)
{
	struct cx25840_state *state = to_state(i2c_get_clientdata(client));

	if (firmware[0])
		return firmware;
	if (is_cx2388x(state))
		return CX2388x_FIRMWARE;
	if (is_cx231xx(state))
		return CX231xx_FIRMWARE;
	return CX25840_FIRMWARE;
}
static const char *get_fw_name(struct i2c_client *client)
{
	struct cx25840_state *state = to_state(i2c_get_clientdata(client));

	if (firmware[0])
		return firmware;
	if (is_cx2388x(state))
		return "v4l-cx23885-avcore-01.fw";
	if (is_cx231xx(state))
		return "v4l-cx231xx-avcore-01.fw";
	return "v4l-cx25840.fw";
}
Exemplo n.º 4
0
static int set_audclk_freq(struct i2c_client *client, u32 freq)
{
	struct cx25840_state *state = to_state(i2c_get_clientdata(client));

	if (freq != 32000 && freq != 44100 && freq != 48000)
		return -EINVAL;

	if (is_cx231xx(state))
		return cx231xx_set_audclk_freq(client, freq);

	if (is_cx2388x(state))
		return cx23885_set_audclk_freq(client, freq);

	if (is_cx2583x(state))
		return cx25836_set_audclk_freq(client, freq);

	return cx25840_set_audclk_freq(client, freq);
}
Exemplo n.º 5
0
void cx25840_audio_set_path(struct i2c_client *client)
{
	struct cx25840_state *state = to_state(i2c_get_clientdata(client));

	if (!is_cx2583x(state)) {
		/* assert soft reset */
		cx25840_and_or(client, 0x810, ~0x1, 0x01);

		/* stop microcontroller */
		cx25840_and_or(client, 0x803, ~0x10, 0);

		/* Mute everything to prevent the PFFT! */
		cx25840_write(client, 0x8d3, 0x1f);

		if (state->aud_input == CX25840_AUDIO_SERIAL) {
			/* Set Path1 to Serial Audio Input */
			cx25840_write4(client, 0x8d0, 0x01011012);

			/* The microcontroller should not be started for the
			 * non-tuner inputs: autodetection is specific for
			 * TV audio. */
		} else {
			/* Set Path1 to Analog Demod Main Channel */
			cx25840_write4(client, 0x8d0, 0x1f063870);
		}
	}

	set_audclk_freq(client, state->audclk_freq);

	if (!is_cx2583x(state)) {
		if (state->aud_input != CX25840_AUDIO_SERIAL) {
			/* When the microcontroller detects the
			 * audio format, it will unmute the lines */
			cx25840_and_or(client, 0x803, ~0x10, 0x10);
		}

		/* deassert soft reset */
		cx25840_and_or(client, 0x810, ~0x1, 0x00);

		/* Ensure the controller is running when we exit */
		if (is_cx2388x(state) || is_cx231xx(state))
			cx25840_and_or(client, 0x803, ~0x10, 0x10);
	}
}