]> err.no Git - linux-2.6/commitdiff
V4L/DVB (6947): Improve audio setup handling
authorMauro Carvalho Chehab <mchehab@infradead.org>
Sat, 5 Jan 2008 12:53:54 +0000 (09:53 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Fri, 25 Jan 2008 21:04:30 +0000 (19:04 -0200)
It is possible to select audio inputs via em28xx or via ac97 functions.
This patch allows configuring a board to use either one way.

It also do some cleanups at audio setup configurations.

Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/em28xx/em28xx.h

index d56484f204677105c9fd435fdeb7bf8aca30ed75..70c5ec268f6a8db5e0035746749b0ed274be51d9 100644 (file)
@@ -252,7 +252,7 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
  * em28xx_write_ac97()
  * write a 16 bit value to the specified AC97 address (LSB first!)
  */
-int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
+static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
 {
        int ret;
        u8 addr = reg & 0x7f;
@@ -268,16 +268,91 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
        return 0;
 }
 
+int em28xx_set_audio_source(struct em28xx *dev)
+{
+       static char *enable  = "\x08\x08";
+       static char *disable = "\x08\x88";
+       char *video = enable, *line = disable;
+       int ret, no_ac97;
+       u8 input;
+
+       if (dev->is_em2800) {
+               if (dev->ctl_ainput)
+                       input = EM2800_AUDIO_SRC_LINE;
+               else
+                       input = EM2800_AUDIO_SRC_TUNER;
+
+               ret = em28xx_write_regs(dev, EM2800_AUDIOSRC_REG, &input, 1);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (dev->has_msp34xx)
+               input = EM28XX_AUDIO_SRC_TUNER;
+       else {
+               switch (dev->ctl_ainput) {
+               case EM28XX_AMUX_VIDEO:
+                       input = EM28XX_AUDIO_SRC_TUNER;
+                       no_ac97 = 1;
+                       break;
+               case EM28XX_AMUX_LINE_IN:
+                       input = EM28XX_AUDIO_SRC_LINE;
+                       no_ac97 = 1;
+                       break;
+               case EM28XX_AMUX_AC97_VIDEO:
+                       input = EM28XX_AUDIO_SRC_LINE;
+                       break;
+               case EM28XX_AMUX_AC97_LINE_IN:
+                       input = EM28XX_AUDIO_SRC_LINE;
+                       video = disable;
+                       line  = enable;
+                       break;
+               }
+       }
+
+       ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
+       if (ret < 0)
+               return ret;
+
+       if (no_ac97)
+               return 0;
+
+       /* Sets AC97 mixer registers */
+
+       ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
+       if (ret < 0)
+               return ret;
+
+       ret = em28xx_write_ac97(dev, LINE_IN_AC97, line);
+
+       return ret;
+}
+
 int em28xx_audio_analog_set(struct em28xx *dev)
 {
+       int ret;
        char s[2] = { 0x00, 0x00 };
+
        s[0] |= 0x1f - dev->volume;
        s[1] |= 0x1f - dev->volume;
+
        if (dev->mute)
                s[1] |= 0x80;
-       return em28xx_write_ac97(dev, MASTER_AC97, s);
-}
+       ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+       if (ret < 0)
+               return ret;
 
+       ret = em28xx_write_reg_bits(dev, XCLK_REG,
+                                   dev->mute ? 0x00 : 0x80, 0x80);
+       if (ret < 0)
+               return ret;
+
+       /* Selects the proper audio input */
+       ret = em28xx_set_audio_source(dev);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
 
 int em28xx_colorlevels_set_default(struct em28xx *dev)
 {
index c2901f13eb2583eada0a99ebb8696305e8a0651e..1a284cb18c24a69b80a57b67ab14c562e66fc4db 100644 (file)
@@ -122,11 +122,13 @@ static int em28xx_config(struct em28xx *dev)
 /*     em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */
        em28xx_write_regs_req(dev,0x00,0x11,"\x51",1);
 
-       em28xx_audio_usb_mute(dev, 1);
        dev->mute = 1;          /* maybe not the right place... */
        dev->volume = 0x1f;
+
+       /* Init XCLK_REG, audio muted */
+       dev->em28xx_write_regs(dev, XCLK_REG, "\x87", 1);
+
        em28xx_audio_analog_set(dev);
-       em28xx_audio_analog_setup(dev);
        em28xx_outfmt_set_yuv422(dev);
        em28xx_colorlevels_set_default(dev);
        em28xx_compression_disable(dev);
@@ -168,7 +170,6 @@ static void em28xx_empty_framequeues(struct em28xx *dev)
 
 static void video_mux(struct em28xx *dev, int index)
 {
-       int ainput;
        struct v4l2_routing route;
 
        route.input = INPUT(index)->vmux;
@@ -185,18 +186,9 @@ static void video_mux(struct em28xx *dev, int index)
                route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
                /* Note: this is msp3400 specific */
                em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
-               ainput = EM28XX_AUDIO_SRC_TUNER;
-               em28xx_audio_source(dev, ainput);
-       } else {
-               switch (dev->ctl_ainput) {
-                       case 0:
-                               ainput = EM28XX_AUDIO_SRC_TUNER;
-                               break;
-                       default:
-                               ainput = EM28XX_AUDIO_SRC_LINE;
-               }
-               em28xx_audio_source(dev, ainput);
        }
+
+       em28xx_set_audio_source(dev);
 }
 
 /* Usage lock check functions */
@@ -292,7 +284,6 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
        case V4L2_CID_AUDIO_MUTE:
                if (ctrl->value != dev->mute) {
                        dev->mute = ctrl->value;
-                       em28xx_audio_usb_mute(dev, ctrl->value);
                        return em28xx_audio_analog_set(dev);
                }
                return 0;
index 93007cc72f4d0f907b877656ed11a457a682e1a5..abde13ecb4a8a5209de3b0377c3cb987fdec61be 100644 (file)
@@ -151,10 +151,17 @@ enum enum28xx_itype {
        EM28XX_RADIO,
 };
 
+enum em28xx_amux {
+       EM28XX_AMUX_VIDEO,
+       EM28XX_AMUX_LINE_IN,
+       EM28XX_AMUX_AC97_VIDEO,
+       EM28XX_AMUX_AC97_LINE_IN,
+};
+
 struct em28xx_input {
        enum enum28xx_itype type;
        unsigned int vmux;
-       unsigned int amux;
+       enum em28xx_amux amux;
 };
 
 #define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
@@ -321,8 +328,9 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
 int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
                          u8 bitmask);
-int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val);
+int em28xx_set_audio_source(struct em28xx *dev);
 int em28xx_audio_analog_set(struct em28xx *dev);
+
 int em28xx_colorlevels_set_default(struct em28xx *dev);
 int em28xx_capture_start(struct em28xx *dev, int start);
 int em28xx_outfmt_set_yuv422(struct em28xx *dev);
@@ -394,6 +402,7 @@ extern const unsigned int em28xx_bcount;
 
 /* em202 registers */
 #define MASTER_AC97    0x02
+#define LINE_IN_AC97    0x10
 #define VIDEO_AC97     0x14
 
 /* register settings */
@@ -418,28 +427,6 @@ extern const unsigned int em28xx_bcount;
        printk(KERN_WARNING "%s: "fmt,\
                        dev->name , ##arg); } while (0)
 
-inline static int em28xx_audio_source(struct em28xx *dev, int input)
-{
-       if(dev->is_em2800){
-               u8 tmp = EM2800_AUDIO_SRC_TUNER;
-               if(input == EM28XX_AUDIO_SRC_LINE)
-                       tmp = EM2800_AUDIO_SRC_LINE;
-               em28xx_write_regs(dev, EM2800_AUDIOSRC_REG, &tmp, 1);
-       }
-       return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
-}
-
-inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute)
-{
-       return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80);
-}
-
-inline static int em28xx_audio_analog_setup(struct em28xx *dev)
-{
-       /* unmute video mixer with default volume level */
-       return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08");
-}
-
 inline static int em28xx_compression_disable(struct em28xx *dev)
 {
        /* side effect of disabling scaler and mixer */