From 4309193cab34f5f79808f03e09f8d39a5f2a7288 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Oct 2008 03:51:46 +0000 Subject: V4L: struct device - replace bus_id with dev_name(), dev_set_name() From: Kay Sievers This patch is part of a larger patch series which will remove the "char bus_id[20]" name string from struct device. The device name is managed in the kobject anyway, and without any size limitation, and just needlessly copied into "struct device". To set and read the device name dev_name(dev) and dev_set_name(dev) must be used. If your code uses static kobjects, which it shouldn't do, "const char *init_name" can be used to statically provide the name the registered device should have. At registration time, the init_name field is cleared, to enforce the use of dev_name(dev) to access the device name at a later time. We need to get rid of all occurrences of bus_id in the entire tree to be able to enable the new interface. Please apply this patch, and possibly convert any remaining remaining occurrences of bus_id. We want to submit a patch to -next, which will remove bus_id from "struct device", to find the remaining pieces to convert, and finally switch over to the new api, which will remove the 20 bytes array and does no longer have a size limitation. Thanks, Kay Acked-by: Greg Kroah-Hartman Signed-Off-By: Kay Sievers Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 740e73cc1..a4493da8a 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1275,7 +1275,7 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); cap->version = EM28XX_VERSION_CODE; @@ -1465,7 +1465,7 @@ static int radio_querycap(struct file *file, void *priv, strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); cap->version = EM28XX_VERSION_CODE; cap->capabilities = V4L2_CAP_TUNER; -- cgit v1.2.3 From 94d05a47bd31702be24fbef3b4ee9448083295d6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Nov 2008 15:24:18 -0200 Subject: Properly handle error messages during alsa registering From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-audio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index d6856b331..bec42349e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -500,7 +500,7 @@ static int em28xx_audio_init(struct em28xx *dev) if (dev->has_audio_class) { /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module */ + the device is expecting the snd-usb-audio module) */ return 0; } @@ -521,7 +521,12 @@ static int em28xx_audio_init(struct em28xx *dev) } spin_lock_init(&adev->slock); - ret = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); + err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); + if (err < 0) { + snd_card_free(card); + return err; + } + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); pcm->info_flags = 0; pcm->private_data = dev; @@ -533,7 +538,7 @@ static int em28xx_audio_init(struct em28xx *dev) err = snd_card_register(card); if (err < 0) { snd_card_free(card); - return -ENOMEM; + return err; } adev->sndcard = card; adev->udev = dev->udev; -- cgit v1.2.3 From 01ea3eb2c9dbd7537a6cd1c915bf7a098d80715d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:04:48 +0000 Subject: Add chip id for em2874 to list of known chips From: Devin Heitmueller Add em2874 chip id Add chip id for em2874 to list of known chips Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 4 ++++ linux/drivers/media/video/em28xx/em28xx-reg.h | 1 + 2 files changed, 5 insertions(+) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 4f078da31..072561e47 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1328,6 +1328,10 @@ void em28xx_pre_card_setup(struct em28xx *dev) case CHIP_ID_EM2860: em28xx_info("chip ID is em2860\n"); break; + case CHIP_ID_EM2874: + em28xx_info("chip ID is em2874\n"); + dev->wait_after_write = 0; + break; case CHIP_ID_EM2883: em28xx_info("chip ID is em2882/em2883\n"); dev->wait_after_write = 0; diff --git a/linux/drivers/media/video/em28xx/em28xx-reg.h b/linux/drivers/media/video/em28xx/em28xx-reg.h index fac1ab23f..0892df17f 100644 --- a/linux/drivers/media/video/em28xx/em28xx-reg.h +++ b/linux/drivers/media/video/em28xx/em28xx-reg.h @@ -86,4 +86,5 @@ enum em28xx_chip_id { CHIP_ID_EM2860 = 34, CHIP_ID_EM2883 = 36, + CHIP_ID_EM2874 = 65, }; -- cgit v1.2.3 From 828680031c009faa7795dea3359744f38193eb57 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:04:53 +0000 Subject: Remove unused variable from em28xx-audio.c From: Devin Heitmueller Remove unused variable from em28xx-audio.c Fix warning for unused "ret" variable Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index bec42349e..cabce87b7 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -496,7 +496,7 @@ static int em28xx_audio_init(struct em28xx *dev) struct snd_card *card; #endif static int devnr; - int ret, err; + int err; if (dev->has_audio_class) { /* This device does not support the extension (in this case -- cgit v1.2.3 From 9293ae2ae1a0de7312fc28fb3b77727d50248592 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:04:57 +0000 Subject: Add a EM28XX_NODECODER option to the list of available decoders From: Devin Heitmueller Add a EM28XX_NODECODER option to the list of available decoders Add a EM28XX_NODECODER option to the list of available decoders. This option becomes important for devices that do not have analog support. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index d73b8c983..ce18c4e2b 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -269,6 +269,7 @@ struct em28xx_input { #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) enum em28xx_decoder { + EM28XX_NODECODER, EM28XX_TVP5150, EM28XX_SAA7113, EM28XX_SAA7114 -- cgit v1.2.3 From 5ac5a13ff2fd49780ebe8662765833c58a4bf669 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:02 +0000 Subject: Remember chip id of devices at initialization From: Devin Heitmueller Remember chip id of devices at initialization When setting up the device, remember the chip id, so we can control behavior in the future without having to read the register continuously. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 1 + linux/drivers/media/video/em28xx/em28xx.h | 1 + 2 files changed, 2 insertions(+) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 072561e47..adc323bef 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1324,6 +1324,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) dev->wait_after_write = 5; rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); if (rc > 0) { + dev->chip_id = rc; switch (rc) { case CHIP_ID_EM2860: em28xx_info("chip ID is em2860\n"); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index ce18c4e2b..5c1bdb295 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -376,6 +376,7 @@ struct em28xx { char name[30]; /* name (including minor) of the device */ int model; /* index in the device_data struct */ int devno; /* marks the number of this device */ + enum em28xx_chip_id chip_id; unsigned int is_em2800:1; unsigned int has_msp34xx:1; unsigned int has_tda9887:1; -- cgit v1.2.3 From 94a01f9a0f103d0960f2c005ed6c995982489054 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:06 +0000 Subject: Support different GPIO/GPO registers for newer devices From: Devin Heitmueller Support different GPIO/GPO registers for newer devices Empia moved the location of the GPIO/GPO registers in newer devices. Add the ability to specify the relocated registers (including caching of register contents). Thanks for Ray Lu from Empia for providing the em2874 datasheet. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 15 ++++++++++++--- linux/drivers/media/video/em28xx/em28xx-core.c | 8 ++++---- linux/drivers/media/video/em28xx/em28xx-reg.h | 3 +++ linux/drivers/media/video/em28xx/em28xx.h | 3 +++ 4 files changed, 22 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index adc323bef..c9aacfcfc 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1317,11 +1317,13 @@ void em28xx_pre_card_setup(struct em28xx *dev) { int rc; - rc = em28xx_read_reg(dev, EM2880_R04_GPO); - if (rc >= 0) - dev->reg_gpo = rc; + /* Set the default GPO/GPIO for legacy devices */ + dev->reg_gpo_num = EM2880_R04_GPO; + dev->reg_gpio_num = EM28XX_R08_GPIO; dev->wait_after_write = 5; + + /* Based on the Chip ID, set the device configuration */ rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); if (rc > 0) { dev->chip_id = rc; @@ -1331,6 +1333,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) break; case CHIP_ID_EM2874: em28xx_info("chip ID is em2874\n"); + dev->reg_gpio_num = EM2874_R80_GPIO; dev->wait_after_write = 0; break; case CHIP_ID_EM2883: @@ -1341,6 +1344,12 @@ void em28xx_pre_card_setup(struct em28xx *dev) em28xx_info("em28xx chip ID = %d\n", rc); } } + + /* Prepopulate cached GPO register content */ + rc = em28xx_read_reg(dev, dev->reg_gpo_num); + if (rc >= 0) + dev->reg_gpo = rc; + em28xx_set_model(dev); /* request some modules */ diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 1a30e361c..27088f55a 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -175,9 +175,9 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) Not sure what happens on reading GPO register. */ if (rc >= 0) { - if (reg == EM2880_R04_GPO) + if (reg == dev->reg_gpo_num) dev->reg_gpo = buf[0]; - else if (reg == EM28XX_R08_GPIO) + else if (reg == dev->reg_gpio_num) dev->reg_gpio = buf[0]; } @@ -196,9 +196,9 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, u8 newval; /* Uses cache for gpo/gpio registers */ - if (reg == EM2880_R04_GPO) + if (reg == dev->reg_gpo_num) oldval = dev->reg_gpo; - else if (reg == EM28XX_R08_GPIO) + else if (reg == dev->reg_gpio_num) oldval = dev->reg_gpio; else oldval = em28xx_read_reg(dev, reg); diff --git a/linux/drivers/media/video/em28xx/em28xx-reg.h b/linux/drivers/media/video/em28xx/em28xx-reg.h index 0892df17f..1f0e8a34e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-reg.h +++ b/linux/drivers/media/video/em28xx/em28xx-reg.h @@ -76,6 +76,9 @@ #define EM28XX_R10_LINE_IN_AC97 0x10 #define EM28XX_R14_VIDEO_AC97 0x14 +/* em2874 registers */ +#define EM2874_R80_GPIO 0x80 + /* register settings */ #define EM2800_AUDIO_SRC_TUNER 0x0d #define EM2800_AUDIO_SRC_LINE 0x0c diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 5c1bdb295..d752d9cac 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -474,6 +474,9 @@ struct em28xx { enum em28xx_mode mode; + /* register numbers for GPO/GPIO registers */ + u16 reg_gpo_num, reg_gpio_num; + /* Caches GPO and GPIO registers */ unsigned char reg_gpo, reg_gpio; -- cgit v1.2.3 From 215aa89455a6032cdf605bdd4b5064b8c14b8067 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:10 +0000 Subject: Skip reading eeprom in newer Empia devices From: Devin Heitmueller Skip reading eeprom in newer Empia devices Empia switched to a 16-bit addressable eeprom in newer devices. While we could certainly write a routine to read the eeprom, there is nothing of use in there that cannot be accessed through registers, and there is the risk that we could corrupt the eeprom (since a 16-bit read call is interpreted as a write call by 8-bit eeproms). So just be safe and bail out of the function. Thanks for Ray Lu from Empia for providing the em2874 datasheet. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-i2c.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index 3bab56b99..51ecdcd34 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -332,6 +332,17 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) struct em28xx_eeprom *em_eeprom = (void *)eedata; int i, err, size = len, block; + if (dev->chip_id == CHIP_ID_EM2874) { + /* Empia switched to a 16-bit addressable eeprom in newer + devices. While we could certainly write a routine to read + the eeprom, there is nothing of use in there that cannot be + accessed through registers, and there is the risk that we + could corrupt the eeprom (since a 16-bit read call is + interpreted as a write call by 8-bit eeproms). + */ + return 0; + } + dev->i2c_client.addr = 0xa0 >> 1; /* Check if board has eeprom */ -- cgit v1.2.3 From 0b65108ee51fa8796b38304395fc9bd64321d98b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:15 +0000 Subject: Fix possible null pointer dereference in info message From: Devin Heitmueller Fix possible null pointer dereference in info message Fix case where we could end up dereferencing a NULL pointer if dev->vdev or dev->vbi_dev were not set properly. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-video.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index a4493da8a..040ea9ef3 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1656,8 +1656,6 @@ static void em28xx_release_resources(struct em28xx *dev) /*FIXME: I2C IR should be disconnected */ - em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", - dev->vdev->num, dev->vbi_dev->num); list_del(&dev->devlist); if (dev->sbutton_input_dev) em28xx_deregister_snapshot_button(dev); @@ -1669,6 +1667,8 @@ static void em28xx_release_resources(struct em28xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { + em28xx_info("V4L2 device /dev/vbi%d deregistered\n", + dev->vbi_dev->num); if (-1 != dev->vbi_dev->minor) video_unregister_device(dev->vbi_dev); else @@ -1676,6 +1676,8 @@ static void em28xx_release_resources(struct em28xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { + em28xx_info("V4L2 device /dev/video%d deregistered\n", + dev->vdev->num); if (-1 != dev->vdev->minor) video_unregister_device(dev->vdev); else -- cgit v1.2.3 From e3afb5932ce80a7a6bb8b796801e21b684b31611 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:02:17 +0000 Subject: Handle changes to endpoint layout in em2874 From: Devin Heitmueller Handle changes to endpoint layout in em2874 Empia moved around their endpoint configuration in newer chips, so accommodate the changes Thanks for Ray Lu from Empia for providing the em2874 datasheet. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-video.c | 36 ++++++++++++++++--------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 040ea9ef3..6332eb07e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -2206,7 +2206,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, struct usb_interface *uif; struct em28xx *dev = NULL; int retval = -ENODEV; - int i, nr, ifnum; + int i, nr, ifnum, isoc_pipe; udev = usb_get_dev(interface_to_usbdev(interface)); ifnum = interface->altsetting[0].desc.bInterfaceNumber; @@ -2233,19 +2233,29 @@ static int em28xx_usb_probe(struct usb_interface *interface, ifnum, interface->altsetting[0].desc.bInterfaceClass); - endpoint = &interface->cur_altsetting->endpoint[1].desc; + endpoint = &interface->cur_altsetting->endpoint[0].desc; /* check if the device has the iso in endpoint at the correct place */ - if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != - USB_ENDPOINT_XFER_ISOC) { - em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); - em28xx_devused &= ~(1<bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { - em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); - em28xx_devused &= ~(1<bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC && + (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) + { + /* It's a newer em2874/em2875 device */ + isoc_pipe = 0; + } else { + isoc_pipe = 1; + endpoint = &interface->cur_altsetting->endpoint[1].desc; + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != + USB_ENDPOINT_XFER_ISOC) { + em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); + em28xx_devused &= ~(1<bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { + em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); + em28xx_devused &= ~(1<= EM28XX_MAXBOARDS) { @@ -2296,7 +2306,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, } for (i = 0; i < dev->num_alt ; i++) { - u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. + u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc. wMaxPacketSize); dev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); -- cgit v1.2.3 From b4d980248bc67a682e8762f9471a3966503d0a42 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:19 +0000 Subject: Don't load em28xx audio module for digital-only devices From: Devin Heitmueller Don't load em28xx audio module for digital-only devices Rework the logic so that the em28xx-alsa module does not get loaded for devices that don't support analog audio (such as the em2874) Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-audio.c | 10 +++++---- linux/drivers/media/video/em28xx/em28xx-video.c | 29 +++++++++++++++++++++---- linux/drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index cabce87b7..b86b0870d 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -498,9 +498,10 @@ static int em28xx_audio_init(struct em28xx *dev) static int devnr; int err; - if (dev->has_audio_class) { + if (dev->has_alsa_audio != 1) { /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module) */ + the device is expecting the snd-usb-audio module or + doesn't have analog audio support at all) */ return 0; } @@ -552,9 +553,10 @@ static int em28xx_audio_fini(struct em28xx *dev) if (dev == NULL) return 0; - if (dev->has_audio_class) { + if (dev->has_alsa_audio != 1) { /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module */ + the device is expecting the snd-usb-audio module or + doesn't have analog audio support at all) */ return 0; } diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 6332eb07e..19684ad45 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1984,6 +1984,19 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, return vfd; } +int em28xx_supports_audio_extension(struct em28xx *dev) +{ + /* The chip dictates whether we support the Empia analog audio + extension */ + switch (dev->chip_id) { + case CHIP_ID_EM2874: + /* Either a digital-only device or provides AC97 audio */ + return 0; + case CHIP_ID_EM2883: + default: + return 1; + } +} /* * em28xx_init_dev() @@ -2173,7 +2186,7 @@ static void request_module_async(struct work_struct *work) if (dev->has_audio_class) request_module("snd-usb-audio"); - else + else if (dev->has_alsa_audio) request_module("em28xx-alsa"); if (dev->has_dvb) @@ -2287,9 +2300,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, } } - printk(KERN_INFO DRIVER_NAME " %s usb audio class\n", - dev->has_audio_class ? "Has" : "Doesn't have"); - /* compute alternate max packet sizes */ uif = udev->actconfig->interface[0]; @@ -2324,6 +2334,17 @@ static int em28xx_usb_probe(struct usb_interface *interface, em28xx_info("Found %s\n", em28xx_boards[dev->model].name); + if (dev->has_audio_class == 0) { + /* We don't have a USB audio class, let's see if we support + ALSA Audio */ + dev->has_alsa_audio = em28xx_supports_audio_extension(dev); + if (dev->has_alsa_audio) + printk(KERN_INFO DRIVER_NAME " supports alsa audio\n"); + } else { + printk(KERN_INFO DRIVER_NAME " has usb audio class\n"); + } + + /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index d752d9cac..12507422f 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -382,6 +382,7 @@ struct em28xx { unsigned int has_tda9887:1; unsigned int stream_on:1; /* Locks streams */ unsigned int has_audio_class:1; + unsigned int has_alsa_audio:1; unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; unsigned int has_dvb:1; -- cgit v1.2.3 From 2cb2731d0d8cc3f0abde2ae9929321a2bd032d59 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:24 +0000 Subject: Properly support capture start on em2874 From: Devin Heitmueller Properly support capture start on em2874 The transport stream enable register moved in the em2874, so make it work properly. Thanks for Ray Lu from Empia for providing the em2874 datasheet. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 18 ++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx-reg.h | 9 +++++++++ 2 files changed, 27 insertions(+) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 27088f55a..48c2caabe 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -359,6 +359,24 @@ int em28xx_colorlevels_set_default(struct em28xx *dev) int em28xx_capture_start(struct em28xx *dev, int start) { int rc; + + if (dev->chip_id == CHIP_ID_EM2874) { + /* The Transport Stream Enable Register moved in em2874 */ + if (!start) { + rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, + 0x00, + EM2874_TS1_CAPTURE_ENABLE); + return rc; + } + + /* Enable Transport Stream */ + rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, + EM2874_TS1_CAPTURE_ENABLE, + EM2874_TS1_CAPTURE_ENABLE); + return rc; + } + + /* FIXME: which is the best order? */ /* video registers are sampled by VREF */ rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, diff --git a/linux/drivers/media/video/em28xx/em28xx-reg.h b/linux/drivers/media/video/em28xx/em28xx-reg.h index 1f0e8a34e..50d1790d8 100644 --- a/linux/drivers/media/video/em28xx/em28xx-reg.h +++ b/linux/drivers/media/video/em28xx/em28xx-reg.h @@ -77,8 +77,17 @@ #define EM28XX_R14_VIDEO_AC97 0x14 /* em2874 registers */ +#define EM2874_R5F_TS_ENABLE 0x5f #define EM2874_R80_GPIO 0x80 +/* em2874 Transport Stream Enable Register (0x5f) */ +#define EM2874_TS1_CAPTURE_ENABLE (1 << 0) +#define EM2874_TS1_FILTER_ENABLE (1 << 1) +#define EM2874_TS1_NULL_DISCARD (1 << 2) +#define EM2874_TS2_CAPTURE_ENABLE (1 << 4) +#define EM2874_TS2_FILTER_ENABLE (1 << 5) +#define EM2874_TS2_NULL_DISCARD (1 << 6) + /* register settings */ #define EM2800_AUDIO_SRC_TUNER 0x0d #define EM2800_AUDIO_SRC_LINE 0x0c -- cgit v1.2.3 From 3fd0630b68e2110e8c61c0915242ba20231d4641 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Nov 2008 05:05:28 +0000 Subject: Add registration for Pinnacle 80e ATSC tuner From: Devin Heitmueller Add registration for Pinnacle 80e ATSC tuner Register the em2874 based Pinnacle 80e device. Note that support for this device also requires the new drx-j driver (which is not available yet) Thanks for Ray Lu from Empia for providing the em2874 datasheet. Thanks to Joerg Schindler from Pinnacle for providing sample hardware. Thanks to Rainer Miethling from Pinnacle for providing engineering support. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 34 +++++++++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx.h | 1 + 2 files changed, 35 insertions(+) (limited to 'linux/drivers/media/video/em28xx') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index c9aacfcfc..75024a252 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1088,6 +1088,20 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2874_BOARD_PINNACLE_PCTV_80E] = { + .name = "Pinnacle PCTV HD Mini", + .vchannels = 0, + .tuner_type = TUNER_ABSENT, + .has_dvb = 1, + .decoder = EM28XX_NODECODER, +#ifdef DJH_DEBUG + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + } }, +#endif + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1185,6 +1199,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO }, { USB_DEVICE(0x2304, 0x0227), .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, + { USB_DEVICE(0x2304, 0x023f), + .driver_info = EM2874_BOARD_PINNACLE_PCTV_80E }, { USB_DEVICE(0x0413, 0x6023), .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, { USB_DEVICE(0x093b, 0xa005), @@ -1260,6 +1276,17 @@ static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = { { -1, -1, -1, -1}, }; +/* Pinnacle PCTV HD Mini (80e) GPIOs + 0-5: not used + 6: demod reset, active low + 7: LED on, active high */ +static struct em28xx_reg_seq em2874_pinnacle_80e_digital[] = { + {EM28XX_R06_I2C_CLK, 0x45, 0xff, 10}, /*400 KHz*/ + {EM2874_R80_GPIO, 0x80, 0xff, 100},/*Demod reset*/ + {EM2874_R80_GPIO, 0xc0, 0xff, 10}, + { -1, -1, -1, -1}, +}; + /* * EEPROM hash table for devices with generic USB IDs */ @@ -1523,6 +1550,13 @@ void em28xx_pre_card_setup(struct em28xx *dev) /* enables audio for that device */ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); break; + + case EM2874_BOARD_PINNACLE_PCTV_80E: + /* Set 400 KHz clock */ + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x45", 1); + + dev->digital_gpio = em2874_pinnacle_80e_digital; + break; } em28xx_gpio_set(dev, dev->tun_analog_gpio); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 12507422f..aa1588c22 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -98,6 +98,7 @@ #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 +#define EM2874_BOARD_PINNACLE_PCTV_80E 59 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3