diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-audio.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-audio.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c index 7a8ad5963de8..35268923911c 100644 --- a/drivers/media/video/cx18/cx18-audio.c +++ b/drivers/media/video/cx18/cx18-audio.c | |||
@@ -26,14 +26,18 @@ | |||
26 | #include "cx18-cards.h" | 26 | #include "cx18-cards.h" |
27 | #include "cx18-audio.h" | 27 | #include "cx18-audio.h" |
28 | 28 | ||
29 | #define CX18_AUDIO_ENABLE 0xc72014 | 29 | #define CX18_AUDIO_ENABLE 0xc72014 |
30 | #define CX18_AI1_MUX_MASK 0x30 | ||
31 | #define CX18_AI1_MUX_I2S1 0x00 | ||
32 | #define CX18_AI1_MUX_I2S2 0x10 | ||
33 | #define CX18_AI1_MUX_843_I2S 0x20 | ||
30 | 34 | ||
31 | /* Selects the audio input and output according to the current | 35 | /* Selects the audio input and output according to the current |
32 | settings. */ | 36 | settings. */ |
33 | int cx18_audio_set_io(struct cx18 *cx) | 37 | int cx18_audio_set_io(struct cx18 *cx) |
34 | { | 38 | { |
35 | const struct cx18_card_audio_input *in; | 39 | const struct cx18_card_audio_input *in; |
36 | u32 val; | 40 | u32 u, v; |
37 | int err; | 41 | int err; |
38 | 42 | ||
39 | /* Determine which input to use */ | 43 | /* Determine which input to use */ |
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx) | |||
52 | return err; | 56 | return err; |
53 | 57 | ||
54 | /* FIXME - this internal mux should be abstracted to a subdev */ | 58 | /* FIXME - this internal mux should be abstracted to a subdev */ |
55 | val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; | 59 | u = cx18_read_reg(cx, CX18_AUDIO_ENABLE); |
56 | val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : | 60 | v = u & ~CX18_AI1_MUX_MASK; |
57 | (in->audio_input << 4); | 61 | switch (in->audio_input) { |
58 | cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); | 62 | case CX18_AV_AUDIO_SERIAL1: |
63 | v |= CX18_AI1_MUX_I2S1; | ||
64 | break; | ||
65 | case CX18_AV_AUDIO_SERIAL2: | ||
66 | v |= CX18_AI1_MUX_I2S2; | ||
67 | break; | ||
68 | default: | ||
69 | v |= CX18_AI1_MUX_843_I2S; | ||
70 | break; | ||
71 | } | ||
72 | if (v == u) { | ||
73 | /* force a toggle of some AI1 MUX control bits */ | ||
74 | u &= ~CX18_AI1_MUX_MASK; | ||
75 | switch (in->audio_input) { | ||
76 | case CX18_AV_AUDIO_SERIAL1: | ||
77 | u |= CX18_AI1_MUX_843_I2S; | ||
78 | break; | ||
79 | case CX18_AV_AUDIO_SERIAL2: | ||
80 | u |= CX18_AI1_MUX_843_I2S; | ||
81 | break; | ||
82 | default: | ||
83 | u |= CX18_AI1_MUX_I2S1; | ||
84 | break; | ||
85 | } | ||
86 | cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE, | ||
87 | u, CX18_AI1_MUX_MASK); | ||
88 | } | ||
89 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
90 | v, CX18_AI1_MUX_MASK); | ||
59 | return 0; | 91 | return 0; |
60 | } | 92 | } |