Skip to content

Commit

Permalink
V4L/DVB (6947): Improve audio setup handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mauro Carvalho Chehab committed Jan 25, 2008
1 parent 6596a4f commit 539c96d
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 42 deletions.
81 changes: 78 additions & 3 deletions drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
{
Expand Down
21 changes: 6 additions & 15 deletions drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down
35 changes: 11 additions & 24 deletions drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand All @@ -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 */
Expand Down

0 comments on commit 539c96d

Please sign in to comment.