summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h10
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c35
-rw-r--r--drivers/media/video/em28xx/em28xx.h8
3 files changed, 52 insertions, 1 deletions
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 491d66abe7f7..12c9132b099e 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -17,6 +17,16 @@
/* em28xx registers */
+#define EM28XX_R00_CHIPCFG 0x00
+
+/* em28xx Chip Configuration 0x00 */
+#define EM28XX_CHIPCFG_VENDOR_AUDIO 0x80
+#define EM28XX_CHIPCFG_I2S_VOLUME_CAPABLE 0x40
+#define EM28XX_CHIPCFG_I2S_3_SAMPRATES 0x30
+#define EM28XX_CHIPCFG_I2S_5_SAMPRATES 0x20
+#define EM28XX_CHIPCFG_AC97 0x10
+#define EM28XX_CHIPCFG_AUDIOMASK 0x30
+
/* GPIO/GPO registers */
#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 154a99c61ee6..1e26061116ea 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1933,16 +1933,49 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
int em28xx_supports_audio_extension(struct em28xx *dev)
{
+ int rc;
+
/* The chip dictates whether we support the Empia analog audio
extension */
switch (dev->chip_id) {
case CHIP_ID_EM2874:
- /* Either a digital-only device or provides AC97 audio */
+ /* Digital only device - no analog support */
+ dev->audio_mode = EM28XX_NO_AUDIO;
return 0;
+ case CHIP_ID_EM2860:
case CHIP_ID_EM2883:
default:
+ /* See how this device is configured */
+ rc = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
+ if (rc & EM28XX_CHIPCFG_VENDOR_AUDIO) {
+ switch(rc & EM28XX_CHIPCFG_AUDIOMASK) {
+ case EM28XX_CHIPCFG_AC97:
+ em28xx_info("AC97 audio (5 sample rates)\n");
+ dev->audio_mode = EM28XX_AC97;
+ break;
+ case EM28XX_CHIPCFG_I2S_3_SAMPRATES:
+ em28xx_info("I2S Audio (3 sample rates)\n");
+ dev->audio_mode = EM28XX_I2S_3_SAMPLE_RATES;
+ break;
+ case EM28XX_CHIPCFG_I2S_5_SAMPRATES:
+ em28xx_info("I2S Audio (5 sample rates)\n");
+ dev->audio_mode = EM28XX_I2S_5_SAMPLE_RATES;
+ break;
+ default:
+ em28xx_info("No audio support detected\n");
+ dev->audio_mode = EM28XX_NO_AUDIO;
+ return 0;
+ }
+ } else {
+ em28xx_info("USB Audio class device\n");
+ return 0;
+ }
+ /* The em28xx audio extension needs to be loaded */
return 1;
}
+
+ /* We should never reach this point */
+ return 0;
}
static int register_analog_devices(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 3152d00e548b..f47c8d34ec79 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -256,6 +256,13 @@ enum enum28xx_itype {
EM28XX_RADIO,
};
+enum em28xx_audio_mode {
+ EM28XX_NO_AUDIO,
+ EM28XX_I2S_3_SAMPLE_RATES,
+ EM28XX_I2S_5_SAMPLE_RATES,
+ EM28XX_AC97,
+};
+
enum em28xx_amux {
EM28XX_AMUX_VIDEO,
EM28XX_AMUX_LINE_IN,
@@ -403,6 +410,7 @@ struct em28xx {
u32 i2s_speed; /* I2S speed for audio digital stream */
enum em28xx_decoder decoder;
+ enum em28xx_audio_mode audio_mode;
int tuner_type; /* type of the tuner */
int tuner_addr; /* tuner address */