mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
V4L/DVB (3427): audmode and rxsubchans fixes (VIDIOC_G/S_TUNER)
- Audmode and rxsubchans fixes in msp3400, tuner, tvaudio and cx25840. - msp3400 cleanups Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
9aeb4b051b
commit
8a4b275f9c
@@ -753,6 +753,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
|
||||
memset(input, 0, sizeof(*input));
|
||||
input->index = state->aud_input;
|
||||
input->capability = V4L2_AUDCAP_STEREO;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -763,7 +764,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
case VIDIOC_G_TUNER:
|
||||
{
|
||||
u8 mode = cx25840_read(client, 0x804);
|
||||
u8 pref = cx25840_read(client, 0x809) & 0xf;
|
||||
u8 vpres = cx25840_read(client, 0x80a) & 0x10;
|
||||
int val = 0;
|
||||
|
||||
@@ -783,44 +783,49 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
val |= V4L2_TUNER_SUB_MONO;
|
||||
|
||||
if (mode == 2 || mode == 4)
|
||||
val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
|
||||
if (mode & 0x10)
|
||||
val |= V4L2_TUNER_SUB_SAP;
|
||||
|
||||
vt->rxsubchans = val;
|
||||
|
||||
switch (pref) {
|
||||
case 0:
|
||||
vt->audmode = V4L2_TUNER_MODE_MONO;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
vt->audmode = V4L2_TUNER_MODE_LANG2;
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
vt->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
}
|
||||
vt->audmode = state->audmode;
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_S_TUNER:
|
||||
if (state->radio)
|
||||
break;
|
||||
|
||||
switch (vt->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
/* Force PREF_MODE to MONO */
|
||||
/* mono -> mono
|
||||
stereo -> mono
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x00);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
/* Force PREF_MODE to STEREO */
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x04);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1/lang2 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x07);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
/* Force PREF_MODE to LANG2 */
|
||||
/* mono -> mono
|
||||
stereo ->stereo
|
||||
bilingual -> lang2 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x01);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
state->audmode = vt->audmode;
|
||||
break;
|
||||
|
||||
case VIDIOC_G_FMT:
|
||||
@@ -901,6 +906,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
|
||||
state->aud_input = CX25840_AUDIO8;
|
||||
state->audclk_freq = 48000;
|
||||
state->pvr150_workaround = 0;
|
||||
state->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
|
||||
cx25840_initialize(client, 1);
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ struct cx25840_state {
|
||||
enum cx25840_video_input vid_input;
|
||||
enum cx25840_audio_input aud_input;
|
||||
u32 audclk_freq;
|
||||
int audmode;
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
@@ -411,9 +411,9 @@ static int msp_mode_v4l2_to_v4l1(int rxsubchans)
|
||||
if (rxsubchans & V4L2_TUNER_SUB_STEREO)
|
||||
mode |= VIDEO_SOUND_STEREO;
|
||||
if (rxsubchans & V4L2_TUNER_SUB_LANG2)
|
||||
mode |= VIDEO_SOUND_LANG2;
|
||||
mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO;
|
||||
if (rxsubchans & V4L2_TUNER_SUB_LANG1)
|
||||
mode |= VIDEO_SOUND_LANG1;
|
||||
mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO;
|
||||
if (mode == 0)
|
||||
mode |= VIDEO_SOUND_MONO;
|
||||
return mode;
|
||||
@@ -430,21 +430,6 @@ static int msp_mode_v4l1_to_v4l2(int mode)
|
||||
return V4L2_TUNER_MODE_MONO;
|
||||
}
|
||||
|
||||
static void msp_any_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
autodetect_stereo(client);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_detect_stereo(client);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct v4l2_queryctrl msp_qctrl_std[] = {
|
||||
{
|
||||
.id = V4L2_CID_AUDIO_VOLUME,
|
||||
@@ -506,22 +491,6 @@ static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
|
||||
};
|
||||
|
||||
|
||||
static void msp_any_set_audmode(struct i2c_client *client, int audmode)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
state->watch_stereo = 0;
|
||||
msp3400c_setstereo(client, audmode);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_set_audmode(client, audmode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
@@ -656,7 +625,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
if (state->opmode != OPMODE_AUTOSELECT)
|
||||
msp3400c_setstereo(client, state->audmode);
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
msp_wake_thread(client);
|
||||
break;
|
||||
@@ -670,8 +639,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
/* set msp3400 to FM radio mode */
|
||||
msp3400c_setmode(client, MSP_MODE_FM_RADIO);
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(10.7),
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(10.7),
|
||||
MSP_CARRIER(10.7));
|
||||
msp_set_audio(client);
|
||||
break;
|
||||
@@ -705,7 +674,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
if (state->radio)
|
||||
break;
|
||||
if (state->opmode == OPMODE_AUTOSELECT)
|
||||
msp_any_detect_stereo(client);
|
||||
msp_detect_stereo(client);
|
||||
va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
|
||||
break;
|
||||
}
|
||||
@@ -721,8 +690,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
state->treble = va->treble;
|
||||
msp_set_audio(client);
|
||||
|
||||
if (va->mode != 0 && state->radio == 0)
|
||||
msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode));
|
||||
if (va->mode != 0 && state->radio == 0) {
|
||||
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -864,7 +834,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
}
|
||||
msp_any_set_audmode(client, state->audmode);
|
||||
msp_set_audmode(client);
|
||||
msp_wake_thread(client);
|
||||
break;
|
||||
}
|
||||
@@ -876,7 +846,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
if (state->radio)
|
||||
break;
|
||||
if (state->opmode == OPMODE_AUTOSELECT)
|
||||
msp_any_detect_stereo(client);
|
||||
msp_detect_stereo(client);
|
||||
vt->audmode = state->audmode;
|
||||
vt->rxsubchans = state->rxsubchans;
|
||||
vt->capability = V4L2_TUNER_CAP_STEREO |
|
||||
@@ -890,8 +860,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
|
||||
if (state->radio) /* TODO: add mono/stereo support for radio */
|
||||
break;
|
||||
state->audmode = vt->audmode;
|
||||
/* only set audmode */
|
||||
msp_any_set_audmode(client, vt->audmode);
|
||||
msp_set_audmode(client);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -981,7 +952,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
const char *p;
|
||||
|
||||
if (state->opmode == OPMODE_AUTOSELECT)
|
||||
msp_any_detect_stereo(client);
|
||||
msp_detect_stereo(client);
|
||||
v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
|
||||
client->name, state->rev1, state->rev2);
|
||||
v4l_info(client, "Audio: volume %d%s\n",
|
||||
@@ -1082,7 +1053,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
state->v4l2_std = V4L2_STD_NTSC;
|
||||
state->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
state->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
state->volume = 58880; /* 0db gain */
|
||||
state->balance = 32768; /* 0db gain */
|
||||
state->bass = 32768;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -104,14 +104,13 @@ int msp_sleep(struct msp_state *state, int timeout);
|
||||
|
||||
/* msp3400-kthreads.c */
|
||||
const char *msp_standard_std_name(int std);
|
||||
void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2);
|
||||
void msp3400c_setmode(struct i2c_client *client, int type);
|
||||
void msp3400c_setstereo(struct i2c_client *client, int mode);
|
||||
int autodetect_stereo(struct i2c_client *client);
|
||||
void msp_set_source(struct i2c_client *client, u16 src);
|
||||
void msp_set_audmode(struct i2c_client *client);
|
||||
void msp_detect_stereo(struct i2c_client *client);
|
||||
int msp3400c_thread(void *data);
|
||||
int msp3410d_thread(void *data);
|
||||
int msp34xxg_thread(void *data);
|
||||
void msp34xxg_detect_stereo(struct i2c_client *client);
|
||||
void msp34xxg_set_audmode(struct i2c_client *client, int audmode);
|
||||
void msp3400c_set_mode(struct i2c_client *client, int mode);
|
||||
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
|
||||
|
||||
#endif /* MSP3400_H */
|
||||
|
||||
@@ -398,15 +398,16 @@ static void tuner_status(struct i2c_client *client)
|
||||
tuner_info("Tuner mode: %s\n", p);
|
||||
tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
|
||||
tuner_info("Standard: 0x%08llx\n", t->std);
|
||||
if (t->mode == V4L2_TUNER_RADIO) {
|
||||
if (t->has_signal) {
|
||||
tuner_info("Signal strength: %d\n", t->has_signal(client));
|
||||
}
|
||||
if (t->is_stereo) {
|
||||
tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
|
||||
}
|
||||
if (t->mode != V4L2_TUNER_RADIO)
|
||||
return;
|
||||
if (t->has_signal) {
|
||||
tuner_info("Signal strength: %d\n", t->has_signal(client));
|
||||
}
|
||||
if (t->is_stereo) {
|
||||
tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* static var Used only in tuner_attach and tuner_probe */
|
||||
@@ -737,33 +738,29 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
return 0;
|
||||
switch_v4l2();
|
||||
|
||||
if (V4L2_TUNER_RADIO == t->mode) {
|
||||
|
||||
if (t->has_signal)
|
||||
tuner->signal = t->has_signal(client);
|
||||
|
||||
if (t->is_stereo) {
|
||||
if (t->is_stereo(client)) {
|
||||
tuner->rxsubchans =
|
||||
V4L2_TUNER_SUB_STEREO |
|
||||
V4L2_TUNER_SUB_MONO;
|
||||
} else {
|
||||
tuner->rxsubchans =
|
||||
V4L2_TUNER_SUB_MONO;
|
||||
}
|
||||
}
|
||||
|
||||
tuner->capability |=
|
||||
V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
|
||||
tuner->audmode = t->audmode;
|
||||
|
||||
tuner->rangelow = radio_range[0] * 16000;
|
||||
tuner->rangehigh = radio_range[1] * 16000;
|
||||
} else {
|
||||
tuner->type = t->mode;
|
||||
if (t->mode != V4L2_TUNER_RADIO) {
|
||||
tuner->rangelow = tv_range[0] * 16;
|
||||
tuner->rangehigh = tv_range[1] * 16;
|
||||
break;
|
||||
}
|
||||
|
||||
/* radio mode */
|
||||
if (t->has_signal)
|
||||
tuner->signal = t->has_signal(client);
|
||||
|
||||
tuner->rxsubchans =
|
||||
V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
|
||||
if (t->is_stereo) {
|
||||
tuner->rxsubchans = t->is_stereo(client) ?
|
||||
V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
|
||||
}
|
||||
|
||||
tuner->capability |=
|
||||
V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
tuner->audmode = t->audmode;
|
||||
tuner->rangelow = radio_range[0] * 16000;
|
||||
tuner->rangehigh = radio_range[1] * 16000;
|
||||
break;
|
||||
}
|
||||
case VIDIOC_S_TUNER:
|
||||
@@ -775,10 +772,11 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
|
||||
switch_v4l2();
|
||||
|
||||
if (V4L2_TUNER_RADIO == t->mode) {
|
||||
t->audmode = tuner->audmode;
|
||||
set_radio_freq(client, t->radio_freq);
|
||||
}
|
||||
/* do nothing unless we're a radio tuner */
|
||||
if (t->mode != V4L2_TUNER_RADIO)
|
||||
break;
|
||||
t->audmode = tuner->audmode;
|
||||
set_radio_freq(client, t->radio_freq);
|
||||
break;
|
||||
}
|
||||
case VIDIOC_LOG_STATUS:
|
||||
|
||||
@@ -130,6 +130,7 @@ struct CHIPSTATE {
|
||||
struct timer_list wt;
|
||||
int done;
|
||||
int watch_stereo;
|
||||
int audmode;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@@ -1514,6 +1515,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
chip->type = desc-chiplist;
|
||||
chip->shadow.count = desc->registers+1;
|
||||
chip->prevmode = -1;
|
||||
chip->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
/* register */
|
||||
i2c_attach_client(&chip->c);
|
||||
|
||||
@@ -1671,6 +1673,8 @@ static int chip_command(struct i2c_client *client,
|
||||
struct v4l2_tuner *vt = arg;
|
||||
int mode = 0;
|
||||
|
||||
if (chip->radio)
|
||||
break;
|
||||
switch (vt->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
mode = VIDEO_SOUND_MONO;
|
||||
@@ -1685,8 +1689,9 @@ static int chip_command(struct i2c_client *client,
|
||||
mode = VIDEO_SOUND_LANG2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
chip->audmode = vt->audmode;
|
||||
|
||||
if (desc->setmode && mode) {
|
||||
chip->watch_stereo = 0;
|
||||
@@ -1704,7 +1709,7 @@ static int chip_command(struct i2c_client *client,
|
||||
|
||||
if (chip->radio)
|
||||
break;
|
||||
vt->audmode = 0;
|
||||
vt->audmode = chip->audmode;
|
||||
vt->rxsubchans = 0;
|
||||
vt->capability = V4L2_TUNER_CAP_STEREO |
|
||||
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
|
||||
@@ -1716,19 +1721,12 @@ static int chip_command(struct i2c_client *client,
|
||||
vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
|
||||
if (mode & VIDEO_SOUND_STEREO)
|
||||
vt->rxsubchans |= V4L2_TUNER_SUB_STEREO;
|
||||
/* Note: for SAP it should be mono/lang2 or stereo/lang2.
|
||||
When this module is converted fully to v4l2, then this
|
||||
should change for those chips that can detect SAP. */
|
||||
if (mode & VIDEO_SOUND_LANG1)
|
||||
vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 |
|
||||
V4L2_TUNER_SUB_LANG2;
|
||||
|
||||
mode = chip->mode;
|
||||
if (mode & VIDEO_SOUND_MONO)
|
||||
vt->audmode = V4L2_TUNER_MODE_MONO;
|
||||
if (mode & VIDEO_SOUND_STEREO)
|
||||
vt->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
if (mode & VIDEO_SOUND_LANG1)
|
||||
vt->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
if (mode & VIDEO_SOUND_LANG2)
|
||||
vt->audmode = V4L2_TUNER_MODE_LANG2;
|
||||
vt->rxsubchans = V4L2_TUNER_SUB_LANG1 |
|
||||
V4L2_TUNER_SUB_LANG2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user