diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-01-09 12:25:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2006-01-09 12:25:42 -0500 |
commit | a8bbf12ad8a8ad532cea0b67f0127ad90d336b04 (patch) | |
tree | bd8d9fb0888a7fe28b4795d7567c01ccf72b3c38 /drivers/media/video/cx25840/cx25840-audio.c | |
parent | 3578d3dd0b1e468a44a76a83efe90476a854625d (diff) |
V4L/DVB (3249): Generalized cx25840 video/audio input handling
- Added VIDIOC_S_AUDIO to set the audio inputs separately.
- Removed AUDC_SET_INPUT.
- Made the video inputs much more general.
- Removed cardtype CID and replaced with a CID to enable
the PVR150 workaround. The cardtype is no longer necessary
with the general video input change.
- Update VIDIOC_LOG_STATUS output to show the video and
audio inputs separately.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-audio.c')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-audio.c | 51 |
1 files changed, 15 insertions, 36 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 6c44bd9c1704..fe6bc411d71f 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -37,8 +37,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
37 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | 37 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ |
38 | cx25840_write(client, 0x127, 0x50); | 38 | cx25840_write(client, 0x127, 0x50); |
39 | 39 | ||
40 | switch (state->audio_input) { | 40 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
41 | case AUDIO_TUNER: | ||
42 | switch (freq) { | 41 | switch (freq) { |
43 | case 32000: | 42 | case 32000: |
44 | /* VID_PLL and AUX_PLL */ | 43 | /* VID_PLL and AUX_PLL */ |
@@ -79,12 +78,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
79 | cx25840_write4(client, 0x90c, 0xaa4f0108); | 78 | cx25840_write4(client, 0x90c, 0xaa4f0108); |
80 | break; | 79 | break; |
81 | } | 80 | } |
82 | break; | 81 | } else { |
83 | |||
84 | case AUDIO_EXTERN_1: | ||
85 | case AUDIO_EXTERN_2: | ||
86 | case AUDIO_INTERN: | ||
87 | case AUDIO_RADIO: | ||
88 | switch (freq) { | 82 | switch (freq) { |
89 | case 32000: | 83 | case 32000: |
90 | /* VID_PLL and AUX_PLL */ | 84 | /* VID_PLL and AUX_PLL */ |
@@ -137,7 +131,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
137 | cx25840_write4(client, 0x90c, 0x55550108); | 131 | cx25840_write4(client, 0x90c, 0x55550108); |
138 | break; | 132 | break; |
139 | } | 133 | } |
140 | break; | ||
141 | } | 134 | } |
142 | 135 | ||
143 | /* deassert soft reset */ | 136 | /* deassert soft reset */ |
@@ -148,48 +141,33 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
148 | return 0; | 141 | return 0; |
149 | } | 142 | } |
150 | 143 | ||
151 | static int set_input(struct i2c_client *client, int audio_input) | 144 | void cx25840_audio_set_path(struct i2c_client *client) |
152 | { | 145 | { |
153 | struct cx25840_state *state = i2c_get_clientdata(client); | 146 | struct cx25840_state *state = i2c_get_clientdata(client); |
154 | 147 | ||
155 | cx25840_dbg("set audio input (%d)\n", audio_input); | ||
156 | |||
157 | /* stop microcontroller */ | 148 | /* stop microcontroller */ |
158 | cx25840_and_or(client, 0x803, ~0x10, 0); | 149 | cx25840_and_or(client, 0x803, ~0x10, 0); |
159 | 150 | ||
160 | /* Mute everything to prevent the PFFT! */ | 151 | /* Mute everything to prevent the PFFT! */ |
161 | cx25840_write(client, 0x8d3, 0x1f); | 152 | cx25840_write(client, 0x8d3, 0x1f); |
162 | 153 | ||
163 | switch (audio_input) { | 154 | if (state->aud_input == CX25840_AUDIO_SERIAL) { |
164 | case AUDIO_TUNER: | ||
165 | /* Set Path1 to Analog Demod Main Channel */ | ||
166 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
167 | |||
168 | /* When the microcontroller detects the | ||
169 | * audio format, it will unmute the lines */ | ||
170 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
171 | break; | ||
172 | |||
173 | case AUDIO_EXTERN_1: | ||
174 | case AUDIO_EXTERN_2: | ||
175 | case AUDIO_INTERN: | ||
176 | case AUDIO_RADIO: | ||
177 | /* Set Path1 to Serial Audio Input */ | 155 | /* Set Path1 to Serial Audio Input */ |
178 | cx25840_write4(client, 0x8d0, 0x12100101); | 156 | cx25840_write4(client, 0x8d0, 0x12100101); |
179 | 157 | ||
180 | /* The microcontroller should not be started for the | 158 | /* The microcontroller should not be started for the |
181 | * non-tuner inputs: autodetection is specific for | 159 | * non-tuner inputs: autodetection is specific for |
182 | * TV audio. */ | 160 | * TV audio. */ |
183 | break; | 161 | } else { |
162 | /* Set Path1 to Analog Demod Main Channel */ | ||
163 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
184 | 164 | ||
185 | default: | 165 | /* When the microcontroller detects the |
186 | cx25840_dbg("Invalid audio input selection %d\n", audio_input); | 166 | * audio format, it will unmute the lines */ |
187 | return -EINVAL; | 167 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
188 | } | 168 | } |
189 | 169 | ||
190 | state->audio_input = audio_input; | 170 | set_audclk_freq(client, state->audclk_freq); |
191 | |||
192 | return set_audclk_freq(client, state->audclk_freq); | ||
193 | } | 171 | } |
194 | 172 | ||
195 | inline static int get_volume(struct i2c_client *client) | 173 | inline static int get_volume(struct i2c_client *client) |
@@ -292,7 +270,7 @@ inline static void set_mute(struct i2c_client *client, int mute) | |||
292 | { | 270 | { |
293 | struct cx25840_state *state = i2c_get_clientdata(client); | 271 | struct cx25840_state *state = i2c_get_clientdata(client); |
294 | 272 | ||
295 | if (state->audio_input == AUDIO_TUNER) { | 273 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
296 | /* Must turn off microcontroller in order to mute sound. | 274 | /* Must turn off microcontroller in order to mute sound. |
297 | * Not sure if this is the best method, but it does work. | 275 | * Not sure if this is the best method, but it does work. |
298 | * If the microcontroller is running, then it will undo any | 276 | * If the microcontroller is running, then it will undo any |
@@ -316,10 +294,9 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
316 | struct v4l2_control *ctrl = arg; | 294 | struct v4l2_control *ctrl = arg; |
317 | 295 | ||
318 | switch (cmd) { | 296 | switch (cmd) { |
319 | case AUDC_SET_INPUT: | ||
320 | return set_input(client, *(int *)arg); | ||
321 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 297 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
322 | return set_audclk_freq(client, *(u32 *)arg); | 298 | return set_audclk_freq(client, *(u32 *)arg); |
299 | |||
323 | case VIDIOC_G_CTRL: | 300 | case VIDIOC_G_CTRL: |
324 | switch (ctrl->id) { | 301 | switch (ctrl->id) { |
325 | case V4L2_CID_AUDIO_VOLUME: | 302 | case V4L2_CID_AUDIO_VOLUME: |
@@ -341,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
341 | return -EINVAL; | 318 | return -EINVAL; |
342 | } | 319 | } |
343 | break; | 320 | break; |
321 | |||
344 | case VIDIOC_S_CTRL: | 322 | case VIDIOC_S_CTRL: |
345 | switch (ctrl->id) { | 323 | switch (ctrl->id) { |
346 | case V4L2_CID_AUDIO_VOLUME: | 324 | case V4L2_CID_AUDIO_VOLUME: |
@@ -362,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
362 | return -EINVAL; | 340 | return -EINVAL; |
363 | } | 341 | } |
364 | break; | 342 | break; |
343 | |||
365 | default: | 344 | default: |
366 | return -EINVAL; | 345 | return -EINVAL; |
367 | } | 346 | } |