Louie Ilievski wrote:

Oh ok, I didn't know you could change the volume with that patch. I thought it was some fixed value. I tried changing it using ivtvctl, and it's much better. A value of around 53000 seems to bring it close to my 350's volume, but I haven't spent a ton of time trying to get it close. The problem is Myth resets the volume after switching the tuners, so it's always going to go right back to the high volume again. Is there a way around this? It seems that for a specific volume that myth sets, the 150 needs to be set at a lower number that corresponds to what it would be for the 250/350 cards. Thanks for this patch though, at least it's controllable now.

Back out that patch and see if this one works better. I'm worried that the volume might be too low now compared to the 350.
Index: driver/ivtv-audio.c
===================================================================
--- driver/ivtv-audio.c (revision 323)
+++ driver/ivtv-audio.c (working copy)
@@ -190,10 +190,10 @@
 void ivtv_audio_set_volume(struct ivtv *itv, int volume)
 {
        struct video_audio va;
+       memset(&va, 0, sizeof(struct video_audio));
 
        switch (itv->card->audio_selector) {
        case USE_MSP34XX:
-               memset(&va, 0, sizeof(struct video_audio));
                ivtv_msp34xx(itv, VIDIOCGAUDIO, &va);
                va.volume = volume;
                va.mode = 0;    /* keep stereo mode at automatic stereo 
detection */
@@ -201,6 +201,10 @@
                break;
         case USE_PVR150:
        case USE_CX25840:       /* FIXME, probably not right */
+               ivtv_cx25840(itv, VIDIOCGAUDIO, &va);
+               va.volume = volume;
+               ivtv_cx25840(itv, VIDIOCSAUDIO, &va);
+               break;
        case USE_GPIO:
                /* do nothing, there's no volume control */
                break;
@@ -210,14 +214,16 @@
 int ivtv_audio_get_volume(struct ivtv *itv)
 {
        struct video_audio va;
+       memset(&va, 0, sizeof(struct video_audio));
 
        switch (itv->card->audio_selector) {
        case USE_MSP34XX:
-               memset(&va, 0, sizeof(struct video_audio));
                ivtv_msp34xx(itv, VIDIOCGAUDIO, &va);
                break;
         case USE_PVR150:
        case USE_CX25840:       /* FIXME, probably not right */
+               ivtv_cx25840(itv, VIDIOCGAUDIO, &va);
+               break;
        case USE_GPIO:
                /* do nothing, there's no volume control */
                va.volume = 65535;      /* dummy code */
Index: driver/cx25840-driver.c
===================================================================
--- driver/cx25840-driver.c     (revision 323)
+++ driver/cx25840-driver.c     (working copy)
@@ -216,10 +216,6 @@
                break;
        }
 
-       // We set 0x470-0x47f manually, prevent
-       // ACFG from trying to autodetect 
-       CX25840_SET_ACFG_DIS(0x01);
-
        if (is_pal) {
                // 8d.
                CX25840_SET_COMB_PHASE_LIMIT(0x11);
@@ -939,7 +935,23 @@
                        *status = VIDEO_NOT_PRESENT;
                break;
        }
+       
+       case VIDIOCGAUDIO:
+       {
+               /* this shouldn't be called directly from user-space */
+               struct video_audio *va = arg;
+               cx25840_get_v4l_audio(client, va);
+               break;
+       }
 
+       case VIDIOCSAUDIO:
+       {
+               /* this shouldn't be called directly from user-space */
+               struct video_audio *va = arg;
+               cx25840_set_v4l_audio(client, va);
+               break;
+       }
+       
        default:
                ERR("invalid ioctl %X", cmd);
                return -EINVAL;
Index: driver/cx25840-audio.c
===================================================================
--- driver/cx25840-audio.c      (revision 323)
+++ driver/cx25840-audio.c      (working copy)
@@ -1,4 +1,5 @@
 #include <linux/i2c.h>
+#include <linux/videodev.h>
 
 #include "decoder.h"
 
@@ -265,3 +266,51 @@
 
        return 0;
 }
+
+void cx25840_get_v4l_audio(struct i2c_client *client, struct video_audio *va)
+{
+       /* MUTABLE isn't included, although it is possible if
+        * we stop the microcontroller and mute all inputs */
+       va->flags = VIDEO_AUDIO_TREBLE | VIDEO_AUDIO_BASS;
+       
+       /* Volume runs +18dB to -96dB, change to -96dB to +0dB */
+       va->step = 193;
+       va->volume = cx25840_read_setting(client, PATH1_VOLUME);
+       //va->volume = (0xff - va->volume) << 8;
+       va->volume = (va->volume <= 36) ? 0xffff : 
+               0xffff - ((va->volume - 36) * 0xffff / va->step);
+       /* bass is 48 steps +12dB to -12dB */
+       va->bass = cx25840_read_setting(client, PATH1_EQ_BASS_VOL);
+       va->bass = ((49 - va->bass) * 0xffff) / 49;
+       /* treble is 48 steps +12dB to -12dB */
+       va->treble = cx25840_read_setting(client, PATH1_EQ_TREBLE_VOL);
+       va->treble = ((49 - va->treble) * 0xffff) / 49;
+       /* balance is 7 bit, 0 to -96dB */
+       va->balance = cx25840_read_setting(client, PATH1_BAL_LEVEL);
+       if (cx25840_read_setting(client, PATH1_BAL_LEFT) == 0)
+               va->balance = 0x80 - va->balance;
+       else
+               va->balance = 0x80 + va->balance;
+       va->balance = va->balance << 8;
+}
+
+void cx25840_set_v4l_audio(struct i2c_client *client, struct video_audio *va)
+{
+       //int volume = 0xff - (va->volume >> 8);
+       int volume = 229 - (va->volume * 193 / 0xffff);
+       int bass = 49 - (va->bass * 49 / 0xffff);
+       int treble = 49 - (va->treble * 49 / 0xffff);
+       int balance = va->balance >> 8;
+
+       CX25840_SET_PATH1_VOLUME(volume);
+       CX25840_SET_PATH1_EQ_BASS_VOL(bass);
+       CX25840_SET_PATH1_EQ_TREBLE_VOL(treble);
+       if (balance > 0x80) {
+               CX25840_SET_PATH1_BAL_LEFT(0x01);
+               CX25840_SET_PATH1_BAL_LEVEL(balance & 0x7f);
+       } else {
+               CX25840_SET_PATH1_BAL_LEFT(0x00);
+               CX25840_SET_PATH1_BAL_LEVEL(0x80 - balance);
+       }
+}
+
Index: driver/cx25840-audio.h
===================================================================
--- driver/cx25840-audio.h      (revision 323)
+++ driver/cx25840-audio.h      (working copy)
@@ -6,3 +6,5 @@
                            struct decoder_state *state, int audio_input);
 int cx25840_set_audio_rate(struct i2c_client *client,
                           struct decoder_state *state, int audio);
+void cx25840_get_v4l_audio(struct i2c_client *client, struct video_audio *va);
+void cx25840_set_v4l_audio(struct i2c_client *client, struct video_audio *va);

Reply via email to