From fde60748d2f0345cabff20d25458c67d4ac06034 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 5 Jun 2008 18:59:08 -0300 Subject: [PATCH 01/42] V4L/DVB (8004): Fix INPUT dependency at budget-ci As reported by Ingo Molnar: MODPOST 346 modules ERROR: "input_free_device" [drivers/media/dvb/ttpci/budget-ci.ko] undefined! ERROR: "input_register_device" [drivers/media/dvb/ttpci/budget-ci.ko] undefined! ERROR: "input_allocate_device" [drivers/media/dvb/ttpci/budget-ci.ko] undefined! ERROR: "input_unregister_device" [drivers/media/dvb/ttpci/budget-ci.ko] undefined! ERROR: "input_event" [drivers/media/common/ir-common.ko] undefined! This occurs when: CONFIG_INPUT=n CONFIG_VIDEO_IR=m CONFIG_DVB_BUDGET_CI=m Thanks-to: Ingo Molnar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index d4339b1b3b68..07643e010093 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -101,6 +101,7 @@ config DVB_BUDGET config DVB_BUDGET_CI tristate "Budget cards with onboard CI connector" depends on DVB_BUDGET_CORE && I2C + depends on INPUT # due to IR select DVB_STV0297 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE From bf67cac1314ba29676fbac2decde0e2e0a8170f8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 7 Jun 2008 15:54:10 -0300 Subject: [PATCH 02/42] V4L/DVB (8005): Fix OOPS if frontend is null Thanks to timf and Mike Galbraith to report this issue. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-dvb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 469f93aac008..726f01ccedf0 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1338,7 +1338,8 @@ static int dvb_init(struct saa7134_dev *dev) return ret; dettach_frontend: - dvb_frontend_detach(dev->dvb.frontend); + if (dev->dvb.frontend) + dvb_frontend_detach(dev->dvb.frontend); dev->dvb.frontend = NULL; return -1; From 45270a1531a2aa90dd890666913c25a1e6f5e8eb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Jun 2008 11:18:17 -0300 Subject: [PATCH 03/42] V4L/DVB (8007): cx18/cx25840: the S-Video LUMA input can use all In1-In8 inputs The S-Video LUMA input was restricted to the In1-In4 inputs, but it turns out that it can use the full range of In1-In8. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 2 +- drivers/media/video/cx18/cx18-av-core.h | 6 +++++- drivers/media/video/cx25840/cx25840-core.c | 2 +- include/media/cx25840.h | 6 +++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 9a26751615c6..8f2959ae7cab 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -228,7 +228,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, if ((vid_input & ~0xff0) || luma < CX18_AV_SVIDEO_LUMA1 || - luma > CX18_AV_SVIDEO_LUMA4 || + luma > CX18_AV_SVIDEO_LUMA8 || chroma < CX18_AV_SVIDEO_CHROMA4 || chroma > CX18_AV_SVIDEO_CHROMA8) { CX18_ERR("0x%04x is not a valid video input!\n", diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 786901d72e9a..39f3c9397158 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -37,12 +37,16 @@ enum cx18_av_video_input { CX18_AV_COMPOSITE7, CX18_AV_COMPOSITE8, - /* S-Video inputs consist of one luma input (In1-In4) ORed with one + /* S-Video inputs consist of one luma input (In1-In8) ORed with one chroma input (In5-In8) */ CX18_AV_SVIDEO_LUMA1 = 0x10, CX18_AV_SVIDEO_LUMA2 = 0x20, CX18_AV_SVIDEO_LUMA3 = 0x30, CX18_AV_SVIDEO_LUMA4 = 0x40, + CX18_AV_SVIDEO_LUMA5 = 0x50, + CX18_AV_SVIDEO_LUMA6 = 0x60, + CX18_AV_SVIDEO_LUMA7 = 0x70, + CX18_AV_SVIDEO_LUMA8 = 0x80, CX18_AV_SVIDEO_CHROMA4 = 0x400, CX18_AV_SVIDEO_CHROMA5 = 0x500, CX18_AV_SVIDEO_CHROMA6 = 0x600, diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 607efdcd22f8..1da6f134888d 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -433,7 +433,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp int chroma = vid_input & 0xf00; if ((vid_input & ~0xff0) || - luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 || + luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { v4l_err(client, "0x%04x is not a valid video input!\n", vid_input); diff --git a/include/media/cx25840.h b/include/media/cx25840.h index cd599ad29fb2..db431d513f2f 100644 --- a/include/media/cx25840.h +++ b/include/media/cx25840.h @@ -32,12 +32,16 @@ enum cx25840_video_input { CX25840_COMPOSITE7, CX25840_COMPOSITE8, - /* S-Video inputs consist of one luma input (In1-In4) ORed with one + /* S-Video inputs consist of one luma input (In1-In8) ORed with one chroma input (In5-In8) */ CX25840_SVIDEO_LUMA1 = 0x10, CX25840_SVIDEO_LUMA2 = 0x20, CX25840_SVIDEO_LUMA3 = 0x30, CX25840_SVIDEO_LUMA4 = 0x40, + CX25840_SVIDEO_LUMA5 = 0x50, + CX25840_SVIDEO_LUMA6 = 0x60, + CX25840_SVIDEO_LUMA7 = 0x70, + CX25840_SVIDEO_LUMA8 = 0x80, CX25840_SVIDEO_CHROMA4 = 0x400, CX25840_SVIDEO_CHROMA5 = 0x500, CX25840_SVIDEO_CHROMA6 = 0x600, From d3d9b803eead0a536d28ffc31c5fadae976991cc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 8 Jun 2008 06:05:18 -0300 Subject: [PATCH 04/42] V4L/DVB (8008): cx18: remove duplicate audio and video input enums cx18-cards.h had a copy of the audio and video input enums from cx18-av-core.h, but with different prefixes. Removed that copy and used the ones from cx18-av-core.h. Thanks to Andy Walls for the report. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 61 ++++++++++++++------------- drivers/media/video/cx18/cx18-cards.h | 40 ------------------ 2 files changed, 31 insertions(+), 70 deletions(-) diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index baccd079243d..c35eb53a34c6 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -23,6 +23,7 @@ #include "cx18-driver.h" #include "cx18-cards.h" +#include "cx18-av-core.h" #include "cx18-i2c.h" #include @@ -54,22 +55,22 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, - { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, + { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, + CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, { CX18_CARD_INPUT_LINE_IN1, - CX23418_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX23418_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, 0 }, .ddr = { /* ESMT M13S128324A-5B memory */ .chip_config = 0x003, @@ -94,22 +95,22 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, - { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, + { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, + CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, { CX18_CARD_INPUT_LINE_IN1, - CX23418_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX23418_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, 0 }, .ddr = { /* Samsung K4D263238G-VC33 memory */ .chip_config = 0x003, @@ -141,19 +142,19 @@ static const struct cx18_card cx18_card_h900 = { .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, { CX18_CARD_INPUT_SVIDEO1, 1, - CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 }, + CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO8, 0 }, + CX18_AV_AUDIO8, 0 }, { CX18_CARD_INPUT_LINE_IN1, - CX23418_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, 0 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, 0 }, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, @@ -188,18 +189,18 @@ static const struct cx18_card cx18_card_mpc718 = { .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO8, 0 }, + CX18_AV_AUDIO8, 0 }, { CX18_CARD_INPUT_LINE_IN1, - CX23418_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, 0 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX23418_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, 0 }, .tuners = { /* XC3028 tuner */ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index bccb67f0db16..3c2c0b92956c 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -36,36 +36,6 @@ #define CX18_CARD_INPUT_COMPOSITE2 5 #define CX18_CARD_INPUT_COMPOSITE3 6 -enum cx34180_video_input { - /* Composite video inputs In1-In8 */ - CX23418_COMPOSITE1 = 1, - CX23418_COMPOSITE2, - CX23418_COMPOSITE3, - CX23418_COMPOSITE4, - CX23418_COMPOSITE5, - CX23418_COMPOSITE6, - CX23418_COMPOSITE7, - CX23418_COMPOSITE8, - - /* S-Video inputs consist of one luma input (In1-In4) ORed with one - chroma input (In5-In8) */ - CX23418_SVIDEO_LUMA1 = 0x10, - CX23418_SVIDEO_LUMA2 = 0x20, - CX23418_SVIDEO_LUMA3 = 0x30, - CX23418_SVIDEO_LUMA4 = 0x40, - CX23418_SVIDEO_CHROMA4 = 0x400, - CX23418_SVIDEO_CHROMA5 = 0x500, - CX23418_SVIDEO_CHROMA6 = 0x600, - CX23418_SVIDEO_CHROMA7 = 0x700, - CX23418_SVIDEO_CHROMA8 = 0x800, - - /* S-Video aliases for common luma/chroma combinations */ - CX23418_SVIDEO1 = 0x510, - CX23418_SVIDEO2 = 0x620, - CX23418_SVIDEO3 = 0x730, - CX23418_SVIDEO4 = 0x840, -}; - /* audio inputs */ #define CX18_CARD_INPUT_AUD_TUNER 1 #define CX18_CARD_INPUT_LINE_IN1 2 @@ -75,16 +45,6 @@ enum cx34180_video_input { #define CX18_CARD_MAX_AUDIO_INPUTS 3 #define CX18_CARD_MAX_TUNERS 2 -enum cx23418_audio_input { - /* Audio inputs: serial or In4-In8 */ - CX23418_AUDIO_SERIAL, - CX23418_AUDIO4 = 4, - CX23418_AUDIO5, - CX23418_AUDIO6, - CX23418_AUDIO7, - CX23418_AUDIO8, -}; - /* V4L2 capability aliases */ #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE) From 0367ca1bc7346d9ea89a4b4f1b9220489bda65a3 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 9 Jun 2008 14:58:04 -0300 Subject: [PATCH 05/42] V4L/DVB (8010): em28xx: Properly register extensions for already attached devices em28xx-video.c - Properly handle loading of the module when multiple devices are already connected (such as at bootup). Before we were only calling dvb_init() against the last device in the list, so while we were handling subsequent adds properly, if there were multiple devices present on driver load, everybody except the last device would not get initialized. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 24 ++++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index fb163ecd9216..285bc62bbe46 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1848,32 +1848,28 @@ static DEFINE_MUTEX(em28xx_extension_devlist_lock); int em28xx_register_extension(struct em28xx_ops *ops) { - struct em28xx *h, *dev = NULL; - - list_for_each_entry(h, &em28xx_devlist, devlist) - dev = h; + struct em28xx *dev = NULL; mutex_lock(&em28xx_extension_devlist_lock); list_add_tail(&ops->next, &em28xx_extension_devlist); - if (dev) - ops->init(dev); - + list_for_each_entry(dev, &em28xx_devlist, devlist) { + if (dev) + ops->init(dev); + } printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); mutex_unlock(&em28xx_extension_devlist_lock); - return 0; } EXPORT_SYMBOL(em28xx_register_extension); void em28xx_unregister_extension(struct em28xx_ops *ops) { - struct em28xx *h, *dev = NULL; + struct em28xx *dev = NULL; - list_for_each_entry(h, &em28xx_devlist, devlist) - dev = h; - - if (dev) - ops->fini(dev); + list_for_each_entry(dev, &em28xx_devlist, devlist) { + if (dev) + ops->fini(dev); + } mutex_lock(&em28xx_extension_devlist_lock); printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); From b38cc642000f0a262db367ffb95cd02ca2ead59b Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 9 Jun 2008 14:59:05 -0300 Subject: [PATCH 06/42] V4L/DVB (8011): em28xx: enable DVB for HVR-900 em28xx-cards.c - DVB support is supposed to be enabled for the first generation HVR-900. This device was confirmed with DVB by mkrufky when we did the original work in April, but I guess we forgot to set the flag. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 3e4f3c7e92e7..5cf71582e3a2 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -157,6 +157,7 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .mts_firmware = 1, + .has_dvb = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, From f56ebe16b045861d26b81ef6683445c0144362b8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 28 May 2008 21:55:06 -0300 Subject: [PATCH 07/42] V4L/DVB (8012): gl861: sleep a little to avoid I2C errors - add little sleep to avoid I2C errors arising on faster CPUs Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/gl861.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index 0a8ac64a4e33..10cc436b0654 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c @@ -47,6 +47,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, return -EINVAL; } + msleep(0); /* avoid I2C errors */ + return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, value, index, rbuf, rlen, 2000); } From ea3a13b7a19f0d7d7344494047c9aa8bb32b6678 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 28 May 2008 22:04:12 -0300 Subject: [PATCH 08/42] V4L/DVB (8013): gl861: remove useless identify_state - remove useless identify_state - device is always warm Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/gl861.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index 10cc436b0654..9e53650ac9d3 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c @@ -94,16 +94,6 @@ static struct i2c_algorithm gl861_i2c_algo = { }; /* Callbacks for DVB USB */ -static int gl861_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - *cold = 0; - - return 0; -} - static struct zl10353_config gl861_zl10353_config = { .demod_address = 0x0f, .no_tuner = 1, @@ -174,7 +164,6 @@ static struct dvb_usb_device_properties gl861_properties = { .size_of_priv = 0, - .identify_state = gl861_identify_state, .num_adapters = 1, .adapter = {{ @@ -196,13 +185,15 @@ static struct dvb_usb_device_properties gl861_properties = { .num_device_descs = 2, .devices = { - { "MSI Mega Sky 55801 DVB-T USB2.0", - { &gl861_table[0], NULL }, - { NULL }, + { + .name = "MSI Mega Sky 55801 DVB-T USB2.0", + .cold_ids = { NULL }, + .warm_ids = { &gl861_table[0], NULL }, }, - { "A-LINK DTU DVB-T USB2.0", - { &gl861_table[1], NULL }, - { NULL }, + { + .name = "A-LINK DTU DVB-T USB2.0", + .cold_ids = { NULL }, + .warm_ids = { &gl861_table[1], NULL }, }, } }; From 1a78db826973b9fa658d72291ec2007889e2faf7 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 10 Jun 2008 11:41:58 -0300 Subject: [PATCH 09/42] V4L/DVB (8015): gl861: replace non critical msleep(0) with msleep(1) to be on the safe side - change msleep(0) to msleep(1) Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/gl861.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index 9e53650ac9d3..037f7ffb47b2 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c @@ -47,7 +47,7 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, return -EINVAL; } - msleep(0); /* avoid I2C errors */ + msleep(1); /* avoid I2C errors */ return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, value, index, rbuf, rlen, 2000); From df619181631217e3166bb6c7538f981e0272617f Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 10 Jun 2008 12:34:35 -0300 Subject: [PATCH 10/42] V4L/DVB (8017): Ensure em28xx extensions only get run against devs that support them em28xx-audio.c em28xx-dvb.c - Em28xx extensions should ensure they are being only loaded against devices that support them. Deals with case where there are multiple em28xx devices, some of which have DVB (or ALSA) support and some do not. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 12 ++++++++++++ drivers/media/video/em28xx/em28xx-dvb.c | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 92b2a6db4fdc..343dff0f8a04 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -415,6 +415,12 @@ static int em28xx_audio_init(struct em28xx *dev) static int devnr; int ret, err; + if (dev->has_audio_class) { + /* This device does not support the extension (in this case + the device is expecting the snd-usb-audio module */ + return 0; + } + printk(KERN_INFO "em28xx-audio.c: probing for em28x1 " "non standard usbaudio\n"); printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " @@ -458,6 +464,12 @@ static int em28xx_audio_fini(struct em28xx *dev) if (dev == NULL) return 0; + if (dev->has_audio_class) { + /* This device does not support the extension (in this case + the device is expecting the snd-usb-audio module */ + return 0; + } + if (dev->adev) { snd_card_free(dev->adev->sndcard); kfree(dev->adev); diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 8cf4983f0039..0b2333ee07f8 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -382,6 +382,11 @@ static int dvb_init(struct em28xx *dev) int result = 0; struct em28xx_dvb *dvb; + if (!dev->has_dvb) { + /* This device does not support the extension */ + return 0; + } + dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { @@ -444,6 +449,11 @@ out_free: static int dvb_fini(struct em28xx *dev) { + if (!dev->has_dvb) { + /* This device does not support the extension */ + return 0; + } + if (dev->dvb) { unregister_dvb(dev->dvb); dev->dvb = NULL; From a8a1f8cc0cae07c209f13857adbdd4b87b36cdde Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 10 Jun 2008 12:35:42 -0300 Subject: [PATCH 11/42] V4L/DVB (8018): Add em2860 chip ID em28xx-cards.c em28xx-reg.h - Add em2860 chip ID (seen on Pointnix Intra-Oral Camera) http://www.pointnix.com/ENG/dental/product_02.asp Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 3 +++ drivers/media/video/em28xx/em28xx-reg.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 5cf71582e3a2..8cbda43727c3 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -525,6 +525,9 @@ void em28xx_pre_card_setup(struct em28xx *dev) rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); if (rc > 0) { switch (rc) { + case CHIP_ID_EM2860: + em28xx_info("chip ID is em2860\n"); + break; case CHIP_ID_EM2883: em28xx_info("chip ID is em2882/em2883\n"); dev->wait_after_write = 0; diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index 9058bed07953..fac1ab23f621 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h @@ -84,5 +84,6 @@ /* FIXME: Need to be populated with the other chip ID's */ enum em28xx_chip_id { + CHIP_ID_EM2860 = 34, CHIP_ID_EM2883 = 36, }; From a14fe9605bfdfe360b97acc9ef912779eb860507 Mon Sep 17 00:00:00 2001 From: Dmitri Belimov Date: Tue, 10 Jun 2008 14:19:31 -0300 Subject: [PATCH 12/42] V4L/DVB (8020): Fix callbacks functions of saa7134_empress If I try v4l2-ctl --all -d /dev/video1 or v4l2-ctl --streamon -d /dev/video1 modules crashed: *pde = 00000000 Modules linked in: ac battery loop saa7134_empress(F) saa6752hs(F) tuner_simple(F) tuner_types(F) tea5767(F) tda9887(F) tda8290(F) tea5761(F) tuner(F) snd_cmipci snd_pcm snd_page_alloc snd_opl3_lib saa7134(F) snd_mpu401 parport_pc parport snd_timer snd_hwdep snd_mpu401_uart floppy rtc psmouse videodev(F) v4l1_compat(F) compat_ioctl32(F) v4l2_common(F) videobuf_dma_sg(F) videobuf_core(F) snd_rawmidi snd_seq_device via_ircc pcspkr snd ir_kbd_i2c(F) irda soundcore ir_common(F) crc_ccitt tveeprom(F) i2c_viapro i2c_core button via_agp agpgart evdev ext3 jbd mbcache ide_cd_mod cdrom ide_disk 8139cp via82cxxx ide_core 8139too mii ehci_hcd uhci_hcd usbcore thermal processor fan EIP is at __mutex_lock_slowpath+0x29/0x7b DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process v4l2-ctl (pid: 2742, ti=ced7e000 task=cf325260 task.ti=ced7e000) d08e5411 00000000 ced7fed4 00000000 d0975acb 40045612 cfa86ee0 ffffffcd cf2b7000 ced7febc c03858d6 00000019 00000292 d089e4ec cf37b2a0 d089e4a0 Call Trace: [] mutex_lock+0xa/0xb [] videobuf_streamon+0xf/0x9a [videobuf_core] [] __video_do_ioctl+0x136a/0x2d68 [videodev] [] task_end_request+0x40/0x51 [ide_core] [] ide_intr+0x187/0x192 [ide_core] [] mntput_no_expire+0x11/0x64 [] path_walk+0x90/0x98 [] video_ioctl2+0x173/0x239 [videodev] [] filemap_fault+0x202/0x370 [] __do_fault+0x2c3/0x2fe [] handle_mm_fault+0x22a/0x49f [] vfs_ioctl+0x47/0x5d [] do_vfs_ioctl+0x245/0x258 [] sys_ioctl+0x41/0x5b [] sysenter_past_esp+0x5f/0x85 ======================= After this fix all of that commands works without problem: v4l2-ctl --all -d /dev/video1 Driver Info: Driver name : saa7134 Card type : Beholder BeholdTV M6 Extra Bus info : PCI:0000:00:0d.0 Driver version: 526 Capabilities : 0x05000001 Video Capture Read/Write Streaming Format Video Capture: Width/Height : 720/576 Pixel Format : MPEG Field : Any Bytes per Line: 0 Size Image : 58656 Colorspace : Unknown (00000000) Video input : 0 (CCIR656) Video Standard = 0x000000ff PAL-B/B1/G/H/I/D/D1/K P.S. data from /dev/video1 is not correct :(( . Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-empress.c | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 81431ee41842..94b2585bdf5b 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -218,8 +218,7 @@ static int empress_enum_fmt_cap(struct file *file, void *priv, static int empress_g_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f); @@ -232,8 +231,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv, static int empress_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f); @@ -247,8 +245,7 @@ static int empress_s_fmt_cap(struct file *file, void *priv, static int empress_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; return videobuf_reqbufs(&dev->empress_tsq, p); } @@ -256,24 +253,21 @@ static int empress_reqbufs(struct file *file, void *priv, static int empress_querybuf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; return videobuf_querybuf(&dev->empress_tsq, b); } static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; return videobuf_qbuf(&dev->empress_tsq, b); } static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; return videobuf_dqbuf(&dev->empress_tsq, b, file->f_flags & O_NONBLOCK); @@ -282,8 +276,7 @@ static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) static int empress_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; return videobuf_streamon(&dev->empress_tsq); } @@ -291,8 +284,7 @@ static int empress_streamon(struct file *file, void *priv, static int empress_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; return videobuf_streamoff(&dev->empress_tsq); } @@ -300,8 +292,7 @@ static int empress_streamoff(struct file *file, void *priv, static int empress_s_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; /* count == 0 is abused in saa6752hs.c, so that special case is handled here explicitly. */ @@ -320,8 +311,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv, static int empress_g_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; + struct saa7134_dev *dev = file->private_data; if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; From 913f5fc209247b607b1994a710315966f4f9d358 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Tue, 10 Jun 2008 15:18:16 -0300 Subject: [PATCH 13/42] V4L/DVB (8022): saa7134: fix race between opening and closing the device decrementing dev->empress_users should be done as last action of ts_release, because it sleeps and write access to dev->empress_started is not protected in any way (additionally closing thread could mute audio after opening thread unmuted it) Signed-off-by: Marcin Slusarz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-empress.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 94b2585bdf5b..1c8cd0ef4a65 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -112,7 +112,6 @@ static int ts_release(struct inode *inode, struct file *file) videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); - dev->empress_users--; /* stop the encoder */ ts_reset_encoder(dev); @@ -121,6 +120,8 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); + dev->empress_users--; + return 0; } From 83ee87a31dc43a5fd6dee3562c146033c3a4cb39 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Jun 2008 09:41:18 -0300 Subject: [PATCH 14/42] V4L/DVB (8026): Avoids an OOPS if dev struct can't be successfully recovered On some alsa versions, it seems that snd_pcm_substream_chip(substream) is returning a NULL pointer. This causes an OOPS, as reported by: https://bugs.launchpad.net/ubuntu/+source/linux-ubuntu-modules-2.6.24/+bug/212271 https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/212960 This patch avoids the OOPS by not letting and open() succeed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-alsa.c | 6 ++++++ drivers/media/video/em28xx/em28xx-audio.c | 6 ++++++ drivers/media/video/saa7134/saa7134-alsa.c | 8 +++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index e976fc6bef7c..80c8883e54b5 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -332,6 +332,12 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; + if (!chip) { + printk(KERN_ERR "BUG: cx88 can't find device struct." + " Can't proceed with open\n"); + return -ENODEV; + } + err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) goto _error; diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 343dff0f8a04..3c006103c1eb 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -268,6 +268,12 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); + if (!dev) { + printk(KERN_ERR "BUG: em28xx can't find device struct." + " Can't proceed with open\n"); + return -ENODEV; + } + /* Sets volume, mute, etc */ dev->mute = 0; diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index ba3082422a01..f118de6e3672 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -613,9 +613,15 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) struct snd_pcm_runtime *runtime = substream->runtime; snd_card_saa7134_pcm_t *pcm; snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); - struct saa7134_dev *dev = saa7134->dev; + struct saa7134_dev *dev; int amux, err; + if (!saa7134) { + printk(KERN_ERR "BUG: saa7134 can't find device struct." + " Can't proceed with open\n"); + return -ENODEV; + } + dev = saa7134->dev; mutex_lock(&dev->dmasound.lock); dev->dmasound.read_count = 0; From b25fed115a8bd8d39d14ce0d03e808272a401d67 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Fri, 13 Jun 2008 19:28:17 -0300 Subject: [PATCH 15/42] V4L/DVB (8027): saa7134: Avermedia A700: only s-video and composite input are working Describe exactly that only s-video and composite input are working on Avermedia A700 Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index b111903aa322..21a761200548 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5615,7 +5615,8 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100); printk("%s: %s: hybrid analog/dvb card\n" - "%s: Sorry, only the analog inputs are supported for now.\n", + "%s: Sorry, only analog s-video and composite input " + "are supported for now.\n", dev->name, card(dev).name, dev->name); break; } From bc36ec746409e4e4719b94a86dc0d8cbeb6f439f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Jun 2008 10:44:04 -0300 Subject: [PATCH 16/42] V4L/DVB (8028): Improve error messages for tda1004x attach A fresh copy of v.29 firmware, using get_firmware, is leading to an invalid firmware: DVB: registering new adapter (saa7133[0]) DVB: registering frontend 0 (Philips TDA10046H DVB-T)... tda1004x: setting up plls for 48MHz sampling clock tda1004x: found firmware revision ff -- invalid tda1004x: trying to boot from eeprom tda1004x: found firmware revision ff -- invalid tda1004x: waiting for firmware upload... tda1004x: Error during firmware upload tda1004x: found firmware revision ff -- invalid tda1004x: firmware upload failed Sometimes, loading/unloading this firmware makes tda1004x to return an invalid ID. However, there were no printk messages to help to identify what were the cause for the error. With this patch, it will now print: Invalid tda1004x ID = 0xff. Can't proceed saa7133[0]/dvb: failed to attach tda10046 saa7133[0]/dvb: frontend initialization failed Tested with LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda1004x.c | 18 ++++++++++++++---- drivers/media/video/saa7134/saa7134-dvb.c | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 49973846373e..3993d1ce334a 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -1248,11 +1248,14 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; + u8 id; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) + if (!state) { + printk(KERN_ERR "Can't alocate memory for tda10045 state\n"); return NULL; + } /* setup the state */ state->config = config; @@ -1260,7 +1263,9 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ - if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { + id = tda1004x_read_byte(state, TDA1004X_CHIPID); + if (id != 0x25) { + printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); kfree(state); return NULL; } @@ -1307,11 +1312,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; + u8 id; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) + if (!state) { + printk(KERN_ERR "Can't alocate memory for tda10046 state\n"); return NULL; + } /* setup the state */ state->config = config; @@ -1319,7 +1327,9 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ - if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { + id = tda1004x_read_byte(state, TDA1004X_CHIPID); + if (id != 0x46) { + printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); kfree(state); return NULL; } diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 726f01ccedf0..653107c83803 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1091,7 +1091,8 @@ static int dvb_init(struct saa7134_dev *dev) ads_tech_duo_config.tuner_address); goto dettach_frontend; } - } + } else + wprintk("failed to attach tda10046\n"); break; case SAA7134_BOARD_TEVION_DVBT_220RF: if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config, From 0e7830b50b20fcc25f21f79b7734102284d7c8f9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Jun 2008 11:27:34 -0300 Subject: [PATCH 17/42] V4L/DVB (8029): Improve error message at tda1004x_attach When an error occurs at firmware loading, sometimes, tda1004x stops answering. Instead of reporting such error, attach code were assuming that the device were answering an invalid ID (0xff). This can be seen when enabling debug options: tda1004x: tda1004x_read_byte: reg=0x0 tda1004x: tda1004x_read_byte: error reg=0x0, ret=-5 Now, instead of reporting an invalid ID, it will report the correct error: tda10046: chip is not answering. Giving up. saa7133[0]/dvb: failed to attach tda10046 saa7133[0]/dvb: frontend initialization failed A possible improvement would be trying to reset the device. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda1004x.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 3993d1ce334a..a0d638653567 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -1248,7 +1248,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; - u8 id; + int id; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); @@ -1264,6 +1264,12 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, /* check if the demod is there */ id = tda1004x_read_byte(state, TDA1004X_CHIPID); + if (id < 0) { + printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n"); + kfree(state); + return NULL; + } + if (id != 0x25) { printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); kfree(state); @@ -1312,7 +1318,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; - u8 id; + int id; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); @@ -1328,6 +1334,11 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, /* check if the demod is there */ id = tda1004x_read_byte(state, TDA1004X_CHIPID); + if (id < 0) { + printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n"); + kfree(state); + return NULL; + } if (id != 0x46) { printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); kfree(state); From 44e645c20304bbe0a72cb994d9baf4b5727d7cec Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 8 Jun 2008 20:10:29 -0300 Subject: [PATCH 18/42] V4L/DVB (8034): tda18271: fix IF notch frequency handling The IF notch bit gets unset when we update the Main Post Div register value, before we have a chance to write the desired IF notch setting to the tuner. Move the IF notch configuration to after we update MPD. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 30 ++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 89c01fb1f859..98acd588739a 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -45,6 +45,21 @@ static inline int charge_pump_source(struct dvb_frontend *fe, int force) TDA18271_MAIN_PLL, force); } +static inline void tda18271_set_if_notch(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_MPD] &= ~0x80; /* IF notch = 0 */ + break; + case TDA18271_DIGITAL: + regs[R_MPD] |= 0x80; /* IF notch = 1 */ + break; + } +} + static int tda18271_channel_configuration(struct dvb_frontend *fe, struct tda18271_std_map_item *map, u32 freq, u32 bw) @@ -66,19 +81,10 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, /* set cal mode to normal */ regs[R_EP4] &= ~0x03; - /* update IF output level & IF notch frequency */ + /* update IF output level */ regs[R_EP4] &= ~0x1c; /* clear if level bits */ regs[R_EP4] |= (map->if_lvl << 2); - switch (priv->mode) { - case TDA18271_ANALOG: - regs[R_MPD] &= ~0x80; /* IF notch = 0 */ - break; - case TDA18271_DIGITAL: - regs[R_MPD] |= 0x80; /* IF notch = 1 */ - break; - } - /* update FM_RFn */ regs[R_EP4] &= ~0x80; regs[R_EP4] |= map->fm_rfn << 7; @@ -135,6 +141,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, switch (priv->role) { case TDA18271_MASTER: tda18271_calc_main_pll(fe, N); + tda18271_set_if_notch(fe); tda18271_write_regs(fe, R_MPD, 4); break; case TDA18271_SLAVE: @@ -142,6 +149,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, tda18271_write_regs(fe, R_CPD, 4); regs[R_MPD] = regs[R_CPD] & 0x7f; + tda18271_set_if_notch(fe); tda18271_write_regs(fe, R_MPD, 1); break; } @@ -507,7 +515,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe) /* set cal mode to normal */ regs[R_EP4] &= ~0x03; - /* update IF output level & IF notch frequency */ + /* update IF output level */ regs[R_EP4] &= ~0x1c; /* clear if level bits */ ret = tda18271_write_regs(fe, R_EP3, 2); From 119a7c7e34b5e5fa65051960ca05000a19dbce85 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 8 Jun 2008 22:12:37 -0300 Subject: [PATCH 19/42] V4L/DVB (8035): tda18271: dont touch EB14 if rf_cal lookup is out of range The TDA18271HD/C1 rf_cal map lookup is expected to go out of range outside of the frequency window 41 MHz - 61.1 MHz. In these cases, the internal RF tracking filters calibration mechanism is used. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-common.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index f1894fec32b9..6fb5b4586569 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c @@ -649,9 +649,17 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); + /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range + * for frequencies above 61.1 MHz. In these cases, the internal RF + * tracking filters calibration mechanism is used. + * + * There is no need to warn the user about this. + */ + if (ret < 0) + goto fail; regs[R_EB14] = val; - +fail: return ret; } From 51858d13612a06494beb08616f8a93bdb2688e4c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Jun 2008 02:03:31 -0300 Subject: [PATCH 20/42] V4L/DVB (8036): tda18271: toggle rf agc speed mode on TDA18271HD/C2 only Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 98acd588739a..1ebf95d6770f 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -75,8 +75,10 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, regs[R_EP3] &= ~0x1f; /* clear std bits */ regs[R_EP3] |= (map->agc_mode << 3) | map->std; - /* set rfagc to high speed mode */ - regs[R_EP3] &= ~0x04; + if (priv->id == TDA18271HDC2) { + /* set rfagc to high speed mode */ + regs[R_EP3] &= ~0x04; + } /* set cal mode to normal */ regs[R_EP4] &= ~0x03; @@ -168,12 +170,14 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, msleep(20); - /* set rfagc to normal speed mode */ - if (map->fm_rfn) - regs[R_EP3] &= ~0x04; - else - regs[R_EP3] |= 0x04; - ret = tda18271_write_regs(fe, R_EP3, 1); + if (priv->id == TDA18271HDC2) { + /* set rfagc to normal speed mode */ + if (map->fm_rfn) + regs[R_EP3] &= ~0x04; + else + regs[R_EP3] |= 0x04; + ret = tda18271_write_regs(fe, R_EP3, 1); + } fail: return ret; } From 7ae1ac4c1db5a3647604acb00d736f17af6999b7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Jun 2008 13:52:49 -0300 Subject: [PATCH 21/42] V4L/DVB (8037): tda18271: ensure that the thermometer is off during channel configuration Having the thermometer on during channel configuration could cause tuning instability. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 1ebf95d6770f..93063c6fbbf6 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -103,6 +103,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, /* disable Power Level Indicator */ regs[R_EP1] |= 0x40; + /* make sure thermometer is off */ + regs[R_TM] &= ~0x10; + /* frequency dependent parameters */ tda18271_calc_ir_measure(fe, &freq); From 02da465945ae0a277aadf2bf37965a9e6c28f8c3 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 13 Jun 2008 09:03:45 -0300 Subject: [PATCH 22/42] V4L/DVB (8039): pxa-camera: fix platform_get_irq() error handling. platform_get_irq() returns a negative value on error, not 0. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pxa_camera.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 7cc8e9b19fb7..5ec5bb9a94d2 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -1019,12 +1019,12 @@ static int pxa_camera_probe(struct platform_device *pdev) struct pxa_camera_dev *pcdev; struct resource *res; void __iomem *base; - unsigned int irq; + int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || !irq) { + if (!res || irq < 0) { err = -ENODEV; goto exit; } From 3cfdc7f25b3116d57e91427caada74dd69bfbc06 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 13 Jun 2008 09:11:01 -0300 Subject: [PATCH 23/42] V4L/DVB (8040): soc-camera: remove soc_camera_host_class class Devices can either be class devices or bus devices, not both at the same time. Soc-camera host devices usually have a platform device as their parent. Trying to also register them with a class crashes the kernel, when linked statically. Interestingly, it works when built as a module. Thanks to Paulius Zaleckas for reporting. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/soc_camera.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index a1b92446c8b4..d015bfe00950 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -763,15 +763,6 @@ static struct device_driver ic_drv = { .owner = THIS_MODULE, }; -/* - * Image capture host - this is a host device, not a bus device, so, - * no bus reference, no probing. - */ -static struct class soc_camera_host_class = { - .owner = THIS_MODULE, - .name = "camera_host", -}; - static void dummy_release(struct device *dev) { } @@ -801,7 +792,6 @@ int soc_camera_host_register(struct soc_camera_host *ici) /* Number might be equal to the platform device ID */ sprintf(ici->dev.bus_id, "camera_host%d", ici->nr); - ici->dev.class = &soc_camera_host_class; mutex_lock(&list_lock); list_for_each_entry(ix, &hosts, list) { @@ -1003,14 +993,9 @@ static int __init soc_camera_init(void) ret = driver_register(&ic_drv); if (ret) goto edrvr; - ret = class_register(&soc_camera_host_class); - if (ret) - goto eclr; return 0; -eclr: - driver_unregister(&ic_drv); edrvr: bus_unregister(&soc_camera_bus_type); return ret; @@ -1018,7 +1003,6 @@ edrvr: static void __exit soc_camera_exit(void) { - class_unregister(&soc_camera_host_class); driver_unregister(&ic_drv); bus_unregister(&soc_camera_bus_type); } From 3b9408870757bd9e07fd03ac6318258f22b8dfa3 Mon Sep 17 00:00:00 2001 From: Austin Lund Date: Fri, 13 Jun 2008 11:02:43 -0300 Subject: [PATCH 24/42] V4L/DVB (8042): DVB-USB UMT-010 channel scan oops In the umt-010 driver the struct umt_properties sets the number of URBs for transfer to 20. But in dvb-usb.h MAX_NO_URBS_FOR_DATA_STREAM is set to 10. Not surprisingly this causes an oops for all devices which use the umt-010 chipset when they are inserted. fix on Kaffeine channel scan for Initialize stream count using MAX_NO_URBS_FOR_DATA_STREAM. Signed-off-by: Tim Gardner Signed-off-by: maximilian attems Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/umt-010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 9e7653bb3b66..118aab1a3e54 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c @@ -107,7 +107,7 @@ static struct dvb_usb_device_properties umt_properties = { /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, - .count = 20, + .count = MAX_NO_URBS_FOR_DATA_STREAM, .endpoint = 0x06, .u = { .bulk = { From 104fe9a2d2a56f25fb95800a7ab0f7600dd6879c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 13 Jun 2008 03:29:43 -0300 Subject: [PATCH 25/42] V4L/DVB (8043): au0828: add support for additional USB device id's Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.au0828 | 2 +- drivers/media/video/au0828/au0828-cards.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828 index aaae360312e4..86d1c8e7b18f 100644 --- a/Documentation/video4linux/CARDLIST.au0828 +++ b/Documentation/video4linux/CARDLIST.au0828 @@ -1,4 +1,4 @@ 0 -> Unknown board (au0828) - 1 -> Hauppauge HVR950Q (au0828) [2040:7200] + 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] 2 -> Hauppauge HVR850 (au0828) [2040:7240] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index a2a6983444fa..898e12395e7c 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -77,8 +77,14 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) /* Make sure we support the board model */ switch (tv.model) { + case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ + case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ + case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ + case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ + case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ + case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ break; default: printk(KERN_WARNING "%s: warning: " @@ -175,6 +181,18 @@ struct usb_device_id au0828_usb_id_table [] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 }, { USB_DEVICE(0x0fe9, 0xd620), .driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 }, + { USB_DEVICE(0x2040, 0x7210), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x7217), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x721b), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x721f), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x7280), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x0fd9, 0x0008), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { }, }; From 74d50724a02d7cdc7f7887411518ec43d0251b97 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 13 Jun 2008 20:33:23 -0300 Subject: [PATCH 26/42] V4L/DVB (8044): au8522: tuning optimizations If the current modulation and frequency is already set to the desired parameters, then don't re-tune. Don't store current frequency until after we've tuned successfully. Force a re-tune after resume from standby. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c index 084a280c2d7f..978a287b751b 100644 --- a/drivers/media/dvb/frontends/au8522.c +++ b/drivers/media/dvb/frontends/au8522.c @@ -463,10 +463,13 @@ static int au8522_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { struct au8522_state *state = fe->demodulator_priv; + int ret = -EINVAL; dprintk("%s(frequency=%d)\n", __func__, p->frequency); - state->current_frequency = p->frequency; + if ((state->current_frequency == p->frequency) && + (state->current_modulation == p->u.vsb.modulation)) + return 0; au8522_enable_modulation(fe, p->u.vsb.modulation); @@ -476,11 +479,16 @@ static int au8522_set_frontend(struct dvb_frontend *fe, if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, p); + ret = fe->ops.tuner_ops.set_params(fe, p); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } + if (ret < 0) + return ret; + + state->current_frequency = p->frequency; + return 0; } @@ -498,6 +506,16 @@ static int au8522_init(struct dvb_frontend *fe) return 0; } +static int au8522_sleep(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + dprintk("%s()\n", __func__); + + state->current_frequency = 0; + + return 0; +} + static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct au8522_state *state = fe->demodulator_priv; @@ -672,6 +690,7 @@ static struct dvb_frontend_ops au8522_ops = { }, .init = au8522_init, + .sleep = au8522_sleep, .i2c_gate_ctrl = au8522_i2c_gate_ctrl, .set_frontend = au8522_set_frontend, .get_frontend = au8522_get_frontend, From 6e501a3f4a7259b1c04aa6cbdfe64376afc9f59c Mon Sep 17 00:00:00 2001 From: Tim Farrington Date: Sun, 15 Jun 2008 13:33:42 -0300 Subject: [PATCH 27/42] V4L/DVB (8048): saa7134: Fix entries for Avermedia A16d and Avermedia E506 Also, adds IR table for Avermedia A16d Signed-off-by: Tim Farrington Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 38 +++++++++++++++ drivers/media/video/saa7134/saa7134-cards.c | 53 ++++++++++++--------- drivers/media/video/saa7134/saa7134-dvb.c | 37 +++++++------- drivers/media/video/saa7134/saa7134-input.c | 9 ++++ include/media/ir-common.h | 1 + 5 files changed, 95 insertions(+), 43 deletions(-) diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index a3485817e46c..8fa91f846d59 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -2201,3 +2201,41 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = { [0x25] = KEY_POWER, /* power */ }; EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); + +IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { + [0x20] = KEY_LIST, + [0x00] = KEY_POWER, + [0x28] = KEY_1, + [0x18] = KEY_2, + [0x38] = KEY_3, + [0x24] = KEY_4, + [0x14] = KEY_5, + [0x34] = KEY_6, + [0x2c] = KEY_7, + [0x1c] = KEY_8, + [0x3c] = KEY_9, + [0x12] = KEY_SUBTITLE, + [0x22] = KEY_0, + [0x32] = KEY_REWIND, + [0x3a] = KEY_SHUFFLE, + [0x02] = KEY_PRINT, + [0x11] = KEY_CHANNELDOWN, + [0x31] = KEY_CHANNELUP, + [0x0c] = KEY_ZOOM, + [0x1e] = KEY_VOLUMEDOWN, + [0x3e] = KEY_VOLUMEUP, + [0x0a] = KEY_MUTE, + [0x04] = KEY_AUDIO, + [0x26] = KEY_RECORD, + [0x06] = KEY_PLAY, + [0x36] = KEY_STOP, + [0x16] = KEY_PAUSE, + [0x2e] = KEY_REWIND, + [0x0e] = KEY_FASTFORWARD, + [0x30] = KEY_TEXT, + [0x21] = KEY_GREEN, + [0x01] = KEY_BLUE, + [0x08] = KEY_EPG, + [0x2a] = KEY_MENU, +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d); diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 21a761200548..2618cfa592e7 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4114,11 +4114,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - /* - TODO: .mpeg = SAA7134_MPEG_DVB, - */ - .inputs = {{ .name = name_tv, .vmux = 1, @@ -4157,7 +4153,7 @@ struct saa7134_board saa7134_boards[] = { } }, .radio = { .name = name_radio, - .amux = LINE1, + .amux = TV, }, }, [SAA7134_BOARD_AVERMEDIA_M115] = { @@ -4167,6 +4163,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 1, @@ -5351,22 +5348,21 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev, { switch (command) { case XC2028_TUNER_RESET: - saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000); - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000); - mdelay(250); - saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0); - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0); - mdelay(250); - saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000); - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000); - mdelay(250); - saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02); - saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81); - saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7); - saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03); - saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2, - 0x0001e000, 0x0001e000); - return 0; + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00000000); + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); + switch (dev->board) { + case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + saa7134_set_gpio(dev, 23, 0); + msleep(10); + saa7134_set_gpio(dev, 23, 1); + break; + case SAA7134_BOARD_AVERMEDIA_A16D: + saa7134_set_gpio(dev, 21, 0); + msleep(10); + saa7134_set_gpio(dev, 21, 1); + break; + } + return 0; } return -EINVAL; } @@ -5553,9 +5549,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS: - case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: case SAA7134_BOARD_AVERMEDIA_M115: - case SAA7134_BOARD_AVERMEDIA_A16D: /* power-down tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0); @@ -5565,6 +5559,18 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); msleep(10); break; + case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + saa7134_set_gpio(dev, 23, 0); + msleep(10); + saa7134_set_gpio(dev, 23, 1); + break; + case SAA7134_BOARD_AVERMEDIA_A16D: + saa7134_set_gpio(dev, 21, 0); + msleep(10); + saa7134_set_gpio(dev, 21, 1); + msleep(1); + dev->has_remote = SAA7134_REMOTE_GPIO; + break; case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: /* power-down tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004); @@ -5676,6 +5682,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_AVERMEDIA_A16D: + case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: ctl.demod = XC3028_FE_ZARLINK456; break; default: diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 653107c83803..341b101b0357 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -153,12 +153,12 @@ static int mt352_aver777_init(struct dvb_frontend* fe) return 0; } -static int mt352_aver_a16d_init(struct dvb_frontend *fe) +static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe) { - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 }; + static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d }; + static u8 reset [] = { RESET, 0x80 }; + static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; + static u8 agc_cfg [] = { AGC_TARGET, 0xe }; static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 }; mt352_write(fe, clock_config, sizeof(clock_config)); @@ -167,12 +167,9 @@ static int mt352_aver_a16d_init(struct dvb_frontend *fe) mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); mt352_write(fe, agc_cfg, sizeof(agc_cfg)); mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - return 0; } - - static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { @@ -215,14 +212,10 @@ static struct mt352_config avermedia_777 = { .demod_init = mt352_aver777_init, }; -static struct mt352_config avermedia_16d = { - .demod_address = 0xf, - .demod_init = mt352_aver_a16d_init, -}; - -static struct mt352_config avermedia_e506r_mt352_dev = { +static struct mt352_config avermedia_xc3028_mt352_dev = { .demod_address = (0x1e >> 1), .no_tuner = 1, + .demod_init = mt352_avermedia_xc3028_init, }; /* ================================================================== @@ -975,9 +968,10 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_AVERMEDIA_A16D: - dprintk("avertv A16D dvb setup\n"); - dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_16d, - &dev->i2c_adap); + dprintk("AverMedia A16D dvb setup\n"); + dev->dvb.frontend = dvb_attach(mt352_attach, + &avermedia_xc3028_mt352_dev, + &dev->i2c_adap); attach_xc3028 = 1; break; case SAA7134_BOARD_MD7134: @@ -1261,11 +1255,14 @@ static int dvb_init(struct saa7134_dev *dev) goto dettach_frontend; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + dprintk("AverMedia E506R dvb setup\n"); + saa7134_set_gpio(dev, 25, 0); + msleep(10); + saa7134_set_gpio(dev, 25, 1); dev->dvb.frontend = dvb_attach(mt352_attach, - &avermedia_e506r_mt352_dev, - &dev->i2c_adap); + &avermedia_xc3028_mt352_dev, + &dev->i2c_adap); attach_xc3028 = 1; - break; case SAA7134_BOARD_MD7134_BRIDGE_2: dev->dvb.frontend = dvb_attach(tda10086_attach, &sd1878_4m, &dev->i2c_adap); diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 919632b10aae..76e6501d238d 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -323,6 +323,15 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPMODE1, 0x1); saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); break; + case SAA7134_BOARD_AVERMEDIA_A16D: + ir_codes = ir_codes_avermedia_a16d; + mask_keycode = 0x02F200; + mask_keydown = 0x000400; + polling = 50; /* ms */ + /* Without this we won't receive key up events */ + saa_setb(SAA7134_GPIO_GPMODE1, 0x1); + saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); + break; case SAA7134_BOARD_KWORLD_TERMINATOR: ir_codes = ir_codes_pixelview; mask_keycode = 0x00001f; diff --git a/include/media/ir-common.h b/include/media/ir-common.h index bfee8be5d63f..b8e8aa91905a 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -146,6 +146,7 @@ extern IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE]; #endif From beb31e636501f39e853ac5d0ffd3fbb910d19d5c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 17 Jun 2008 17:37:51 -0300 Subject: [PATCH 28/42] V4L/DVB (8061): cx18: only select tuner / frontend modules if !DVB_FE_CUSTOMISE The automatic Kconfig selection for tuners and frontends should be conditional, based on !DVB_FE_CUSTOMISE. This patch corrects the selection for VIDEO_CX18 on MEDIA_TUNER_MXL5005S and DVB_S5H1409 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index 5f942690570c..9aefdc5ea79a 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig @@ -10,8 +10,8 @@ config VIDEO_CX18 select VIDEO_TVEEPROM select VIDEO_CX2341X select VIDEO_CS5345 - select DVB_S5H1409 - select MEDIA_TUNER_MXL5005S + select DVB_S5H1409 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE ---help--- This is a video4linux driver for Conexant cx23418 based PCI combo video recorder devices. From 527629fb7c35ad93389ab132823d19139dd88e70 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 14 Jun 2008 03:58:08 -0300 Subject: [PATCH 29/42] V4L/DVB (8063): cx18: Fix unintended auto configurations in cx18-av-core Change the cx18-av-core code so that accesses to cx23418 av core that cause auto-configuration will be adjusted to emulate the auto-configuration behavior of the cx25843. This fixes the VBI displayed as video at the top of the frame for NTSC and probably other things. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 71 ++++++++++++++++++++++--- drivers/media/video/cx18/cx18-av-core.h | 10 ++++ 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 8f2959ae7cab..faca43eb940f 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -69,6 +69,58 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, or_value); } +int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask) +{ + int retval; + u32 saved_reg[8] = {0}; + + if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { + saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL); + saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL); + } + + if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { + saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1); + saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC); + } + + if (no_acfg_mask & CXADEC_NO_ACFG_VID) { + saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL); + saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL); + saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG); + saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG); + } + + retval = cx18_av_write(cx, addr, value); + + if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { + cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]); + cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]); + } + + if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { + cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]); + cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]); + } + + if (no_acfg_mask & CXADEC_NO_ACFG_VID) { + cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]); + cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]); + cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]); + cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]); + } + + return retval; +} + +int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask, + u8 or_value, int no_acfg_mask) +{ + return cx18_av_write_no_acfg(cx, addr, + (cx18_av_read(cx, addr) & and_mask) | + or_value, no_acfg_mask); +} + /* ----------------------------------------------------------------------- */ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, @@ -170,13 +222,15 @@ static void input_change(struct cx18 *cx) /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ if (std & V4L2_STD_SECAM) - cx18_av_write(cx, 0x402, 0); + cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL); else { - cx18_av_write(cx, 0x402, 0x04); + cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL); cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); } - cx18_av_and_or(cx, 0x401, ~0x60, 0); - cx18_av_and_or(cx, 0x401, ~0x60, 0x60); + cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0, + CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); + cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60, + CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); if (std & V4L2_STD_525_60) { if (std == V4L2_STD_NTSC_M_JP) { @@ -262,7 +316,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, cx18_av_write(cx, 0x103, reg); /* Set INPUT_MODE to Composite (0) or S-Video (1) */ - cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); + cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02, + CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ @@ -318,12 +373,12 @@ static int set_v4lstd(struct cx18 *cx) This happens for example with the Yuan MPC622. */ if (fmt >= 4 && fmt < 8) { /* Set format to NTSC-M */ - cx18_av_and_or(cx, 0x400, ~0xf, 1); + cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE); /* Turn off LCOMB */ cx18_av_and_or(cx, 0x47b, ~6, 0); } - cx18_av_and_or(cx, 0x400, ~0xf, fmt); - cx18_av_and_or(cx, 0x403, ~0x3, pal_m); + cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE); + cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL); cx18_av_vbi_setup(cx); input_change(cx); return 0; diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 39f3c9397158..c172823ce1d8 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -295,14 +295,24 @@ struct cx18_av_state { #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ +/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/ +#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */ +#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */ +#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */ +#define CXADEC_NO_ACFG_ALL 0x07 + /* ----------------------------------------------------------------------- */ /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); +int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, + int no_acfg_mask); u8 cx18_av_read(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); +int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value, + int no_acfg_mask); int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); /* ----------------------------------------------------------------------- */ From 46195b555aa3edd265b4e765e4edff59b253b55e Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Thu, 19 Jun 2008 23:17:05 -0300 Subject: [PATCH 30/42] V4L/DVB (8066): cx18: Fix audio mux input definitions for HVR-1600 Line In 2 and FM radio Fix the cx18-cards.c structures for the HVR-1600 to reflect that audio Line In 2 and FM radio audio go to AIN3 and AIN4 of the CS5345 mux respectively. Verified by physical inspection of an HVR-1600MCE, by listening to FM broadcasts with the HVR-1600MCE, and by comparing with the card definition for a PVR-150 in ivtv. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index c35eb53a34c6..c18865b0d6cc 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -67,10 +67,10 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, .ddr = { /* ESMT M13S128324A-5B memory */ .chip_config = 0x003, @@ -107,10 +107,10 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, .ddr = { /* Samsung K4D263238G-VC33 memory */ .chip_config = 0x003, From 08cf7b2ed172cc83f3d2f44b712b3d54e6cc4ae6 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 22 Jun 2008 00:04:21 -0300 Subject: [PATCH 31/42] V4L/DVB (8067): cx18: Fix firmware load for case when digital capture happens first This is a fix for the case when a digital capture from dvr0 happens first after modprobe, before access to any cx18 v4l2 device nodes. The initial dvb feed start has been changed to load the firmware if not already loaded. Also fixed a use counter to correct dvb feed accounting if starting the transport DMA fails. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-dvb.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index c9744173f969..cae38985b131 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -69,11 +69,21 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) struct dvb_demux *demux = feed->demux; struct cx18_stream *stream = (struct cx18_stream *) demux->priv; struct cx18 *cx = stream->cx; - int ret = -EINVAL; + int ret; u32 v; CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", feed->pid, feed->index); + + mutex_lock(&cx->serialize_lock); + ret = cx18_init_on_first_open(cx); + mutex_unlock(&cx->serialize_lock); + if (ret) { + CX18_ERR("Failed to initialize firmware starting DVB feed\n"); + return ret; + } + ret = -EINVAL; + switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: @@ -101,6 +111,11 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) if (stream->dvb.feeding++ == 0) { CX18_DEBUG_INFO("Starting Transport DMA\n"); ret = cx18_start_v4l2_encode_stream(stream); + if (ret < 0) { + CX18_DEBUG_INFO( + "Failed to start Transport DMA\n"); + stream->dvb.feeding--; + } } else ret = 0; mutex_unlock(&stream->dvb.feedlock); From 1f09e8a25c9aaa4066b4593c1bf99a4cbcc38120 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 22 Jun 2008 01:27:00 -0300 Subject: [PATCH 32/42] V4L/DVB (8068): cx18: Add I2C slave reset via GPIO upon initialization cx18: Add I2C slave reset via GPIO upon initialization. One user, Michael , has reported this allows his HVR-1600 EEPROM to be consistently recognized when using (long,) 100 msec delays. The delays in this commit are nominal (10 & 40 msec) and need testing/tuning on boards with I2C problems to find the right values. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 10 ++++++++++ drivers/media/video/cx18/cx18-cards.h | 10 +++++++++- drivers/media/video/cx18/cx18-gpio.c | 26 +++++++++++++++++++++++++- drivers/media/video/cx18/cx18-gpio.h | 1 + drivers/media/video/cx18/cx18-i2c.c | 2 ++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index c18865b0d6cc..bbf23fa459d6 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -82,6 +82,11 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { }, .gpio_init.initial_value = 0x3001, .gpio_init.direction = 0x3001, + .gpio_i2c_slave_reset = { + .active_lo_mask = 0x3001, + .msecs_asserted = 10, + .msecs_recovery = 40, + }, .i2c = &cx18_i2c_std, }; @@ -122,6 +127,11 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { }, .gpio_init.initial_value = 0x3001, .gpio_init.direction = 0x3001, + .gpio_i2c_slave_reset = { + .active_lo_mask = 0x3001, + .msecs_asserted = 10, + .msecs_recovery = 40, + }, .i2c = &cx18_i2c_std, }; diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index 3c2c0b92956c..dc2dd945d4c3 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -78,6 +78,13 @@ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ u32 initial_value; }; +struct cx18_gpio_i2c_slave_reset { + u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */ + u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ + int msecs_asserted; /* time period reset must remain asserted */ + int msecs_recovery; /* time after deassert for chips to be ready */ +}; + struct cx18_card_tuner { v4l2_std_id std; /* standard for which the tuner is suitable */ int tuner; /* tuner ID (from tuner.h) */ @@ -114,7 +121,8 @@ struct cx18_card { /* GPIO card-specific settings */ u8 xceive_pin; /* XCeive tuner GPIO reset pin */ - struct cx18_gpio_init gpio_init; + struct cx18_gpio_init gpio_init; + struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; struct cx18_card_tuner_i2c *i2c; diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index ceb63653c926..b302833f6f9d 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -53,10 +53,34 @@ static void gpio_write(struct cx18 *cx) write_reg(((dir & 0xffff) << 16) | (val & 0xffff), CX18_REG_GPIO_OUT1); write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); - write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), + write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), CX18_REG_GPIO_OUT2); } +void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) +{ + const struct cx18_gpio_i2c_slave_reset *p; + + p = &cx->card->gpio_i2c_slave_reset; + + if ((p->active_lo_mask | p->active_hi_mask) == 0) + return; + + /* Assuming that the masks are a subset of the bits in gpio_dir */ + + /* Assert */ + cx->gpio_val = + (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); + gpio_write(cx); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); + + /* Deassert */ + cx->gpio_val = + (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); + gpio_write(cx); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); +} + void cx18_gpio_init(struct cx18 *cx) { cx->gpio_dir = cx->card->gpio_init.direction; diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h index 41bac8856b50..525c328f748a 100644 --- a/drivers/media/video/cx18/cx18-gpio.h +++ b/drivers/media/video/cx18/cx18-gpio.h @@ -21,4 +21,5 @@ */ void cx18_gpio_init(struct cx18 *cx); +void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); int cx18_reset_tuner_gpio(void *dev, int cmd, int value); diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 1d6c51a75313..680bc4e35b79 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -405,6 +405,8 @@ int init_cx18_i2c(struct cx18 *cx) cx18_setscl(&cx->i2c_algo_cb_data[1], 1); cx18_setsda(&cx->i2c_algo_cb_data[1], 1); + cx18_reset_i2c_slaves_gpio(cx); + return i2c_bit_add_bus(&cx->i2c_adap[0]) || i2c_bit_add_bus(&cx->i2c_adap[1]); } From ad907fa39517ca35b46912fbfe2b77cd89e1d56a Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 22 Jun 2008 02:00:09 -0300 Subject: [PATCH 33/42] V4L/DVB (8069): cx18: Fix S-Video and Compsite inputs for the Yuan MPC718 and enable card entry cx18: Fix S-Video and Compsite input settings for the Yuan MPC718 per user reports from Yuri Warczynski and Brian Hope and enable the card entry. The tuner reset GPIO pin is likely incorrect as the tuner firmware cannot be reloaded without a reboot. It is likely the audio routing is done via GPIO which is not implemented yet, as users report audio doesn't work for some inputs. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index bbf23fa459d6..c26e0ef5b075 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -194,23 +194,26 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = { static const struct cx18_card cx18_card_mpc718 = { .type = CX18_CARD_YUAN_MPC718, .name = "Yuan MPC718", - .comment = "Not yet supported!\n", - .v4l2_capabilities = 0, + .comment = "Some Composite and S-Video inputs are currently working.\n", + .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, + { CX18_CARD_INPUT_SVIDEO1, 1, + CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, + { CX18_CARD_INPUT_SVIDEO2, 2, + CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, + { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, 0 }, - { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, 0 }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, .tuners = { /* XC3028 tuner */ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, From c9fa2b1eee9d10c2455d3cd148cf13b34d91bdef Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 19 Jun 2008 22:45:55 -0300 Subject: [PATCH 34/42] V4L/DVB (8071): tda10023: Fix possible kernel oops during initialisation If the i2c write fails during initialisation, an oops happens because state->frontend.dvb is still undefined. Fixed. Thanks to Sigmund Augdal for reporting this bug, and to Hartmut Birr for suggesting the fix. Thanks-to: Sigmund Augdal Thanks-to: Hartmut Birr Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10023.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c index 0727b80bc4d2..c6ff5b82ff80 100644 --- a/drivers/media/dvb/frontends/tda10023.c +++ b/drivers/media/dvb/frontends/tda10023.c @@ -116,9 +116,12 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) int ret; ret = i2c_transfer (state->i2c, msg, 2); - if (ret != 2) - printk("DVB: TDA10023: %s: readreg error (ret == %i)\n", - __func__, ret); + if (ret != 2) { + int num = state->frontend.dvb ? state->frontend.dvb->num : -1; + printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error " + "(reg == 0x%02x, ret == %i)\n", + num, __func__, reg, ret); + } return b1[0]; } @@ -129,11 +132,12 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) int ret; ret = i2c_transfer (state->i2c, &msg, 1); - if (ret != 1) - printk("DVB: TDA10023(%d): %s, writereg error " + if (ret != 1) { + int num = state->frontend.dvb ? state->frontend.dvb->num : -1; + printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error " "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - state->frontend.dvb->num, __func__, reg, data, ret); - + num, __func__, reg, data, ret); + } return (ret != 1) ? -EREMOTEIO : 0; } @@ -464,7 +468,7 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, int i; /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL); + state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); if (state == NULL) goto error; /* setup the state */ From edabaffc7e7fccdeadac6273704102adc2b604ae Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 19 Jun 2008 23:04:27 -0300 Subject: [PATCH 35/42] V4L/DVB (8073): av7110: Catch another type of ARM crash Catch another type of ARM crash. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_hw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 9d81074b31df..c99936c4772a 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c @@ -427,6 +427,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) if (err) { printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", __func__, type); + av7110->arm_errors++; return -ETIMEDOUT; } msleep(1); From 0b915e74ac10b65da930aa430837d4338f5deb65 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 19 Jun 2008 23:10:14 -0300 Subject: [PATCH 36/42] V4L/DVB (8074): av7110: OSD transfers should not be interrupted OSD transfers should not be interrupted. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_hw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index c99936c4772a..3a3f5279e927 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c @@ -854,10 +854,8 @@ static osd_raw_window_t bpp2bit[8] = { static inline int WaitUntilBmpLoaded(struct av7110 *av7110) { - int ret = wait_event_interruptible_timeout(av7110->bmpq, + int ret = wait_event_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, 10*HZ); - if (ret == -ERESTARTSYS) - return ret; if (ret == 0) { printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n", ret, av7110->bmp_state); From 7876ad75b1a3b7dc3d5d765d0be086d89fd2e663 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 19 Jun 2008 23:25:04 -0300 Subject: [PATCH 37/42] V4L/DVB (8075): stv0299: Uncorrected block count and bit error rate fixed Fix uncorrected block counter and bit error rate to follow DVB API spec: - Unsupported controls return -ENOSYS. - UNC must never be set to 0. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0299.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 17556183e871..35435bef8e79 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c @@ -63,6 +63,7 @@ struct stv0299_state { u32 symbol_rate; fe_code_rate_t fec_inner; int errmode; + u32 ucblocks; }; #define STATUS_BER 0 @@ -501,8 +502,10 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) { struct stv0299_state* state = fe->demodulator_priv; - if (state->errmode != STATUS_BER) return 0; - *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); + if (state->errmode != STATUS_BER) + return -ENOSYS; + + *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8); return 0; } @@ -540,8 +543,12 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { struct stv0299_state* state = fe->demodulator_priv; - if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0; - else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); + if (state->errmode != STATUS_UCBLOCKS) + return -ENOSYS; + + state->ucblocks += stv0299_readreg(state, 0x1e); + state->ucblocks += (stv0299_readreg(state, 0x1d) << 8); + *ucblocks = state->ucblocks; return 0; } From 7fa8e6fa1519194fc0c931f40d530fb55137bad9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 13:23:27 -0300 Subject: [PATCH 38/42] V4L/DVB (8092): videodev: simplify and fix standard enumeration VIDIOC_ENUMSTD did not return all the PAL/SECAM/NTSC variants: it just returned one single PAL/SECAM/NTSC standard without separate entries for the trickier standards like NTSC-JP. Changed the code so that it behaves better. Also simplified the if/switch statements into a common standards lookup table. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 243 +++++++++------------------------ include/media/v4l2-dev.h | 4 +- 2 files changed, 69 insertions(+), 178 deletions(-) diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 31e8af0ba278..67a661cf5219 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -51,12 +51,51 @@ #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" +struct std_descr { + v4l2_std_id std; + const char *descr; +}; + +static const struct std_descr standards[] = { + { V4L2_STD_NTSC, "NTSC" }, + { V4L2_STD_NTSC_M, "NTSC-M" }, + { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, + { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, + { V4L2_STD_NTSC_443, "NTSC-443" }, + { V4L2_STD_PAL, "PAL" }, + { V4L2_STD_PAL_BG, "PAL-BG" }, + { V4L2_STD_PAL_B, "PAL-B" }, + { V4L2_STD_PAL_B1, "PAL-B1" }, + { V4L2_STD_PAL_G, "PAL-G" }, + { V4L2_STD_PAL_H, "PAL-H" }, + { V4L2_STD_PAL_I, "PAL-I" }, + { V4L2_STD_PAL_DK, "PAL-DK" }, + { V4L2_STD_PAL_D, "PAL-D" }, + { V4L2_STD_PAL_D1, "PAL-D1" }, + { V4L2_STD_PAL_K, "PAL-K" }, + { V4L2_STD_PAL_M, "PAL-M" }, + { V4L2_STD_PAL_N, "PAL-N" }, + { V4L2_STD_PAL_Nc, "PAL-Nc" }, + { V4L2_STD_PAL_60, "PAL-60" }, + { V4L2_STD_SECAM, "SECAM" }, + { V4L2_STD_SECAM_B, "SECAM-B" }, + { V4L2_STD_SECAM_G, "SECAM-G" }, + { V4L2_STD_SECAM_H, "SECAM-H" }, + { V4L2_STD_SECAM_DK, "SECAM-DK" }, + { V4L2_STD_SECAM_D, "SECAM-D" }, + { V4L2_STD_SECAM_K, "SECAM-K" }, + { V4L2_STD_SECAM_K1, "SECAM-K1" }, + { V4L2_STD_SECAM_L, "SECAM-L" }, + { V4L2_STD_SECAM_LC, "SECAM-Lc" }, + { 0, "Unknown" } +}; + /* video4linux standard ID conversion to standard name */ -char *v4l2_norm_to_name(v4l2_std_id id) +const char *v4l2_norm_to_name(v4l2_std_id id) { - char *name; u32 myid = id; + int i; /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 64 bit comparations. So, on that architecture, with some gcc @@ -64,110 +103,17 @@ char *v4l2_norm_to_name(v4l2_std_id id) */ BUG_ON(myid != id); - switch (myid) { - case V4L2_STD_PAL: - name = "PAL"; - break; - case V4L2_STD_PAL_BG: - name = "PAL-BG"; - break; - case V4L2_STD_PAL_DK: - name = "PAL-DK"; - break; - case V4L2_STD_PAL_B: - name = "PAL-B"; - break; - case V4L2_STD_PAL_B1: - name = "PAL-B1"; - break; - case V4L2_STD_PAL_G: - name = "PAL-G"; - break; - case V4L2_STD_PAL_H: - name = "PAL-H"; - break; - case V4L2_STD_PAL_I: - name = "PAL-I"; - break; - case V4L2_STD_PAL_D: - name = "PAL-D"; - break; - case V4L2_STD_PAL_D1: - name = "PAL-D1"; - break; - case V4L2_STD_PAL_K: - name = "PAL-K"; - break; - case V4L2_STD_PAL_M: - name = "PAL-M"; - break; - case V4L2_STD_PAL_N: - name = "PAL-N"; - break; - case V4L2_STD_PAL_Nc: - name = "PAL-Nc"; - break; - case V4L2_STD_PAL_60: - name = "PAL-60"; - break; - case V4L2_STD_NTSC: - name = "NTSC"; - break; - case V4L2_STD_NTSC_M: - name = "NTSC-M"; - break; - case V4L2_STD_NTSC_M_JP: - name = "NTSC-M-JP"; - break; - case V4L2_STD_NTSC_443: - name = "NTSC-443"; - break; - case V4L2_STD_NTSC_M_KR: - name = "NTSC-M-KR"; - break; - case V4L2_STD_SECAM: - name = "SECAM"; - break; - case V4L2_STD_SECAM_DK: - name = "SECAM-DK"; - break; - case V4L2_STD_SECAM_B: - name = "SECAM-B"; - break; - case V4L2_STD_SECAM_D: - name = "SECAM-D"; - break; - case V4L2_STD_SECAM_G: - name = "SECAM-G"; - break; - case V4L2_STD_SECAM_H: - name = "SECAM-H"; - break; - case V4L2_STD_SECAM_K: - name = "SECAM-K"; - break; - case V4L2_STD_SECAM_K1: - name = "SECAM-K1"; - break; - case V4L2_STD_SECAM_L: - name = "SECAM-L"; - break; - case V4L2_STD_SECAM_LC: - name = "SECAM-LC"; - break; - default: - name = "Unknown"; - break; - } - - return name; + for (i = 0; standards[i].std; i++) + if (myid == standards[i].std) + break; + return standards[i].descr; } EXPORT_SYMBOL(v4l2_norm_to_name); /* Fill in the fields of a v4l2_standard structure according to the 'id' and 'transmission' parameters. Returns negative on error. */ int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, char *name) + int id, const char *name) { u32 index = vs->index; @@ -1218,95 +1164,40 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_ENUMSTD: { struct v4l2_standard *p = arg; - v4l2_std_id id = vfd->tvnorms,curr_id=0; - unsigned int index = p->index,i; + v4l2_std_id id = vfd->tvnorms, curr_id = 0; + unsigned int index = p->index, i, j = 0; + const char *descr = ""; - if (index<0) { - ret=-EINVAL; - break; - } - - /* Return norm array on a canonical way */ - for (i=0;i<= index && id; i++) { - if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) { - curr_id = V4L2_STD_PAL; - } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) { - curr_id = V4L2_STD_PAL_BG; - } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) { - curr_id = V4L2_STD_PAL_DK; - } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) { - curr_id = V4L2_STD_PAL_B; - } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) { - curr_id = V4L2_STD_PAL_B1; - } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) { - curr_id = V4L2_STD_PAL_G; - } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) { - curr_id = V4L2_STD_PAL_H; - } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) { - curr_id = V4L2_STD_PAL_I; - } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) { - curr_id = V4L2_STD_PAL_D; - } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) { - curr_id = V4L2_STD_PAL_D1; - } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) { - curr_id = V4L2_STD_PAL_K; - } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) { - curr_id = V4L2_STD_PAL_M; - } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) { - curr_id = V4L2_STD_PAL_N; - } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) { - curr_id = V4L2_STD_PAL_Nc; - } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) { - curr_id = V4L2_STD_PAL_60; - } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) { - curr_id = V4L2_STD_NTSC; - } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) { - curr_id = V4L2_STD_NTSC_M; - } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) { - curr_id = V4L2_STD_NTSC_M_JP; - } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) { - curr_id = V4L2_STD_NTSC_443; - } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) { - curr_id = V4L2_STD_NTSC_M_KR; - } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) { - curr_id = V4L2_STD_SECAM; - } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) { - curr_id = V4L2_STD_SECAM_DK; - } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) { - curr_id = V4L2_STD_SECAM_B; - } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) { - curr_id = V4L2_STD_SECAM_D; - } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) { - curr_id = V4L2_STD_SECAM_G; - } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) { - curr_id = V4L2_STD_SECAM_H; - } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) { - curr_id = V4L2_STD_SECAM_K; - } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) { - curr_id = V4L2_STD_SECAM_K1; - } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) { - curr_id = V4L2_STD_SECAM_L; - } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) { - curr_id = V4L2_STD_SECAM_LC; - } else { + /* Return norm array in a canonical way */ + for (i = 0; i <= index && id; i++) { + /* last std value in the standards array is 0, so this + while always ends there since (id & 0) == 0. */ + while ((id & standards[j].std) != standards[j].std) + j++; + curr_id = standards[j].std; + descr = standards[j].descr; + j++; + if (curr_id == 0) break; - } - id &= ~curr_id; + if (curr_id != V4L2_STD_PAL && + curr_id != V4L2_STD_SECAM && + curr_id != V4L2_STD_NTSC) + id &= ~curr_id; } - if (i<=index) + if (i <= index) return -EINVAL; - v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id)); + v4l2_video_std_construct(p, curr_id, descr); p->index = index; - dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " + dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " "framelines=%d\n", p->index, (unsigned long long)p->id, p->name, p->frameperiod.numerator, p->frameperiod.denominator, p->framelines); - ret=0; + ret = 0; break; } case VIDIOC_G_STD: diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 33f01ae08f76..859f7a6f6f67 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -40,9 +40,9 @@ #define VFL_TYPE_VTX 3 /* Video standard functions */ -extern char *v4l2_norm_to_name(v4l2_std_id id); +extern const char *v4l2_norm_to_name(v4l2_std_id id); extern int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, char *name); + int id, const char *name); /* Prints the ioctl in a human-readable format */ extern void v4l_printk_ioctl(unsigned int cmd); From 836c28584d4629fdc85365f083b84e1298e14312 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 21 Jun 2008 19:32:41 -0300 Subject: [PATCH 39/42] V4L/DVB (8096): au8522: prevent false-positive lock status This decreases scan time in Queens, New York from 28 minutes to 7 minutes, with the exact same services found. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c index 978a287b751b..03900d241a76 100644 --- a/drivers/media/dvb/frontends/au8522.c +++ b/drivers/media/dvb/frontends/au8522.c @@ -527,10 +527,8 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) if (state->current_modulation == VSB_8) { dprintk("%s() Checking VSB_8\n", __func__); reg = au8522_readreg(state, 0x4088); - if (reg & 0x01) - *status |= FE_HAS_VITERBI; - if (reg & 0x02) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; + if ((reg & 0x03) == 0x03) + *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; } else { dprintk("%s() Checking QAM\n", __func__); reg = au8522_readreg(state, 0x4541); From e470d8177ed6ae56f4310ce793a57bcb2fed1749 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 21 Jun 2008 21:06:02 -0300 Subject: [PATCH 40/42] V4L/DVB (8097): xc5000: check device hardware state to determine if firmware download is needed This patch ensures that the xc5000 will have firmware loaded as needed if the part is powered down or reset via gpio from the host. An example of this, in some cases, could be after the system resumes from standby or hibernate modes. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/xc5000.c | 30 +++++++++++++++++------ drivers/media/common/tuners/xc5000_priv.h | 1 - 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index ceae6db901ec..7cf4f5bdb2ec 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -177,6 +177,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"FM Radio-INPUT1", 0x0208, 0x9002} }; +static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); static void xc5000_TunerReset(struct dvb_frontend *fe); @@ -352,7 +353,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, static int xc_shutdown(struct xc5000_priv *priv) { - return 0; + return XC_RESULT_SUCCESS; /* Fixme: cannot bring tuner back alive once shutdown * without reloading the driver modules. * return xc_write_reg(priv, XREG_POWER_DOWN, 0); @@ -685,6 +686,25 @@ static int xc5000_set_params(struct dvb_frontend *fe, return 0; } +static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) +{ + struct xc5000_priv *priv = fe->tuner_priv; + int ret; + u16 id; + + ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id); + if (ret == XC_RESULT_SUCCESS) { + if (id == XC_PRODUCT_ID_FW_NOT_LOADED) + ret = XC_RESULT_RESET_FAILURE; + else + ret = XC_RESULT_SUCCESS; + } + + dprintk(1, "%s() returns %s id = 0x%x\n", __func__, + ret == XC_RESULT_SUCCESS ? "True" : "False", id); + return ret; +} + static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); static int xc5000_set_analog_params(struct dvb_frontend *fe, @@ -693,7 +713,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, struct xc5000_priv *priv = fe->tuner_priv; int ret; - if(priv->fwloaded == 0) + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) xc_load_fw_and_init_tuner(fe); dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", @@ -808,11 +828,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) struct xc5000_priv *priv = fe->tuner_priv; int ret = 0; - if (priv->fwloaded == 0) { + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { ret = xc5000_fwupload(fe); if (ret != XC_RESULT_SUCCESS) return ret; - priv->fwloaded = 1; } /* Start the tuner self-calibration process */ @@ -852,7 +871,6 @@ static int xc5000_sleep(struct dvb_frontend *fe) return -EREMOTEIO; } else { - /* priv->fwloaded = 0; */ return XC_RESULT_SUCCESS; } } @@ -933,7 +951,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, cfg->i2c_address); printk(KERN_INFO "xc5000: Firmware has been loaded previously\n"); - priv->fwloaded = 1; break; case XC_PRODUCT_ID_FW_NOT_LOADED: printk(KERN_INFO @@ -941,7 +958,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, cfg->i2c_address); printk(KERN_INFO "xc5000: Firmware has not been loaded previously\n"); - priv->fwloaded = 0; break; default: printk(KERN_ERR diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h index ecebfe4745ad..a72a9887fe7f 100644 --- a/drivers/media/common/tuners/xc5000_priv.h +++ b/drivers/media/common/tuners/xc5000_priv.h @@ -30,7 +30,6 @@ struct xc5000_priv { u32 bandwidth; u8 video_standard; u8 rf_mode; - u8 fwloaded; void *devptr; }; From 5c554e6b984ce6b36488b93a7ec8e2752233e7cb Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 22 Jun 2008 09:11:40 -0300 Subject: [PATCH 41/42] V4L/DVB (8100): V4L/vivi: fix possible memory leak in vivi_fillbuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move allocation after first check and fix memory leak. Noticed-by: Daniel Marjamäki Signed-off-by: Marcin Slusarz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 845be1864f68..5ff9a58b6135 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -327,13 +327,14 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) int hmax = buf->vb.height; int wmax = buf->vb.width; struct timeval ts; - char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); + char *tmpbuf; void *vbuf = videobuf_to_vmalloc(&buf->vb); - if (!tmpbuf) + if (!vbuf) return; - if (!vbuf) + tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); + if (!tmpbuf) return; for (h = 0; h < hmax; h++) { From a17898737eaed4ef41f273da7b830c632e06613e Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 22 Jun 2008 17:03:02 -0300 Subject: [PATCH 42/42] V4L/DVB (8108): Fix open/close race in saa7134 The saa7134 driver uses a (non-atomic) variable in an attempt to only allow one opener of the device (how it deals with sending the fd over unix sockets I don't know). Unfortunately, the release function first decrements this variable, and THEN goes on to disable more of the device. This allows for a race where another opener of the device comes in after the decrement of the variable, configures the hardware just to then see the hardware be disabled by the rest of the release function. This patch makes the release function use the same lock as the open function to protect the hardware as well as the variable (which now at least has some locking to protect it). Signed-off-by: Arjan van de Ven Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-empress.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 1c8cd0ef4a65..3ae71a340822 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -110,6 +110,8 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; + mutex_lock(&dev->empress_tsq.vb_lock); + videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); @@ -122,6 +124,8 @@ static int ts_release(struct inode *inode, struct file *file) dev->empress_users--; + mutex_unlock(&dev->empress_tsq.vb_lock); + return 0; }