From: Devin Heitmueller Date: Wed, 19 Nov 2008 11:22:28 +0000 (-0300) Subject: V4L/DVB (9648): em28xx: get audio config from em28xx register X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=5c2231c84304563fd5d28e8bbb72e09e882a8e32;p=linux-beck.git V4L/DVB (9648): em28xx: get audio config from em28xx register Make use of the em28xx chip configuration register to determine whether we have AC97 audio, I2S audio, or no audio support at all. Thanks for Ray Lu from Empia for providing the em2860/em2880 datasheet. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- 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 */