This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / media / video / cx88 / cx88-tvaudio.c
index 874d297..f6def3d 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    $Id: cx88-tvaudio.c,v 1.24 2004/10/25 11:51:00 kraxel Exp $
-
     cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
 
      (c) 2001 Michael Eskin, Tom Zakrajsek [Windows version]
@@ -18,9 +16,9 @@
 
     Some comes from the dscaler sources, one of the dscaler driver guy works
     for Conexant ...
-
+    
     -----------------------------------------------------------------------
-
+    
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
 
 #include "cx88.h"
 
 static unsigned int audio_debug = 1;
-module_param(audio_debug,int,0644);
+MODULE_PARM(audio_debug,"i");
 MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]");
 
 #define dprintk(fmt, arg...)   if (audio_debug) \
-       printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
+       printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg)
 
 /* ----------------------------------------------------------- */
 
@@ -97,7 +93,7 @@ struct rlist {
        u32 val;
 };
 
-static void set_audio_registers(struct cx88_core *core,
+static void set_audio_registers(struct cx8800_dev *dev,
                                const struct rlist *l)
 {
        int i;
@@ -119,7 +115,7 @@ static void set_audio_registers(struct cx88_core *core,
        }
 }
 
-static void set_audio_start(struct cx88_core *core,
+static void set_audio_start(struct cx8800_dev *dev,
                            u32 mode, u32 ctl)
 {
        // mute
@@ -137,7 +133,7 @@ static void set_audio_start(struct cx88_core *core,
        cx_write(AUD_CTL,           ctl);
 }
 
-static void set_audio_finish(struct cx88_core *core)
+static void set_audio_finish(struct cx8800_dev *dev)
 {
        u32 volume;
 
@@ -154,7 +150,7 @@ static void set_audio_finish(struct cx88_core *core)
 
 /* ----------------------------------------------------------- */
 
-static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
+static void set_audio_standard_BTSC(struct cx8800_dev *dev, unsigned int sap)
 {
        static const struct rlist btsc[] = {
                /* from dscaler */
@@ -251,19 +247,19 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
        // dscaler: don't know why to set EN_FMRADIO_EN_RDS
        if (sap) {
                dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
-               set_audio_start(core, 0x0001,
+               set_audio_start(dev, 0x0001,
                                EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
-               set_audio_registers(core, btsc_sap);
+               set_audio_registers(dev, btsc_sap);
        } else {
                dprintk("%s (status: known-good)\n",__FUNCTION__);
-               set_audio_start(core, 0x0001,
+               set_audio_start(dev, 0x0001,
                                EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
-               set_audio_registers(core, btsc);
+               set_audio_registers(dev, btsc);
        }
-       set_audio_finish(core);
+       set_audio_finish(dev);
 }
 
-static void set_audio_standard_NICAM(struct cx88_core *core)
+static void set_audio_standard_NICAM(struct cx8800_dev *dev)
 {
        static const struct rlist nicam_common[] = {
                /* from dscaler */
@@ -320,25 +316,24 @@ static void set_audio_standard_NICAM(struct cx88_core *core)
                 { /* end of list */ },
        };
 
-        set_audio_start(core, 0x0010,
+        set_audio_start(dev, 0x0010,
                        EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
-        set_audio_registers(core, nicam_common);
-       switch (core->tvaudio) {
+        set_audio_registers(dev, nicam_common);
+       switch (dev->tvaudio) {
        case WW_NICAM_I:
                dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__);
-               set_audio_registers(core, nicam_pal_i);
-               break;
+               set_audio_registers(dev, nicam_pal_i);
        case WW_NICAM_BGDKL:
-               dprintk("%s PAL-BGDK NICAM (status: unknown)\n",__FUNCTION__);
-               set_audio_registers(core, nicam_default);
+               dprintk("%s PAL NICAM (status: unknown)\n",__FUNCTION__);
+               set_audio_registers(dev, nicam_default);
                break;
        };
-        set_audio_finish(core);
+        set_audio_finish(dev);
 }
 
-static void set_audio_standard_NICAM_L(struct cx88_core *core)
+static void set_audio_standard_NICAM_L(struct cx8800_dev *dev)
 {
-       /* This is officially weird.. register dumps indicate windows
+       /* This is officially wierd.. register dumps indicate windows
         * uses audio mode 4.. A2. Let's operate and find out. */
 
        static const struct rlist nicam_l[] = {
@@ -454,13 +449,13 @@ static void set_audio_standard_NICAM_L(struct cx88_core *core)
        };
 
        dprintk("%s (status: unknown)\n",__FUNCTION__);
-        set_audio_start(core, 0x0004,
+        set_audio_start(dev, 0x0004,
                        0 /* FIXME */);
-       set_audio_registers(core, nicam_l);
-        set_audio_finish(core);
+       set_audio_registers(dev, nicam_l);
+        set_audio_finish(dev);
 }
 
-static void set_audio_standard_A2(struct cx88_core *core)
+static void set_audio_standard_A2(struct cx8800_dev *dev)
 {
        /* from dscaler cvs */
        static const struct rlist a2_common[] = {
@@ -550,33 +545,26 @@ static void set_audio_standard_A2(struct cx88_core *core)
                { /* end of list */ },
        };
 
-       set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO);
-       set_audio_registers(core, a2_common);
-       switch (core->tvaudio) {
-       case WW_NICAM_I:
-               /* gives at least mono according to the dscaler guys */
-               /* so use use that while nicam is broken ...         */
-               dprintk("%s PAL-I mono (status: unknown)\n",__FUNCTION__);
-               set_audio_registers(core, a2_table1);
-               cx_write(AUD_CTL, EN_A2_FORCE_MONO1);
-               break;
+       set_audio_start(dev, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO);
+       set_audio_registers(dev, a2_common);
+       switch (dev->tvaudio) {
        case WW_A2_BG:
                dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
-               set_audio_registers(core, a2_table1);
+               set_audio_registers(dev, a2_table1);
                break;
        case WW_A2_DK:
                dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
-               set_audio_registers(core, a2_table2);
+               set_audio_registers(dev, a2_table2);
                break;
        case WW_A2_M:
                dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
-               set_audio_registers(core, a2_table3);
+               set_audio_registers(dev, a2_table3);
                break;
        };
-       set_audio_finish(core);
+       set_audio_finish(dev);
 }
 
-static void set_audio_standard_EIAJ(struct cx88_core *core)
+static void set_audio_standard_EIAJ(struct cx8800_dev *dev)
 {
        static const struct rlist eiaj[] = {
                /* TODO: eiaj register settings are not there yet ... */
@@ -585,12 +573,12 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
        };
        dprintk("%s (status: unknown)\n",__FUNCTION__);
 
-       set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO);
-       set_audio_registers(core, eiaj);
-       set_audio_finish(core);
+       set_audio_start(dev, 0x0002, EN_EIAJ_AUTO_STEREO);
+       set_audio_registers(dev, eiaj);
+       set_audio_finish(dev);
 }
 
-static void set_audio_standard_FM(struct cx88_core *core)
+static void set_audio_standard_FM(struct cx8800_dev *dev)
 {
 #if 0 /* FIXME */
        switch (dev->audio_properties.FM_deemphasis)
@@ -608,7 +596,7 @@ static void set_audio_standard_FM(struct cx88_core *core)
                        cx_write(AUD_DEEMPH1_B0, 0x1C29);
                        cx_write(AUD_DEEMPH1_A1, 0x3FC66);
                        cx_write(AUD_DEEMPH1_B1, 0x399A);
-
+                       
                        break;
 
                case WW_FM_DEEMPH_75:
@@ -630,51 +618,50 @@ static void set_audio_standard_FM(struct cx88_core *core)
 #endif
 
        dprintk("%s (status: unknown)\n",__FUNCTION__);
-       set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
+       set_audio_start(dev, 0x0020, EN_FMRADIO_AUTO_STEREO);
 
        // AB: 10/2/01: this register is not being reset appropriately on occasion.
        cx_write(AUD_POLYPH80SCALEFAC,3);
 
-       set_audio_finish(core);
+       set_audio_finish(dev);
 }
 
 /* ----------------------------------------------------------- */
 
-void cx88_set_tvaudio(struct cx88_core *core)
+void cx88_set_tvaudio(struct cx8800_dev *dev)
 {
-       switch (core->tvaudio) {
+       switch (dev->tvaudio) {
        case WW_BTSC:
-               set_audio_standard_BTSC(core,0);
+               set_audio_standard_BTSC(dev,0);
                break;
-       // case WW_NICAM_I:
+       case WW_NICAM_I:
        case WW_NICAM_BGDKL:
-               set_audio_standard_NICAM(core);
+               set_audio_standard_NICAM(dev);
                break;
-       case WW_NICAM_I:
        case WW_A2_BG:
        case WW_A2_DK:
        case WW_A2_M:
-               set_audio_standard_A2(core);
+               set_audio_standard_A2(dev);
                break;
        case WW_EIAJ:
-               set_audio_standard_EIAJ(core);
+               set_audio_standard_EIAJ(dev);
                break;
        case WW_FM:
-               set_audio_standard_FM(core);
+               set_audio_standard_FM(dev);
                break;
        case WW_SYSTEM_L_AM:
-               set_audio_standard_NICAM_L(core);
+               set_audio_standard_NICAM_L(dev);
                break;
        case WW_NONE:
        default:
-               printk("%s/0: unknown tv audio mode [%d]\n",
-                      core->name, core->tvaudio);
+               printk("%s: unknown tv audio mode [%d]\n",
+                      dev->name, dev->tvaudio);
                break;
        }
        return;
 }
 
-void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
+void cx88_get_stereo(struct cx8800_dev *dev, struct v4l2_tuner *t)
 {
        static char *m[] = {"stereo", "dual mono", "mono", "sap"};
        static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"};
@@ -683,28 +670,16 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
        reg   = cx_read(AUD_STATUS);
        mode  = reg & 0x03;
        pilot = (reg >> 2) & 0x03;
-
-       if (core->astat != reg)
-               dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",
-                       reg, m[mode], p[pilot],
-                       aud_ctl_names[cx_read(AUD_CTL) & 63]);
-       core->astat = reg;
+       dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",
+               reg, m[mode], p[pilot],
+               aud_ctl_names[cx_read(AUD_CTL) & 63]);
 
        t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
                V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
        t->rxsubchans = V4L2_TUNER_SUB_MONO;
        t->audmode    = V4L2_TUNER_MODE_MONO;
 
-       switch (core->tvaudio) {
-       case WW_BTSC:
-               t->capability = V4L2_TUNER_CAP_STEREO |
-                       V4L2_TUNER_CAP_SAP;
-               t->rxsubchans = V4L2_TUNER_SUB_STEREO;
-               if (1 == pilot) {
-                       /* SAP */
-                       t->rxsubchans |= V4L2_TUNER_SUB_SAP;
-               }
-               break;
+       switch (dev->tvaudio) {
        case WW_A2_BG:
        case WW_A2_DK:
        case WW_A2_M:
@@ -732,33 +707,17 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
        return;
 }
 
-void cx88_set_stereo(struct cx88_core *core, u32 mode)
+void cx88_set_stereo(struct cx8800_dev *dev, u32 mode)
 {
        u32 ctl  = UNSET;
        u32 mask = UNSET;
 
-       switch (core->tvaudio) {
-       case WW_BTSC:
-               switch (mode) {
-               case V4L2_TUNER_MODE_MONO:
-                       ctl  = EN_BTSC_FORCE_MONO;
-                       mask = 0x3f;
-                       break;
-               case V4L2_TUNER_MODE_SAP:
-                       ctl  = EN_BTSC_FORCE_SAP;
-                       mask = 0x3f;
-                       break;
-               case V4L2_TUNER_MODE_STEREO:
-                       ctl  = EN_BTSC_AUTO_STEREO;
-                       mask = 0x3f;
-                       break;
-               }
-               break;
+       switch (dev->tvaudio) {
        case WW_A2_BG:
        case WW_A2_DK:
        case WW_A2_M:
                switch (mode) {
-               case V4L2_TUNER_MODE_MONO:
+               case V4L2_TUNER_MODE_MONO:   
                case V4L2_TUNER_MODE_LANG1:
                        ctl  = EN_A2_FORCE_MONO1;
                        mask = 0x3f;
@@ -775,7 +734,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode)
                break;
        case WW_NICAM_BGDKL:
                switch (mode) {
-               case V4L2_TUNER_MODE_MONO:
+               case V4L2_TUNER_MODE_MONO:   
                        ctl  = EN_NICAM_FORCE_MONO1;
                        mask = 0x3f;
                        break;
@@ -788,10 +747,10 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode)
                        mask = 0x93f;
                        break;
                }
-               break;
+               break;  
        case WW_FM:
                switch (mode) {
-               case V4L2_TUNER_MODE_MONO:
+               case V4L2_TUNER_MODE_MONO:   
                        ctl  = EN_FMRADIO_FORCE_MONO;
                        mask = 0x3f;
                        break;
@@ -800,7 +759,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode)
                        mask = 0x3f;
                        break;
                }
-               break;
+               break;  
        }
 
        if (UNSET != ctl) {
@@ -815,33 +774,32 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode)
        return;
 }
 
+/* just monitor the audio status for now ... */
 int cx88_audio_thread(void *data)
 {
-       struct cx88_core *core = data;
+       struct cx8800_dev *dev = data;
        struct v4l2_tuner t;
 
+       daemonize("msp3400");
+       allow_signal(SIGTERM);
        dprintk("cx88: tvaudio thread started\n");
+
        for (;;) {
-               if (kthread_should_stop())
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(HZ*3);
+               if (signal_pending(current))
+                       break;
+               if (dev->shutdown)
                        break;
 
-               /* just monitor the audio status for now ... */
                memset(&t,0,sizeof(t));
-               cx88_get_stereo(core,&t);
-               msleep_interruptible(1000);
+               cx88_get_stereo(dev,&t);
        }
 
        dprintk("cx88: tvaudio thread exiting\n");
-       return 0;
+        complete_and_exit(&dev->texit, 0);
 }
 
-/* ----------------------------------------------------------- */
-
-EXPORT_SYMBOL(cx88_set_tvaudio);
-EXPORT_SYMBOL(cx88_set_stereo);
-EXPORT_SYMBOL(cx88_get_stereo);
-EXPORT_SYMBOL(cx88_audio_thread);
-
 /*
  * Local variables:
  * c-basic-offset: 8