The patch number 9692 was added via Jean-Francois Moine <[EMAIL PROTECTED]> to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward compatible with older kernels. Compatibility modifications will be removed before inclusion into the mainstream Kernel If anyone has any objections, please let us know by sending a message to: [EMAIL PROTECTED] ------ merge: v4l-dvb --- linux/drivers/media/video/em28xx/em28xx-cards.c | 3 linux/drivers/media/video/em28xx/em28xx-core.c | 56 ++++++++------- linux/drivers/media/video/em28xx/em28xx-reg.h | 58 ++++++++++++++-- linux/drivers/media/video/em28xx/em28xx-video.c | 9 +- linux/drivers/media/video/em28xx/em28xx.h | 5 + 5 files changed, 96 insertions(+), 35 deletions(-) diff -r 3b263849cc22 -r 9c6590d84b52 linux/drivers/media/video/em28xx/em28xx-cards.c --- a/linux/drivers/media/video/em28xx/em28xx-cards.c Wed Nov 19 10:37:53 2008 +0100 +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c Wed Nov 19 11:36:49 2008 +0100 @@ -1360,6 +1360,9 @@ void em28xx_pre_card_setup(struct em28xx if (rc > 0) { dev->chip_id = rc; switch (rc) { + case CHIP_ID_EM2750: + em28xx_info("chip ID is em2750\n"); + break; case CHIP_ID_EM2820: em28xx_info("chip ID is em2820\n"); break; diff -r 3b263849cc22 -r 9c6590d84b52 linux/drivers/media/video/em28xx/em28xx-core.c --- a/linux/drivers/media/video/em28xx/em28xx-core.c Wed Nov 19 10:37:53 2008 +0100 +++ b/linux/drivers/media/video/em28xx/em28xx-core.c Wed Nov 19 11:36:49 2008 +0100 @@ -69,19 +69,29 @@ int em28xx_read_reg_req_len(struct em28x int ret, byte; if (dev->state & DEV_DISCONNECTED) - return(-ENODEV); + return -ENODEV; + + if (len > URB_MAX_CTRL_SIZE) + return -EINVAL; em28xx_regdbg("req=%02x, reg=%02x ", req, reg); ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, buf, len, HZ); + 0x0000, reg, dev->urb_buf, len, HZ); + if (ret < 0) { + if (reg_debug) + printk(" failed!\n"); + return ret; + } + + if (len) + memcpy(buf, dev->urb_buf, len); if (reg_debug) { - printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); + printk("%02x values: ", ret); for (byte = 0; byte < len; byte++) printk(" %02x", (unsigned char)buf[byte]); - printk("\n"); } @@ -104,14 +114,16 @@ int em28xx_read_reg_req(struct em28xx *d ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, &val, 1, HZ); + 0x0000, reg, dev->urb_buf, 1, HZ); + if (ret < 0) { + printk(" failed!\n"); + return ret; + } + + val = dev->urb_buf[0]; if (reg_debug) - printk(ret < 0 ? " failed!\n" : - "%02x\n", (unsigned char) val); - - if (ret < 0) - return ret; + printk("%02x\n", (unsigned char) val); return val; } @@ -130,19 +142,13 @@ int em28xx_write_regs_req(struct em28xx { int ret; - /*usb_control_msg seems to expect a kmalloced buffer */ - unsigned char *bufs; - if (dev->state & DEV_DISCONNECTED) return -ENODEV; - if (len < 1) + if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) return -EINVAL; - bufs = kmalloc(len, GFP_KERNEL); - em28xx_regdbg("req=%02x reg=%02x:", req, reg); - if (reg_debug) { int i; for (i = 0; i < len; ++i) @@ -150,16 +156,14 @@ int em28xx_write_regs_req(struct em28xx printk("\n"); } - if (!bufs) - return -ENOMEM; - memcpy(bufs, buf, len); + memcpy(dev->urb_buf, buf, len); ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, bufs, len, HZ); + 0x0000, reg, dev->urb_buf, len, HZ); + if (dev->wait_after_write) msleep(dev->wait_after_write); - kfree(bufs); return ret; } @@ -292,11 +296,11 @@ static int em28xx_set_audio_source(struc /* Sets AC97 mixer registers This is seems to be needed, even for non-ac97 configs */ - ret = em28xx_write_ac97(dev, EM28XX_R14_VIDEO_AC97, video); + ret = em28xx_write_ac97(dev, AC97_VIDEO_VOL, video); if (ret < 0) return ret; - ret = em28xx_write_ac97(dev, EM28XX_R10_LINE_IN_AC97, line); + ret = em28xx_write_ac97(dev, AC97_LINEIN_VOL, line); return ret; } @@ -312,7 +316,7 @@ int em28xx_audio_analog_set(struct em28x /* Mute */ s[1] |= 0x80; - ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); + ret = em28xx_write_ac97(dev, AC97_MASTER_VOL, s); if (ret < 0) return ret; @@ -334,7 +338,7 @@ int em28xx_audio_analog_set(struct em28x /* Unmute device */ if (!dev->mute) s[1] &= ~0x80; - ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); + ret = em28xx_write_ac97(dev, AC97_MASTER_VOL, s); return ret; } diff -r 3b263849cc22 -r 9c6590d84b52 linux/drivers/media/video/em28xx/em28xx-reg.h --- a/linux/drivers/media/video/em28xx/em28xx-reg.h Wed Nov 19 10:37:53 2008 +0100 +++ b/linux/drivers/media/video/em28xx/em28xx-reg.h Wed Nov 19 11:36:49 2008 +0100 @@ -78,11 +78,6 @@ 0x47 IR data */ -/* em202 registers */ -#define EM28XX_R02_MASTER_AC97 0x02 -#define EM28XX_R10_LINE_IN_AC97 0x10 -#define EM28XX_R14_VIDEO_AC97 0x14 - /* em2874 registers */ #define EM2874_R50_IR_CONFIG 0x50 #define EM2874_R51_IR 0x51 @@ -113,7 +108,60 @@ enum em28xx_chip_id { enum em28xx_chip_id { CHIP_ID_EM2820 = 18, CHIP_ID_EM2840 = 20, + CHIP_ID_EM2750 = 33, CHIP_ID_EM2860 = 34, CHIP_ID_EM2883 = 36, CHIP_ID_EM2874 = 65, }; + +/* + * Registers used by em202 and other AC97 chips + */ + +/* Standard AC97 registers */ +#define AC97_RESET 0x00 +#define AC97_MASTER_VOL 0x02 +#define AC97_LINE_LEVEL_VOL 0x04 +#define AC97_MASTER_MONO_VOL 0x06 + +#define AC97_PC_BEEP_VOL 0x0a +#define AC97_PHONE_VOL 0x0c +#define AC97_MIC_VOL 0x0e +#define AC97_LINEIN_VOL 0x10 +#define AC97_CD_VOL 0x12 +#define AC97_VIDEO_VOL 0x14 +#define AC97_AUX_VOL 0x16 +#define AC97_PCM_OUT_VOL 0x18 +#define AC97_RECORD_SELECT 0x1a +#define AC97_RECORD_GAIN 0x1c +#define AC97_GENERAL_PURPOSE 0x20 +#define AC97_3D_CTRL 0x22 +#define AC97_AUD_INT_AND_PAG 0x24 +#define AC97_POWER_DOWN_CTRL 0x26 +#define AC97_EXT_AUD_ID 0x28 +#define AC97_EXT_AUD_CTRL 0x2a + +/* Supported rate varies for each AC97 device + if write an unsupported value, it will return the closest one + */ +#define AC97_PCM_OUT_FRONT_SRATE 0x2c +#define AC97_PCM_OUT_SURR_SRATE 0x2e +#define AC97_PCM_OUT_LFE_SRATE 0x30 +#define AC97_PCM_IN_SRATE 0x32 +#define AC97_LFE_MASTER_VOL 0x36 +#define AC97_SURR_MASTER_VOL 0x38 +#define AC97_SPDIF_OUT_CTRL 0x3a + +#define AC97_VENDOR_ID1 0x7c +#define AC97_VENDOR_ID2 0x7e + +/* EMP202 vendor registers */ +#define EM202_EXT_MODEM_CTRL 0x3e +#define EM202_GPIO_CONF 0x4c +#define EM202_GPIO_POLARITY 0x4e +#define EM202_GPIO_STICKY 0x50 +#define EM202_GPIO_MASK 0x52 +#define EM202_GPIO_STATUS 0x54 +#define EM202_SPDIF_OUT_SEL 0x6a +#define EM202_ANTIPOP 0x72 +#define EM202_EAPD_GPIO_ACCESS 0x74 diff -r 3b263849cc22 -r 9c6590d84b52 linux/drivers/media/video/em28xx/em28xx-video.c --- a/linux/drivers/media/video/em28xx/em28xx-video.c Wed Nov 19 10:37:53 2008 +0100 +++ b/linux/drivers/media/video/em28xx/em28xx-video.c Wed Nov 19 11:36:49 2008 +0100 @@ -2034,8 +2034,6 @@ static int em28xx_init_dev(struct em28xx errCode = em28xx_config(dev); if (errCode) { em28xx_errdev("error configuring device\n"); - em28xx_devused &= ~(1<<dev->devno); - kfree(dev); return -ENOMEM; } @@ -2172,7 +2170,6 @@ fail_unreg: fail_unreg: em28xx_release_resources(dev); mutex_unlock(&dev->lock); - kfree(dev); return retval; } @@ -2333,8 +2330,12 @@ static int em28xx_usb_probe(struct usb_i /* allocate device struct */ retval = em28xx_init_dev(&dev, udev, nr); - if (retval) + if (retval) { + em28xx_devused &= ~(1<<dev->devno); + kfree(dev); + return retval; + } em28xx_info("Found %s\n", em28xx_boards[dev->model].name); diff -r 3b263849cc22 -r 9c6590d84b52 linux/drivers/media/video/em28xx/em28xx.h --- a/linux/drivers/media/video/em28xx/em28xx.h Wed Nov 19 10:37:53 2008 +0100 +++ b/linux/drivers/media/video/em28xx/em28xx.h Wed Nov 19 11:36:49 2008 +0100 @@ -104,6 +104,9 @@ #define EM28XX_MIN_BUF 4 #define EM28XX_DEF_BUF 8 +/*Limits the max URB message size */ +#define URB_MAX_CTRL_SIZE 80 + /* Params for validated field */ #define EM28XX_BOARD_NOT_VALIDATED 1 #define EM28XX_BOARD_VALIDATED 0 @@ -468,6 +471,8 @@ struct em28xx { unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ + char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ + /* helper funcs that call usb_control_msg */ int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, char *buf, int len); --- Patch is available at: http://linuxtv.org/hg/v4l-dvb/rev/9c6590d84b5203c69556ccd671f5da0a3116b397 _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits