X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fcx88%2Fcx88-tvaudio.c;h=874d2974d5e60d01591342d92996b139fa3071ce;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=f6def3df94607a7628a6879a804c12a0b758cd82;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index f6def3df9..874d2974d 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -1,4 +1,6 @@ /* + $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] @@ -16,9 +18,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 @@ -49,15 +51,17 @@ #include #include #include +#include +#include #include "cx88.h" static unsigned int audio_debug = 1; -MODULE_PARM(audio_debug,"i"); +module_param(audio_debug,int,0644); MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]"); #define dprintk(fmt, arg...) if (audio_debug) \ - printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg) + printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) /* ----------------------------------------------------------- */ @@ -93,7 +97,7 @@ struct rlist { u32 val; }; -static void set_audio_registers(struct cx8800_dev *dev, +static void set_audio_registers(struct cx88_core *core, const struct rlist *l) { int i; @@ -115,7 +119,7 @@ static void set_audio_registers(struct cx8800_dev *dev, } } -static void set_audio_start(struct cx8800_dev *dev, +static void set_audio_start(struct cx88_core *core, u32 mode, u32 ctl) { // mute @@ -133,7 +137,7 @@ static void set_audio_start(struct cx8800_dev *dev, cx_write(AUD_CTL, ctl); } -static void set_audio_finish(struct cx8800_dev *dev) +static void set_audio_finish(struct cx88_core *core) { u32 volume; @@ -150,7 +154,7 @@ static void set_audio_finish(struct cx8800_dev *dev) /* ----------------------------------------------------------- */ -static void set_audio_standard_BTSC(struct cx8800_dev *dev, unsigned int sap) +static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap) { static const struct rlist btsc[] = { /* from dscaler */ @@ -247,19 +251,19 @@ static void set_audio_standard_BTSC(struct cx8800_dev *dev, 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(dev, 0x0001, + set_audio_start(core, 0x0001, EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP); - set_audio_registers(dev, btsc_sap); + set_audio_registers(core, btsc_sap); } else { dprintk("%s (status: known-good)\n",__FUNCTION__); - set_audio_start(dev, 0x0001, + set_audio_start(core, 0x0001, EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO); - set_audio_registers(dev, btsc); + set_audio_registers(core, btsc); } - set_audio_finish(dev); + set_audio_finish(core); } -static void set_audio_standard_NICAM(struct cx8800_dev *dev) +static void set_audio_standard_NICAM(struct cx88_core *core) { static const struct rlist nicam_common[] = { /* from dscaler */ @@ -316,24 +320,25 @@ static void set_audio_standard_NICAM(struct cx8800_dev *dev) { /* end of list */ }, }; - set_audio_start(dev, 0x0010, + set_audio_start(core, 0x0010, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); - set_audio_registers(dev, nicam_common); - switch (dev->tvaudio) { + set_audio_registers(core, nicam_common); + switch (core->tvaudio) { case WW_NICAM_I: dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__); - set_audio_registers(dev, nicam_pal_i); + set_audio_registers(core, nicam_pal_i); + break; case WW_NICAM_BGDKL: - dprintk("%s PAL NICAM (status: unknown)\n",__FUNCTION__); - set_audio_registers(dev, nicam_default); + dprintk("%s PAL-BGDK NICAM (status: unknown)\n",__FUNCTION__); + set_audio_registers(core, nicam_default); break; }; - set_audio_finish(dev); + set_audio_finish(core); } -static void set_audio_standard_NICAM_L(struct cx8800_dev *dev) +static void set_audio_standard_NICAM_L(struct cx88_core *core) { - /* This is officially wierd.. register dumps indicate windows + /* This is officially weird.. register dumps indicate windows * uses audio mode 4.. A2. Let's operate and find out. */ static const struct rlist nicam_l[] = { @@ -449,13 +454,13 @@ static void set_audio_standard_NICAM_L(struct cx8800_dev *dev) }; dprintk("%s (status: unknown)\n",__FUNCTION__); - set_audio_start(dev, 0x0004, + set_audio_start(core, 0x0004, 0 /* FIXME */); - set_audio_registers(dev, nicam_l); - set_audio_finish(dev); + set_audio_registers(core, nicam_l); + set_audio_finish(core); } -static void set_audio_standard_A2(struct cx8800_dev *dev) +static void set_audio_standard_A2(struct cx88_core *core) { /* from dscaler cvs */ static const struct rlist a2_common[] = { @@ -545,26 +550,33 @@ static void set_audio_standard_A2(struct cx8800_dev *dev) { /* end of list */ }, }; - set_audio_start(dev, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO); - set_audio_registers(dev, a2_common); - switch (dev->tvaudio) { + 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; case WW_A2_BG: dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); - set_audio_registers(dev, a2_table1); + set_audio_registers(core, a2_table1); break; case WW_A2_DK: dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); - set_audio_registers(dev, a2_table2); + set_audio_registers(core, a2_table2); break; case WW_A2_M: dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); - set_audio_registers(dev, a2_table3); + set_audio_registers(core, a2_table3); break; }; - set_audio_finish(dev); + set_audio_finish(core); } -static void set_audio_standard_EIAJ(struct cx8800_dev *dev) +static void set_audio_standard_EIAJ(struct cx88_core *core) { static const struct rlist eiaj[] = { /* TODO: eiaj register settings are not there yet ... */ @@ -573,12 +585,12 @@ static void set_audio_standard_EIAJ(struct cx8800_dev *dev) }; dprintk("%s (status: unknown)\n",__FUNCTION__); - set_audio_start(dev, 0x0002, EN_EIAJ_AUTO_STEREO); - set_audio_registers(dev, eiaj); - set_audio_finish(dev); + set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO); + set_audio_registers(core, eiaj); + set_audio_finish(core); } -static void set_audio_standard_FM(struct cx8800_dev *dev) +static void set_audio_standard_FM(struct cx88_core *core) { #if 0 /* FIXME */ switch (dev->audio_properties.FM_deemphasis) @@ -596,7 +608,7 @@ static void set_audio_standard_FM(struct cx8800_dev *dev) cx_write(AUD_DEEMPH1_B0, 0x1C29); cx_write(AUD_DEEMPH1_A1, 0x3FC66); cx_write(AUD_DEEMPH1_B1, 0x399A); - + break; case WW_FM_DEEMPH_75: @@ -618,50 +630,51 @@ static void set_audio_standard_FM(struct cx8800_dev *dev) #endif dprintk("%s (status: unknown)\n",__FUNCTION__); - set_audio_start(dev, 0x0020, EN_FMRADIO_AUTO_STEREO); + set_audio_start(core, 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(dev); + set_audio_finish(core); } /* ----------------------------------------------------------- */ -void cx88_set_tvaudio(struct cx8800_dev *dev) +void cx88_set_tvaudio(struct cx88_core *core) { - switch (dev->tvaudio) { + switch (core->tvaudio) { case WW_BTSC: - set_audio_standard_BTSC(dev,0); + set_audio_standard_BTSC(core,0); break; - case WW_NICAM_I: + // case WW_NICAM_I: case WW_NICAM_BGDKL: - set_audio_standard_NICAM(dev); + set_audio_standard_NICAM(core); break; + case WW_NICAM_I: case WW_A2_BG: case WW_A2_DK: case WW_A2_M: - set_audio_standard_A2(dev); + set_audio_standard_A2(core); break; case WW_EIAJ: - set_audio_standard_EIAJ(dev); + set_audio_standard_EIAJ(core); break; case WW_FM: - set_audio_standard_FM(dev); + set_audio_standard_FM(core); break; case WW_SYSTEM_L_AM: - set_audio_standard_NICAM_L(dev); + set_audio_standard_NICAM_L(core); break; case WW_NONE: default: - printk("%s: unknown tv audio mode [%d]\n", - dev->name, dev->tvaudio); + printk("%s/0: unknown tv audio mode [%d]\n", + core->name, core->tvaudio); break; } return; } -void cx88_get_stereo(struct cx8800_dev *dev, struct v4l2_tuner *t) +void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) { static char *m[] = {"stereo", "dual mono", "mono", "sap"}; static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"}; @@ -670,16 +683,28 @@ void cx88_get_stereo(struct cx8800_dev *dev, struct v4l2_tuner *t) reg = cx_read(AUD_STATUS); mode = reg & 0x03; pilot = (reg >> 2) & 0x03; - dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n", - reg, m[mode], p[pilot], - aud_ctl_names[cx_read(AUD_CTL) & 63]); + + 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; 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 (dev->tvaudio) { + 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; case WW_A2_BG: case WW_A2_DK: case WW_A2_M: @@ -707,17 +732,33 @@ void cx88_get_stereo(struct cx8800_dev *dev, struct v4l2_tuner *t) return; } -void cx88_set_stereo(struct cx8800_dev *dev, u32 mode) +void cx88_set_stereo(struct cx88_core *core, u32 mode) { u32 ctl = UNSET; u32 mask = UNSET; - switch (dev->tvaudio) { + 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; 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; @@ -734,7 +775,7 @@ void cx88_set_stereo(struct cx8800_dev *dev, 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; @@ -747,10 +788,10 @@ void cx88_set_stereo(struct cx8800_dev *dev, 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; @@ -759,7 +800,7 @@ void cx88_set_stereo(struct cx8800_dev *dev, u32 mode) mask = 0x3f; break; } - break; + break; } if (UNSET != ctl) { @@ -774,32 +815,33 @@ void cx88_set_stereo(struct cx8800_dev *dev, u32 mode) return; } -/* just monitor the audio status for now ... */ int cx88_audio_thread(void *data) { - struct cx8800_dev *dev = data; + struct cx88_core *core = data; struct v4l2_tuner t; - daemonize("msp3400"); - allow_signal(SIGTERM); dprintk("cx88: tvaudio thread started\n"); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ*3); - if (signal_pending(current)) - break; - if (dev->shutdown) + if (kthread_should_stop()) break; + /* just monitor the audio status for now ... */ memset(&t,0,sizeof(t)); - cx88_get_stereo(dev,&t); + cx88_get_stereo(core,&t); + msleep_interruptible(1000); } dprintk("cx88: tvaudio thread exiting\n"); - complete_and_exit(&dev->texit, 0); + return 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