diff options
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-audio.c')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-audio.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index f897c1ebd5f3..f93b5160bb4f 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -194,19 +194,34 @@ void cx25840_audio_set_path(struct i2c_client *client) | |||
194 | 194 | ||
195 | static int get_volume(struct i2c_client *client) | 195 | static int get_volume(struct i2c_client *client) |
196 | { | 196 | { |
197 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
198 | int vol; | ||
199 | |||
200 | if (state->unmute_volume >= 0) | ||
201 | return state->unmute_volume; | ||
202 | |||
197 | /* Volume runs +18dB to -96dB in 1/2dB steps | 203 | /* Volume runs +18dB to -96dB in 1/2dB steps |
198 | * change to fit the msp3400 -114dB to +12dB range */ | 204 | * change to fit the msp3400 -114dB to +12dB range */ |
199 | 205 | ||
200 | /* check PATH1_VOLUME */ | 206 | /* check PATH1_VOLUME */ |
201 | int vol = 228 - cx25840_read(client, 0x8d4); | 207 | vol = 228 - cx25840_read(client, 0x8d4); |
202 | vol = (vol / 2) + 23; | 208 | vol = (vol / 2) + 23; |
203 | return vol << 9; | 209 | return vol << 9; |
204 | } | 210 | } |
205 | 211 | ||
206 | static void set_volume(struct i2c_client *client, int volume) | 212 | static void set_volume(struct i2c_client *client, int volume) |
207 | { | 213 | { |
208 | /* First convert the volume to msp3400 values (0-127) */ | 214 | struct cx25840_state *state = i2c_get_clientdata(client); |
209 | int vol = volume >> 9; | 215 | int vol; |
216 | |||
217 | if (state->unmute_volume >= 0) { | ||
218 | state->unmute_volume = volume; | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | /* Convert the volume to msp3400 values (0-127) */ | ||
223 | vol = volume >> 9; | ||
224 | |||
210 | /* now scale it up to cx25840 values | 225 | /* now scale it up to cx25840 values |
211 | * -114dB to -96dB maps to 0 | 226 | * -114dB to -96dB maps to 0 |
212 | * this should be 19, but in my testing that was 4dB too loud */ | 227 | * this should be 19, but in my testing that was 4dB too loud */ |
@@ -284,30 +299,26 @@ static void set_balance(struct i2c_client *client, int balance) | |||
284 | 299 | ||
285 | static int get_mute(struct i2c_client *client) | 300 | static int get_mute(struct i2c_client *client) |
286 | { | 301 | { |
287 | /* check SRC1_MUTE_EN */ | 302 | struct cx25840_state *state = i2c_get_clientdata(client); |
288 | return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; | 303 | |
304 | return state->unmute_volume >= 0; | ||
289 | } | 305 | } |
290 | 306 | ||
291 | static void set_mute(struct i2c_client *client, int mute) | 307 | static void set_mute(struct i2c_client *client, int mute) |
292 | { | 308 | { |
293 | struct cx25840_state *state = i2c_get_clientdata(client); | 309 | struct cx25840_state *state = i2c_get_clientdata(client); |
294 | 310 | ||
295 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | 311 | if (mute && state->unmute_volume == -1) { |
296 | /* Must turn off microcontroller in order to mute sound. | 312 | int vol = get_volume(client); |
297 | * Not sure if this is the best method, but it does work. | 313 | |
298 | * If the microcontroller is running, then it will undo any | 314 | set_volume(client, 0); |
299 | * changes to the mute register. */ | 315 | state->unmute_volume = vol; |
300 | if (mute) { | 316 | } |
301 | /* disable microcontroller */ | 317 | else if (!mute && state->unmute_volume != -1) { |
302 | cx25840_and_or(client, 0x803, ~0x10, 0x00); | 318 | int vol = state->unmute_volume; |
303 | cx25840_write(client, 0x8d3, 0x1f); | 319 | |
304 | } else { | 320 | state->unmute_volume = -1; |
305 | /* enable microcontroller */ | 321 | set_volume(client, vol); |
306 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
307 | } | ||
308 | } else { | ||
309 | /* SRC1_MUTE_EN */ | ||
310 | cx25840_and_or(client, 0x8d3, ~0x2, mute ? 0x02 : 0x00); | ||
311 | } | 322 | } |
312 | } | 323 | } |
313 | 324 | ||