V4L/DVB (6051): cx25840: make proper use of SOFT_RESET
Whenever the 0x80b register is used the microcontroller should be reset. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
e17a06bada
commit
8267761881
2 changed files with 12 additions and 17 deletions
|
@ -157,13 +157,12 @@ void cx25840_audio_set_path(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct cx25840_state *state = i2c_get_clientdata(client);
|
struct cx25840_state *state = i2c_get_clientdata(client);
|
||||||
|
|
||||||
|
/* assert soft reset */
|
||||||
|
cx25840_and_or(client, 0x810, ~0x1, 0x01);
|
||||||
|
|
||||||
/* stop microcontroller */
|
/* stop microcontroller */
|
||||||
cx25840_and_or(client, 0x803, ~0x10, 0);
|
cx25840_and_or(client, 0x803, ~0x10, 0);
|
||||||
|
|
||||||
/* assert soft reset */
|
|
||||||
if (!state->is_cx25836)
|
|
||||||
cx25840_and_or(client, 0x810, ~0x1, 0x01);
|
|
||||||
|
|
||||||
/* Mute everything to prevent the PFFT! */
|
/* Mute everything to prevent the PFFT! */
|
||||||
cx25840_write(client, 0x8d3, 0x1f);
|
cx25840_write(client, 0x8d3, 0x1f);
|
||||||
|
|
||||||
|
@ -181,15 +180,14 @@ void cx25840_audio_set_path(struct i2c_client *client)
|
||||||
|
|
||||||
set_audclk_freq(client, state->audclk_freq);
|
set_audclk_freq(client, state->audclk_freq);
|
||||||
|
|
||||||
/* deassert soft reset */
|
|
||||||
if (!state->is_cx25836)
|
|
||||||
cx25840_and_or(client, 0x810, ~0x1, 0x00);
|
|
||||||
|
|
||||||
if (state->aud_input != CX25840_AUDIO_SERIAL) {
|
if (state->aud_input != CX25840_AUDIO_SERIAL) {
|
||||||
/* When the microcontroller detects the
|
/* When the microcontroller detects the
|
||||||
* audio format, it will unmute the lines */
|
* audio format, it will unmute the lines */
|
||||||
cx25840_and_or(client, 0x803, ~0x10, 0x10);
|
cx25840_and_or(client, 0x803, ~0x10, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* deassert soft reset */
|
||||||
|
cx25840_and_or(client, 0x810, ~0x1, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_volume(struct i2c_client *client)
|
static int get_volume(struct i2c_client *client)
|
||||||
|
@ -330,18 +328,18 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
|
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
|
||||||
|
if (!state->is_cx25836)
|
||||||
|
cx25840_and_or(client, 0x810, ~0x1, 1);
|
||||||
if (state->aud_input != CX25840_AUDIO_SERIAL) {
|
if (state->aud_input != CX25840_AUDIO_SERIAL) {
|
||||||
cx25840_and_or(client, 0x803, ~0x10, 0);
|
cx25840_and_or(client, 0x803, ~0x10, 0);
|
||||||
cx25840_write(client, 0x8d3, 0x1f);
|
cx25840_write(client, 0x8d3, 0x1f);
|
||||||
}
|
}
|
||||||
if (!state->is_cx25836)
|
|
||||||
cx25840_and_or(client, 0x810, ~0x1, 1);
|
|
||||||
retval = set_audclk_freq(client, *(u32 *)arg);
|
retval = set_audclk_freq(client, *(u32 *)arg);
|
||||||
if (!state->is_cx25836)
|
|
||||||
cx25840_and_or(client, 0x810, ~0x1, 0);
|
|
||||||
if (state->aud_input != CX25840_AUDIO_SERIAL) {
|
if (state->aud_input != CX25840_AUDIO_SERIAL) {
|
||||||
cx25840_and_or(client, 0x803, ~0x10, 0x10);
|
cx25840_and_or(client, 0x803, ~0x10, 0x10);
|
||||||
}
|
}
|
||||||
|
if (!state->is_cx25836)
|
||||||
|
cx25840_and_or(client, 0x810, ~0x1, 0);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
case VIDIOC_G_CTRL:
|
case VIDIOC_G_CTRL:
|
||||||
|
|
|
@ -250,6 +250,7 @@ static void input_change(struct i2c_client *client)
|
||||||
}
|
}
|
||||||
cx25840_and_or(client, 0x401, ~0x60, 0);
|
cx25840_and_or(client, 0x401, ~0x60, 0);
|
||||||
cx25840_and_or(client, 0x401, ~0x60, 0x60);
|
cx25840_and_or(client, 0x401, ~0x60, 0x60);
|
||||||
|
cx25840_and_or(client, 0x810, ~0x01, 1);
|
||||||
|
|
||||||
if (state->radio) {
|
if (state->radio) {
|
||||||
cx25840_write(client, 0x808, 0xf9);
|
cx25840_write(client, 0x808, 0xf9);
|
||||||
|
@ -284,11 +285,7 @@ static void input_change(struct i2c_client *client)
|
||||||
cx25840_write(client, 0x80b, 0x10);
|
cx25840_write(client, 0x80b, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cx25840_read(client, 0x803) & 0x10) {
|
cx25840_and_or(client, 0x810, ~0x01, 0);
|
||||||
/* restart audio decoder microcontroller */
|
|
||||||
cx25840_and_or(client, 0x803, ~0x10, 0x00);
|
|
||||||
cx25840_and_or(client, 0x803, ~0x10, 0x10);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
|
static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
|
||||||
|
|
Loading…
Reference in a new issue