Inspired by Raymond Scholz's "Cool down by switching off PVR components?" post. Here's a patch to disable the wm8775 when not needed (that is when we're on tuner audio). The datasheet says that all the registers stay set even when the chip is powered down, so there's no need to reinitialize it seems (my tests confirm this as well).

Sorry Ray, your card doesn't have a wm8775 though :)
Index: driver/ivtv-audio.c
===================================================================
--- driver/ivtv-audio.c (revision 337)
+++ driver/ivtv-audio.c (working copy)
@@ -142,11 +142,19 @@
               }
 
               if (wm_input) {
+                     // Make sure the unit is powered up
+                     int pwrdn = 0;
+                     ivtv_wm8775(itv, WM8775_SET_POWERDN, &pwrdn);
+
                       // select wm8775 input
                       ctl.list[0].setting_id = AMX;
                       ctl.list[0].value = wm_input;
                       ivtv_wm8775(itv, WM8775_CONFIGURE, &ctl);
-              }
+              } else {
+                     // Don't need the wolfson, power it down
+                     int pwrdn = 1;
+                     ivtv_wm8775(itv, WM8775_SET_POWERDN, &pwrdn);
+             }
 
               return 0;
       }
Index: driver/wm8775.c
===================================================================
--- driver/wm8775.c     (revision 337)
+++ driver/wm8775.c     (working copy)
@@ -156,7 +156,7 @@
        //OK 
        /*ADCPD,  */ {R13, 1, 1, 0x00, "ADCPD", 0},
        //OK
-       /*PWDN,   */ {R13, 0, 1, 0x00, "PWDN", 0},
+       /*PDWN,   */ {R13, 0, 1, 0x00, "PDWN", 0},
        //OK
        /*ZCLA,   */ {R14, 8, 1, 0x00, "ZCLA", 0},
        //OK
@@ -393,6 +393,22 @@
        return 0;
 }
 
+static int wm8775_powerdn_set(struct i2c_client *client, int pwrdn)
+{
+       config_request config[2];
+
+       // the datasheet recommends powering down the mux and ADC 
+       // separate from the main power down
+       config[0].value = pwrdn;
+       config[0].setting_id = AINPD;
+       config[1].value = pwrdn;
+       config[1].setting_id = ADCPD;
+       configure(client, config, 2);
+       config[0].setting_id = PDWN;
+       configure(client, config, 1);
+       return 0;
+}
+
 static int command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
        wm8775_ioctl *i = arg;
@@ -412,6 +428,12 @@
                        return -EINVAL;
                }
                return get_configuration(client, i->list, i->list_length);
+       case WM8775_SET_POWERDN:
+               if (!arg) {
+                       LOG_INFO("Invalid ioctl argument pointer. (%p)", arg);
+                       return -EINVAL;
+               }
+               return wm8775_powerdn_set(client, *((int *)arg));
        default:
                return -EINVAL;
        }
Index: driver/wm8775.h
===================================================================
--- driver/wm8775.h     (revision 337)
+++ driver/wm8775.h     (working copy)
@@ -19,7 +19,7 @@
 
 typedef enum {
        RESET = 0, TOD, ADCHPD, ADCMCLK, ADCWL, ADCBCP, ADCLRP, ADCFMT, ADCMS,
-       ADCOSR, ADCRATE, AINPD, ADCPD, PWDN, ZCLA, LAG, ZCRA, RAG,
+       ADCOSR, ADCRATE, AINPD, ADCPD, PDWN, ZCLA, LAG, ZCRA, RAG,
        LCSEL, MAXGAIN, LCT, LCEN, ALCZC, HLD, DCY, ATK, NGTH, NGAT, TRANWIN,
        MAXATTEN, LRBOTH, MUTELA, MUTERA, AMX
 } wm8775_setting_id;
@@ -37,3 +37,4 @@
 #define WM8775_CONFIGURE _IOW( 'w', 100, wm8775_ioctl)
 #define WM8775_LOG_STATE _IO(  'w', 101)
 #define WM8775_GET_STATE _IOWR('w', 102, wm8775_ioctl)
+#define WM8775_SET_POWERDN _IOW('w', 103, int)

Reply via email to