diff options
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-audio.c')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-audio.c | 144 |
1 files changed, 17 insertions, 127 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 45608d50529c..6faad34df3ac 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c @@ -474,33 +474,10 @@ void cx25840_audio_set_path(struct i2c_client *client) cx25840_and_or(client, 0x803, ~0x10, 0x10); } -static int get_volume(struct i2c_client *client) -{ - struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - int vol; - - if (state->unmute_volume >= 0) - return state->unmute_volume; - - /* Volume runs +18dB to -96dB in 1/2dB steps - * change to fit the msp3400 -114dB to +12dB range */ - - /* check PATH1_VOLUME */ - vol = 228 - cx25840_read(client, 0x8d4); - vol = (vol / 2) + 23; - return vol << 9; -} - static void set_volume(struct i2c_client *client, int volume) { - struct cx25840_state *state = to_state(i2c_get_clientdata(client)); int vol; - if (state->unmute_volume >= 0) { - state->unmute_volume = volume; - return; - } - /* Convert the volume to msp3400 values (0-127) */ vol = volume >> 9; @@ -517,52 +494,6 @@ static void set_volume(struct i2c_client *client, int volume) cx25840_write(client, 0x8d4, 228 - (vol * 2)); } -static int get_bass(struct i2c_client *client) -{ - /* bass is 49 steps +12dB to -12dB */ - - /* check PATH1_EQ_BASS_VOL */ - int bass = cx25840_read(client, 0x8d9) & 0x3f; - bass = (((48 - bass) * 0xffff) + 47) / 48; - return bass; -} - -static void set_bass(struct i2c_client *client, int bass) -{ - /* PATH1_EQ_BASS_VOL */ - cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); -} - -static int get_treble(struct i2c_client *client) -{ - /* treble is 49 steps +12dB to -12dB */ - - /* check PATH1_EQ_TREBLE_VOL */ - int treble = cx25840_read(client, 0x8db) & 0x3f; - treble = (((48 - treble) * 0xffff) + 47) / 48; - return treble; -} - -static void set_treble(struct i2c_client *client, int treble) -{ - /* PATH1_EQ_TREBLE_VOL */ - cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); -} - -static int get_balance(struct i2c_client *client) -{ - /* balance is 7 bit, 0 to -96dB */ - - /* check PATH1_BAL_LEVEL */ - int balance = cx25840_read(client, 0x8d5) & 0x7f; - /* check PATH1_BAL_LEFT */ - if ((cx25840_read(client, 0x8d5) & 0x80) == 0) - balance = 0x80 - balance; - else - balance = 0x80 + balance; - return balance << 8; -} - static void set_balance(struct i2c_client *client, int balance) { int bal = balance >> 8; @@ -579,31 +510,6 @@ static void set_balance(struct i2c_client *client, int balance) } } -static int get_mute(struct i2c_client *client) -{ - struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - - return state->unmute_volume >= 0; -} - -static void set_mute(struct i2c_client *client, int mute) -{ - struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - - if (mute && state->unmute_volume == -1) { - int vol = get_volume(client); - - set_volume(client, 0); - state->unmute_volume = vol; - } - else if (!mute && state->unmute_volume != -1) { - int vol = state->unmute_volume; - - state->unmute_volume = -1; - set_volume(client, vol); - } -} - int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -624,25 +530,31 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) return retval; } -int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int cx25840_audio_s_ctrl(struct v4l2_ctrl *ctrl) { + struct v4l2_subdev *sd = to_sd(ctrl); + struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: - ctrl->value = get_volume(client); + if (state->mute->val) + set_volume(client, 0); + else + set_volume(client, state->volume->val); break; case V4L2_CID_AUDIO_BASS: - ctrl->value = get_bass(client); + /* PATH1_EQ_BASS_VOL */ + cx25840_and_or(client, 0x8d9, ~0x3f, + 48 - (ctrl->val * 48 / 0xffff)); break; case V4L2_CID_AUDIO_TREBLE: - ctrl->value = get_treble(client); + /* PATH1_EQ_TREBLE_VOL */ + cx25840_and_or(client, 0x8db, ~0x3f, + 48 - (ctrl->val * 48 / 0xffff)); break; case V4L2_CID_AUDIO_BALANCE: - ctrl->value = get_balance(client); - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = get_mute(client); + set_balance(client, ctrl->val); break; default: return -EINVAL; @@ -650,28 +562,6 @@ int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - set_volume(client, ctrl->value); - break; - case V4L2_CID_AUDIO_BASS: - set_bass(client, ctrl->value); - break; - case V4L2_CID_AUDIO_TREBLE: - set_treble(client, ctrl->value); - break; - case V4L2_CID_AUDIO_BALANCE: - set_balance(client, ctrl->value); - break; - case V4L2_CID_AUDIO_MUTE: - set_mute(client, ctrl->value); - break; - default: - return -EINVAL; - } - return 0; -} +const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops = { + .s_ctrl = cx25840_audio_s_ctrl, +}; |