]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/cx25840/cx25840-core.c
V4L/DVB (5999): cx25840: add radio support.
[linux-2.6-omap-h63xx.git] / drivers / media / video / cx25840 / cx25840-core.c
index 1757a588970fc242717128f707765029a9862eac..8f9c32613b45151b4951b19e4d246385608acb07 100644 (file)
@@ -179,7 +179,7 @@ static void cx25836_initialize(struct i2c_client *client)
        cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
 }
 
-static void cx25840_initialize(struct i2c_client *client, int loadfw)
+static void cx25840_initialize(struct i2c_client *client)
 {
        struct cx25840_state *state = i2c_get_clientdata(client);
 
@@ -197,8 +197,7 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
        cx25840_write(client, 0x13c, 0x01);
        cx25840_write(client, 0x13c, 0x00);
        /* 5. */
-       if (loadfw)
-               cx25840_loadfw(client);
+       cx25840_loadfw(client);
        /* 6. */
        cx25840_write(client, 0x115, 0x8c);
        cx25840_write(client, 0x116, 0x07);
@@ -252,7 +251,11 @@ static void input_change(struct i2c_client *client)
        cx25840_and_or(client, 0x401, ~0x60, 0);
        cx25840_and_or(client, 0x401, ~0x60, 0x60);
 
-       if (std & V4L2_STD_525_60) {
+       if (state->radio) {
+               cx25840_write(client, 0x808, 0xf9);
+               cx25840_write(client, 0x80b, 0x00);
+       }
+       else if (std & V4L2_STD_525_60) {
                /* Certain Hauppauge PVR150 models have a hardware bug
                   that causes audio to drop out. For these models the
                   audio standard must be set explicitly.
@@ -555,7 +558,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
 {
        struct v4l2_pix_format *pix;
        int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
-       int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+       int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
 
        switch (fmt->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -567,7 +570,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
                Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
                Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
 
-               Vlines = pix->height + (is_pal ? 4 : 7);
+               Vlines = pix->height + (is_50Hz ? 4 : 7);
 
                if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
                    (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
@@ -625,6 +628,22 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
        struct v4l2_tuner *vt = arg;
        struct v4l2_routing *route = arg;
 
+       /* ignore these commands */
+       switch (cmd) {
+               case TUNER_SET_TYPE_ADDR:
+                       return 0;
+       }
+
+       if (!state->is_initialized) {
+               v4l_dbg(1, cx25840_debug, client, "cmd %08x triggered fw load\n", cmd);
+               /* initialize on first use */
+               state->is_initialized = 1;
+               if (state->is_cx25836)
+                       cx25836_initialize(client);
+               else
+                       cx25840_initialize(client);
+       }
+
        switch (cmd) {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        /* ioctls to allow direct access to the
@@ -825,7 +844,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
                if (state->is_cx25836)
                        cx25836_initialize(client);
                else
-                       cx25840_initialize(client, 0);
+                       cx25840_initialize(client);
                break;
 
        case VIDIOC_G_CHIP_IDENT:
@@ -900,17 +919,13 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
        state->audclk_freq = 48000;
        state->pvr150_workaround = 0;
        state->audmode = V4L2_TUNER_MODE_LANG1;
+       state->unmute_volume = -1;
        state->vbi_line_offset = 8;
        state->id = id;
        state->rev = device_id;
 
        i2c_attach_client(client);
 
-       if (state->is_cx25836)
-               cx25836_initialize(client);
-       else
-               cx25840_initialize(client, 1);
-
        return 0;
 }
 
@@ -1056,9 +1071,10 @@ static void log_audio_status(struct i2c_client *client)
        }
        v4l_info(client, "Detected audio standard:   %s\n", p);
        v4l_info(client, "Audio muted:               %s\n",
-                   (mute_ctl & 0x2) ? "yes" : "no");
+                   (state->unmute_volume >= 0) ? "yes" : "no");
        v4l_info(client, "Audio microcontroller:     %s\n",
-                   (download_ctl & 0x10) ? "running" : "stopped");
+                   (download_ctl & 0x10) ?
+                               ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
 
        switch (audio_config >> 4) {
        case 0x00: p = "undefined"; break;