public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 10/11] [media] em28xx: Add support for devices with a separate audio interface
       [not found] <cover.1308503857.git.mchehab@redhat.com>
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 01/11] [media] em28xx: Don't initialize a var if won't be using it Mauro Carvalho Chehab
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

Some devices use a separate interface for the vendor audio class.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 47f21a3..cff0768 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -3,9 +3,9 @@
  *
  *  Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com>
  *
- *  Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+ *  Copyright (C) 2007-2011 Mauro Carvalho Chehab <mchehab@redhat.com>
  *	- Port to work with the in-kernel driver
- *	- Several cleanups
+ *	- Cleanups, fixes, alsa-controls, etc.
  *
  *  This driver is based on my previous au600 usb pstn audio driver
  *  and inherits all the copyrights
@@ -281,24 +281,28 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
 		return -ENODEV;
 	}
 
-	/* Sets volume, mute, etc */
-
-	dev->mute = 0;
-	mutex_lock(&dev->lock);
-	ret = em28xx_audio_analog_set(dev);
-	if (ret < 0)
-		goto err;
-
 	runtime->hw = snd_em28xx_hw_capture;
-	if (dev->alt == 0 && dev->adev.users == 0) {
-		dev->alt = 7;
-		dprintk("changing alternate number to 7\n");
-		usb_set_interface(dev->udev, 0, 7);
+	if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) {
+		if (dev->audio_ifnum)
+			dev->alt = 1;
+		else
+			dev->alt = 7;
+
+		dprintk("changing alternate number on interface %d to %d\n",
+			dev->audio_ifnum, dev->alt);
+		usb_set_interface(dev->udev, dev->audio_ifnum, dev->alt);
+
+		/* Sets volume, mute, etc */
+		dev->mute = 0;
+		mutex_lock(&dev->lock);
+		ret = em28xx_audio_analog_set(dev);
+		if (ret < 0)
+			goto err;
+
+		dev->adev.users++;
+		mutex_unlock(&dev->lock);
 	}
 
-	dev->adev.users++;
-	mutex_unlock(&dev->lock);
-
 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 	dev->adev.capture_pcm_substream = substream;
 	runtime->private_data = dev;
@@ -635,17 +639,17 @@ static int em28xx_audio_init(struct em28xx *dev)
 	static int          devnr;
 	int                 err;
 
-	if (dev->has_alsa_audio != 1) {
+	if (!dev->has_alsa_audio || dev->audio_ifnum < 0) {
 		/* This device does not support the extension (in this case
 		   the device is expecting the snd-usb-audio module or
 		   doesn't have analog audio support at all) */
 		return 0;
 	}
 
-	printk(KERN_INFO "em28xx-audio.c: probing for em28x1 "
-			 "non standard usbaudio\n");
+	printk(KERN_INFO "em28xx-audio.c: probing for em28xx Audio Vendor Class\n");
 	printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
 			 "Rechberger\n");
+	printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2007-2011 Mauro Carvalho Chehab\n");
 
 	err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
 			      &card);
@@ -737,7 +741,7 @@ static void __exit em28xx_alsa_unregister(void)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
 MODULE_DESCRIPTION("Em28xx Audio driver");
 
 module_init(em28xx_alsa_register);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index bbd67d7..c445bea 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2846,6 +2846,16 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 		}
 	}
 
+	if (dev->is_audio_only) {
+		errCode = em28xx_audio_setup(dev);
+		if (errCode)
+			return -ENODEV;
+		em28xx_add_into_devlist(dev);
+		em28xx_init_extension(dev);
+
+		return 0;
+	}
+
 	/* Prepopulate cached GPO register content */
 	retval = em28xx_read_reg(dev, dev->reg_gpo_num);
 	if (retval >= 0)
@@ -2946,6 +2956,9 @@ fail_reg_devices:
 	return retval;
 }
 
+/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
+#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
+
 /*
  * em28xx_usb_probe()
  * checks for supported devices
@@ -2955,15 +2968,15 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 {
 	const struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *udev;
-	struct usb_interface *uif;
 	struct em28xx *dev = NULL;
 	int retval;
-	int i, nr, ifnum, isoc_pipe;
+	bool is_audio_only = false, has_audio = false;
+	int i, nr, isoc_pipe;
+	const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 	char *speed;
 	char descr[255] = "";
 
 	udev = usb_get_dev(interface_to_usbdev(interface));
-	ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 
 	/* Check to see next free device and mark as used */
 	nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
@@ -2983,6 +2996,19 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 		goto err;
 	}
 
+	/* Get endpoints */
+	for (i = 0; i < interface->num_altsetting; i++) {
+		int ep;
+
+		for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
+			struct usb_host_endpoint	*e;
+			e = &interface->altsetting[i].endpoint[ep];
+
+			if (e->desc.bEndpointAddress == 0x83)
+				has_audio = true;
+		}
+	}
+
 	endpoint = &interface->cur_altsetting->endpoint[0].desc;
 
 	/* check if the device has the iso in endpoint at the correct place */
@@ -3002,19 +3028,22 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 			check_interface = 0;
 
 		if (!check_interface) {
-			em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
-				"interface %i, class %i found.\n",
-				le16_to_cpu(udev->descriptor.idVendor),
-				le16_to_cpu(udev->descriptor.idProduct),
-				ifnum,
-				interface->altsetting[0].desc.bInterfaceClass);
+			if (has_audio) {
+				is_audio_only = true;
+			} else {
+				em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
+					"interface %i, class %i found.\n",
+					le16_to_cpu(udev->descriptor.idVendor),
+					le16_to_cpu(udev->descriptor.idProduct),
+					ifnum,
+					interface->altsetting[0].desc.bInterfaceClass);
+				em28xx_err(DRIVER_NAME " This is an anciliary "
+					"interface not used by the driver\n");
 
-			em28xx_err(DRIVER_NAME " This is an anciliary "
-				"interface not used by the driver\n");
-
-			em28xx_devused &= ~(1<<nr);
-			retval = -ENODEV;
-			goto err;
+				em28xx_devused &= ~(1<<nr);
+				retval = -ENODEV;
+				goto err;
+			}
 		}
 	}
 
@@ -3044,8 +3073,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 	if (*descr)
 		strlcat(descr, " ", sizeof(descr));
 
-	printk(DRIVER_NAME ": New device %s@ %s Mbps "
-		"(%04x:%04x, interface %d, class %d)\n",
+	printk(KERN_INFO DRIVER_NAME
+		": New device %s@ %s Mbps (%04x:%04x, interface %d, class %d)\n",
 		descr,
 		speed,
 		le16_to_cpu(udev->descriptor.idVendor),
@@ -3053,6 +3082,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 		ifnum,
 		interface->altsetting->desc.bInterfaceNumber);
 
+	if (has_audio)
+		printk(KERN_INFO DRIVER_NAME
+		       ": Audio Vendor Class interface %i found\n",
+		       ifnum);
+
 	/*
 	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
 	 * video stream wouldn't likely work, since 12 Mbps is generally
@@ -3088,10 +3122,13 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 	dev->devno = nr;
 	dev->model = id->driver_info;
 	dev->alt   = -1;
+	dev->is_audio_only = is_audio_only;
+	dev->has_alsa_audio = has_audio;
+	dev->audio_ifnum = ifnum;
 
 	/* Checks if audio is provided by some interface */
 	for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
-		uif = udev->config->interface[i];
+		struct usb_interface *uif = udev->config->interface[i];
 		if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
 			dev->has_audio_class = 1;
 			break;
@@ -3099,9 +3136,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 	}
 
 	/* compute alternate max packet sizes */
-	uif = udev->actconfig->interface[0];
-
-	dev->num_alt = uif->num_altsetting;
+	dev->num_alt = interface->num_altsetting;
 	dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
 
 	if (dev->alt_max_pkt_size == NULL) {
@@ -3113,14 +3148,21 @@ 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[isoc_pipe].desc.wMaxPacketSize);
-		dev->alt_max_pkt_size[i] =
-		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+		u16 tmp = le16_to_cpu(interface->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
+		unsigned int size = tmp & 0x7ff;
+
+		if (udev->speed == USB_SPEED_HIGH)
+			size = size * hb_mult(tmp);
+
+		dev->alt_max_pkt_size[i] = size;
 	}
 
 	if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
 		dev->model = card[nr];
 
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(interface, dev);
+
 	/* allocate device struct */
 	mutex_init(&dev->lock);
 	mutex_lock(&dev->lock);
@@ -3132,9 +3174,6 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 		goto err;
 	}
 
-	/* save our data pointer in this interface device */
-	usb_set_intfdata(interface, dev);
-
 	request_modules(dev);
 
 	/* Should be the last thing to do, to avoid newer udev's to
@@ -3163,6 +3202,13 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
 	if (!dev)
 		return;
 
+	if (dev->is_audio_only) {
+		mutex_lock(&dev->lock);
+		em28xx_close_extension(dev);
+		mutex_unlock(&dev->lock);
+		return;
+	}
+
 	em28xx_info("disconnecting %s\n", dev->vdev->name);
 
 	flush_request_modules(dev);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 752d4ed..16c9b73 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -499,17 +499,13 @@ int em28xx_audio_setup(struct em28xx *dev)
 	if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
 		|| dev->chip_id == CHIP_ID_EM28174) {
 		/* Digital only device - don't load any alsa module */
-		dev->audio_mode.has_audio = 0;
-		dev->has_audio_class = 0;
-		dev->has_alsa_audio = 0;
+		dev->audio_mode.has_audio = false;
+		dev->has_audio_class = false;
+		dev->has_alsa_audio = false;
 		return 0;
 	}
 
-	/* If device doesn't support Usb Audio Class, use vendor class */
-	if (!dev->has_audio_class)
-		dev->has_alsa_audio = 1;
-
-	dev->audio_mode.has_audio = 1;
+	dev->audio_mode.has_audio = true;
 
 	/* See how this device is configured */
 	cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
@@ -519,8 +515,8 @@ int em28xx_audio_setup(struct em28xx *dev)
 		cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */
 	} else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) {
 		/* The device doesn't have vendor audio at all */
-		dev->has_alsa_audio = 0;
-		dev->audio_mode.has_audio = 0;
+		dev->has_alsa_audio = false;
+		dev->audio_mode.has_audio = false;
 		return 0;
 	} else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
 		   EM28XX_CHIPCFG_I2S_3_SAMPRATES) {
@@ -549,8 +545,8 @@ int em28xx_audio_setup(struct em28xx *dev)
 		 */
 		em28xx_warn("AC97 chip type couldn't be determined\n");
 		dev->audio_mode.ac97 = EM28XX_NO_AC97;
-		dev->has_alsa_audio = 0;
-		dev->audio_mode.has_audio = 0;
+		dev->has_alsa_audio = false;
+		dev->audio_mode.has_audio = false;
 		goto init_audio;
 	}
 
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index f9b77b4..e03849f 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -487,6 +487,8 @@ struct em28xx {
 	int devno;		/* marks the number of this device */
 	enum em28xx_chip_id chip_id;
 
+	int audio_ifnum;
+
 	struct v4l2_device v4l2_dev;
 	struct em28xx_board board;
 
@@ -503,6 +505,7 @@ struct em28xx {
 
 	unsigned int has_audio_class:1;
 	unsigned int has_alsa_audio:1;
+	unsigned int is_audio_only:1;
 
 	/* Controls audio streaming */
 	struct work_struct wq_trigger;              /* Trigger to start/stop audio for alsa module */
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 01/11] [media] em28xx: Don't initialize a var if won't be using it
       [not found] <cover.1308503857.git.mchehab@redhat.com>
  2011-06-19 17:42 ` [PATCH 10/11] [media] em28xx: Add support for devices with a separate audio interface Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 11/11] [media] em28xx: Mark Kworld 305 as validated Mauro Carvalho Chehab
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Fixes most cases of initializing a var but not using it.

There are still 3 cases at em28xx-alsa, were those vars should
probably be used.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 3c48a72..a24e177 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -286,10 +286,9 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
 
 	runtime->hw = snd_em28xx_hw_capture;
 	if (dev->alt == 0 && dev->adev.users == 0) {
-		int errCode;
 		dev->alt = 7;
 		dprintk("changing alternate number to 7\n");
-		errCode = usb_set_interface(dev->udev, 0, 7);
+		usb_set_interface(dev->udev, 0, 7);
 	}
 
 	dev->adev.users++;
@@ -342,6 +341,8 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
 
 	ret = snd_pcm_alloc_vmalloc_buffer(substream,
 				params_buffer_bytes(hw_params));
+	if (ret < 0)
+		return ret;
 	format = params_format(hw_params);
 	rate = params_rate(hw_params);
 	channels = params_channels(hw_params);
@@ -393,7 +394,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
 	struct em28xx *dev = snd_pcm_substream_chip(substream);
-	int retval;
+	int retval = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -406,7 +407,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
 		retval = -EINVAL;
 	}
 	schedule_work(&dev->wq_trigger);
-	return 0;
+	return retval;
 }
 
 static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7635a45..bbd67d7 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2660,10 +2660,9 @@ void em28xx_card_setup(struct em28xx *dev)
 			.addr = 0xba >> 1,
 			.platform_data = &pdata,
 		};
-		struct v4l2_subdev *sd;
 
 		pdata.xtal = dev->sensor_xtal;
-		sd = v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
+		v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
 				&mt9v011_info, NULL);
 	}
 
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index e33f145..55d0d9d 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -917,7 +917,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode);
 static void em28xx_irq_callback(struct urb *urb)
 {
 	struct em28xx *dev = urb->context;
-	int rc, i;
+	int i;
 
 	switch (urb->status) {
 	case 0:             /* success */
@@ -934,7 +934,7 @@ static void em28xx_irq_callback(struct urb *urb)
 
 	/* Copy data from URB */
 	spin_lock(&dev->slock);
-	rc = dev->isoc_ctl.isoc_copy(dev, urb);
+	dev->isoc_ctl.isoc_copy(dev, urb);
 	spin_unlock(&dev->slock);
 
 	/* Reset urb buffers */
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 4739fc7..4ece685 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -218,9 +218,7 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
  */
 static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
 {
-	char msg;
 	int ret;
-	msg = addr;
 
 	ret = dev->em28xx_read_reg_req(dev, 2, addr);
 	if (ret < 0) {
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 11/11] [media] em28xx: Mark Kworld 305 as validated
       [not found] <cover.1308503857.git.mchehab@redhat.com>
  2011-06-19 17:42 ` [PATCH 10/11] [media] em28xx: Add support for devices with a separate audio interface Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 01/11] [media] em28xx: Don't initialize a var if won't be using it Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 02/11] [media] em28xx: Fix a wrong enum at the ac97 control tables Mauro Carvalho Chehab
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List

This board were used for testing the em28xx-alsa using a separate interface.
So, it is obviously validated ;)

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index c445bea..c892a1e 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1319,7 +1319,6 @@ struct em28xx_board em28xx_boards[] = {
 	},
 	[EM2880_BOARD_KWORLD_DVB_305U] = {
 		.name	      = "KWorld DVB-T 305U",
-		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.decoder      = EM28XX_TVP5150,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 02/11] [media] em28xx: Fix a wrong enum at the ac97 control tables
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (2 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 11/11] [media] em28xx: Mark Kworld 305 as validated Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 03/11] [media] em28xx: Allow to compile it without RC/input support Mauro Carvalho Chehab
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 55d0d9d..7bf3a86 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -314,12 +314,12 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val)
 	return 0;
 }
 
-struct em28xx_vol_table {
+struct em28xx_vol_itable {
 	enum em28xx_amux mux;
 	u8		 reg;
 };
 
-static struct em28xx_vol_table inputs[] = {
+static struct em28xx_vol_itable inputs[] = {
 	{ EM28XX_AMUX_VIDEO, 	AC97_VIDEO_VOL   },
 	{ EM28XX_AMUX_LINE_IN,	AC97_LINEIN_VOL  },
 	{ EM28XX_AMUX_PHONE,	AC97_PHONE_VOL   },
@@ -403,7 +403,12 @@ static int em28xx_set_audio_source(struct em28xx *dev)
 	return ret;
 }
 
-static const struct em28xx_vol_table outputs[] = {
+struct em28xx_vol_otable {
+	enum em28xx_aout mux;
+	u8		 reg;
+};
+
+static const struct em28xx_vol_otable outputs[] = {
 	{ EM28XX_AOUT_MASTER, AC97_MASTER_VOL      },
 	{ EM28XX_AOUT_LINE,   AC97_LINE_LEVEL_VOL  },
 	{ EM28XX_AOUT_MONO,   AC97_MASTER_MONO_VOL },
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 03/11] [media] em28xx: Allow to compile it without RC/input support
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (3 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 02/11] [media] em28xx: Fix a wrong enum at the ac97 control tables Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 07/11] [media] em28xx-audio: add debug info for the volume control Mauro Carvalho Chehab
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 3cb78f2..49878fd 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -3,7 +3,6 @@ config VIDEO_EM28XX
 	depends on VIDEO_DEV && I2C
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
-	depends on RC_CORE
 	select VIDEOBUF_VMALLOC
 	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
@@ -44,3 +43,12 @@ config VIDEO_EM28XX_DVB
 	---help---
 	  This adds support for DVB cards based on the
 	  Empiatech em28xx chips.
+
+config VIDEO_EM28XX_RC
+        bool "EM28XX Remote Controller support"
+        depends on RC_CORE
+        depends on VIDEO_EM28XX
+        depends on !(RC_CORE=m && VIDEO_EM28XX=y)
+        default y
+        ---help---
+          Enables Remote Controller support on em28xx driver.
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index d0f093d..38aaa00 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -1,5 +1,7 @@
-em28xx-objs     := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
-		   em28xx-input.o em28xx-vbi.o
+em28xx-y :=	em28xx-video.o em28xx-i2c.o em28xx-cards.o
+em28xx-y +=	em28xx-core.o  em28xx-vbi.o
+
+em28xx-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-input.o
 
 em28xx-alsa-objs := em28xx-audio.o
 
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 28b9954..f9b77b4 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -697,6 +697,9 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
 void em28xx_release_resources(struct em28xx *dev);
 
 /* Provided by em28xx-input.c */
+
+#ifdef CONFIG_VIDEO_EM28XX_RC
+
 int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
@@ -709,6 +712,20 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev);
 int em28xx_ir_init(struct em28xx *dev);
 int em28xx_ir_fini(struct em28xx *dev);
 
+#else
+
+#define em28xx_get_key_terratec			NULL
+#define em28xx_get_key_em_haup			NULL
+#define em28xx_get_key_pinnacle_usb_grey	NULL
+#define em28xx_get_key_winfast_usbii_deluxe	NULL
+
+static inline void em28xx_register_snapshot_button(struct em28xx *dev) {}
+static inline void em28xx_deregister_snapshot_button(struct em28xx *dev) {}
+static inline int em28xx_ir_init(struct em28xx *dev) { return 0; }
+static inline int em28xx_ir_fini(struct em28xx *dev) { return 0; }
+
+#endif
+
 /* Provided by em28xx-vbi.c */
 extern struct videobuf_queue_ops em28xx_vbi_qops;
 
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 07/11] [media] em28xx-audio: add debug info for the volume control
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (4 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 03/11] [media] em28xx: Allow to compile it without RC/input support Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 08/11] [media] em28xx-audio: Properly report failures to start stream Mauro Carvalho Chehab
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 302553a..56739a4 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -464,6 +464,13 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
 	val |= rc & 0x8000;	/* Preserve the mute flag */
 
 	rc = em28xx_write_ac97(dev, kcontrol->private_value, val);
+	if (rc < 0)
+		goto err;
+
+	dprintk("%sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x\n",
+		(val & 0x8000) ? "muted " : "",
+		0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
+		val, (int)kcontrol->private_value);
 
 err:
 	mutex_unlock(&dev->lock);
@@ -482,6 +489,11 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
 	if (val < 0)
 		return val;
 
+	dprintk("%sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x\n",
+		(val & 0x8000) ? "muted " : "",
+		0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
+		val, (int)kcontrol->private_value);
+
 	value->value.integer.value[0] = 0x1f - (val & 0x1f);
 	value->value.integer.value[1] = 0x1f - ((val << 8) & 0x1f);
 
@@ -506,6 +518,13 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol,
 		rc |= 0x8000;
 
 	rc = em28xx_write_ac97(dev, kcontrol->private_value, rc);
+	if (rc < 0)
+		goto err;
+
+	dprintk("%sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x\n",
+		(val & 0x8000) ? "muted " : "",
+		0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
+		val, (int)kcontrol->private_value);
 
 err:
 	mutex_unlock(&dev->lock);
@@ -529,6 +548,11 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol,
 	else
 		value->value.integer.value[0] = 1;
 
+	dprintk("%sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x\n",
+		(val & 0x8000) ? "muted " : "",
+		0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
+		val, (int)kcontrol->private_value);
+
 	return 0;
 }
 
@@ -556,6 +580,8 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
 	err = snd_ctl_add(card, kctl);
 	if (err < 0)
 		return err;
+	dprintk("Added control %s for ac97 volume control 0x%04x\n",
+		ctl_name, id);
 
 	memset (&tmp, 0, sizeof(tmp));
 	tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -572,6 +598,8 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
 	err = snd_ctl_add(card, kctl);
 	if (err < 0)
 		return err;
+	dprintk("Added control %s for ac97 volume control 0x%04x\n",
+		ctl_name, id);
 
 	return 0;
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 08/11] [media] em28xx-audio: Properly report failures to start stream
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (5 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 07/11] [media] em28xx-audio: add debug info for the volume control Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 04/11] [media] em28xx-alsa: add mixer support for AC97 volume controls Mauro Carvalho Chehab
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

If the audio stream fails for any reason, it should:
	1) Report an error via dmesg;
	2) Mark internally that the stream didn't started.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 56739a4..5381f6d 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -213,9 +213,12 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
 	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
 		errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
 		if (errCode) {
+			em28xx_errdev("submit of audio urb failed\n");
 			em28xx_deinit_isoc_audio(dev);
+			atomic_set(&dev->stream_started, 0);
 			return errCode;
 		}
+
 	}
 
 	return 0;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 04/11] [media] em28xx-alsa: add mixer support for AC97 volume controls
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (6 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 08/11] [media] em28xx-audio: Properly report failures to start stream Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 05/11] [media] em28xx-audio: add support for mute controls Mauro Carvalho Chehab
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

Export ac97 volume controls via mixer.

Pulseaudio will probably handle it very badly, as it has
no idea about how volumes are wired, and how are they
associated with each TV input. Those wirings are
card model dependent, and we don't have the wiring mappings
for each supported device.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index a24e177..a75c779 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -41,6 +41,7 @@
 #include <sound/info.h>
 #include <sound/initval.h>
 #include <sound/control.h>
+#include <sound/tlv.h>
 #include <media/v4l2-common.h>
 #include "em28xx.h"
 
@@ -433,6 +434,92 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
 	return vmalloc_to_page(pageptr);
 }
 
+/*
+ * AC97 volume control support
+ */
+static int em28xx_vol_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *info)
+{
+	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	info->count = 2;
+	info->value.integer.min = 0;
+	info->value.integer.max = 0x1f;
+
+	return 0;
+}
+
+/* FIXME: should also add mute controls for each */
+
+static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	struct em28xx *dev = snd_kcontrol_chip(kcontrol);
+	u16 val = (value->value.integer.value[0] & 0x1f) |
+		  (value->value.integer.value[1] & 0x1f) << 8;
+	int rc;
+
+	mutex_lock(&dev->lock);
+	rc = em28xx_read_ac97(dev, kcontrol->private_value);
+	if (rc < 0)
+		goto err;
+
+	val |= rc & 0x8080;	/* Preserve the mute flags */
+
+	rc = em28xx_write_ac97(dev, kcontrol->private_value, val);
+
+err:
+	mutex_unlock(&dev->lock);
+	return rc;
+}
+
+static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	struct em28xx *dev = snd_kcontrol_chip(kcontrol);
+	int val;
+
+	mutex_lock(&dev->lock);
+	val = em28xx_read_ac97(dev, kcontrol->private_value);
+	mutex_unlock(&dev->lock);
+	if (val < 0)
+		return val;
+
+	value->value.integer.value[0] = val & 0x1f;
+	value->value.integer.value[1] = (val << 8) & 0x1f;
+
+	return 0;
+}
+
+static const DECLARE_TLV_DB_SCALE(em28xx_db_scale, -3450, 150, 0);
+
+static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
+			   char *name, int id)
+{
+	int err;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_new tmp = {
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name  = name,
+		.info  = em28xx_vol_info,
+		.get   = em28xx_vol_get,
+		.put   = em28xx_vol_put,
+		.private_value = id,
+		.tlv.p = em28xx_db_scale,
+	};
+
+	kctl = snd_ctl_new1(&tmp, dev);
+
+	err = snd_ctl_add(card, kctl);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+
+/*
+ * register/unregister code and data
+ */
 static struct snd_pcm_ops snd_em28xx_pcm_capture = {
 	.open      = snd_em28xx_capture_open,
 	.close     = snd_em28xx_pcm_close,
@@ -489,6 +576,22 @@ static int em28xx_audio_init(struct em28xx *dev)
 
 	INIT_WORK(&dev->wq_trigger, audio_trigger);
 
+	if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
+		em28xx_cvol_new(card, dev, "Video", AC97_VIDEO_VOL);
+		em28xx_cvol_new(card, dev, "Line In", AC97_LINEIN_VOL);
+		em28xx_cvol_new(card, dev, "Phone", AC97_PHONE_VOL);
+		em28xx_cvol_new(card, dev, "Microphone", AC97_PHONE_VOL);
+		em28xx_cvol_new(card, dev, "CD", AC97_CD_VOL);
+		em28xx_cvol_new(card, dev, "AUX", AC97_AUX_VOL);
+		em28xx_cvol_new(card, dev, "PCM", AC97_PCM_OUT_VOL);
+
+		em28xx_cvol_new(card, dev, "Master", AC97_MASTER_VOL);
+		em28xx_cvol_new(card, dev, "Line", AC97_LINE_LEVEL_VOL);
+		em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO_VOL);
+		em28xx_cvol_new(card, dev, "LFE", AC97_LFE_MASTER_VOL);
+		em28xx_cvol_new(card, dev, "Surround", AC97_SURR_MASTER_VOL);
+	}
+
 	err = snd_card_register(card);
 	if (err < 0) {
 		snd_card_free(card);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 7bf3a86..752d4ed 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -286,6 +286,7 @@ int em28xx_read_ac97(struct em28xx *dev, u8 reg)
 		return ret;
 	return le16_to_cpu(val);
 }
+EXPORT_SYMBOL_GPL(em28xx_read_ac97);
 
 /*
  * em28xx_write_ac97()
@@ -313,6 +314,7 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(em28xx_write_ac97);
 
 struct em28xx_vol_itable {
 	enum em28xx_amux mux;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 05/11] [media] em28xx-audio: add support for mute controls
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (7 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 04/11] [media] em28xx-alsa: add mixer support for AC97 volume controls Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 06/11] [media] em28xx-audio: volumes are inverted Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 09/11] [media] em28xx-audio: Some Alsa API fixes Mauro Carvalho Chehab
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index a75c779..c7b96b4 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -448,8 +448,6 @@ static int em28xx_vol_info(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-/* FIXME: should also add mute controls for each */
-
 static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *value)
 {
@@ -463,7 +461,7 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
 	if (rc < 0)
 		goto err;
 
-	val |= rc & 0x8080;	/* Preserve the mute flags */
+	val |= rc & 0x8000;	/* Preserve the mute flag */
 
 	rc = em28xx_write_ac97(dev, kcontrol->private_value, val);
 
@@ -490,25 +488,87 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	struct em28xx *dev = snd_kcontrol_chip(kcontrol);
+	u16 val = value->value.integer.value[0];
+	int rc;
+
+	mutex_lock(&dev->lock);
+	rc = em28xx_read_ac97(dev, kcontrol->private_value);
+	if (rc < 0)
+		goto err;
+
+	if (val)
+		rc |= 0x8000;
+	else
+		rc &= 0x7f7f;
+
+	rc = em28xx_write_ac97(dev, kcontrol->private_value, rc);
+
+err:
+	mutex_unlock(&dev->lock);
+	return rc;
+}
+
+static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	struct em28xx *dev = snd_kcontrol_chip(kcontrol);
+	int val;
+
+	mutex_lock(&dev->lock);
+	val = em28xx_read_ac97(dev, kcontrol->private_value);
+	mutex_unlock(&dev->lock);
+	if (val < 0)
+		return val;
+
+	if (val & 0x8000)
+		value->value.integer.value[0] = 1;
+	else
+		value->value.integer.value[0] = 0;
+
+	return 0;
+}
+
 static const DECLARE_TLV_DB_SCALE(em28xx_db_scale, -3450, 150, 0);
 
 static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
 			   char *name, int id)
 {
 	int err;
+	char ctl_name[44];
 	struct snd_kcontrol *kctl;
-	struct snd_kcontrol_new tmp = {
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name  = name,
-		.info  = em28xx_vol_info,
-		.get   = em28xx_vol_get,
-		.put   = em28xx_vol_put,
-		.private_value = id,
-		.tlv.p = em28xx_db_scale,
-	};
+	struct snd_kcontrol_new tmp;
 
+	memset (&tmp, 0, sizeof(tmp));
+	tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	tmp.private_value = id,
+	tmp.name  = ctl_name,
+
+	/* Add Mute Control */
+	sprintf(ctl_name, "%s Switch", name);
+	tmp.get  = em28xx_vol_get_mute;
+	tmp.put  = em28xx_vol_put_mute;
+	tmp.info = snd_ctl_boolean_mono_info;
 	kctl = snd_ctl_new1(&tmp, dev);
+	err = snd_ctl_add(card, kctl);
+	if (err < 0)
+		return err;
+
+	memset (&tmp, 0, sizeof(tmp));
+	tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	tmp.private_value = id,
+	tmp.name  = ctl_name,
 
+	/* Add Volume Control */
+	sprintf(ctl_name, "%s Volume", name);
+	tmp.get   = em28xx_vol_get;
+	tmp.put   = em28xx_vol_put;
+	tmp.info  = em28xx_vol_info;
+	tmp.tlv.p = em28xx_db_scale,
+	kctl = snd_ctl_new1(&tmp, dev);
 	err = snd_ctl_add(card, kctl);
 	if (err < 0)
 		return err;
@@ -516,7 +576,6 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
 	return 0;
 }
 
-
 /*
  * register/unregister code and data
  */
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 06/11] [media] em28xx-audio: volumes are inverted
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (8 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 05/11] [media] em28xx-audio: add support for mute controls Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  2011-06-19 17:42 ` [PATCH 09/11] [media] em28xx-audio: Some Alsa API fixes Mauro Carvalho Chehab
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

While here, fix volume mask to 5 bits

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index c7b96b4..302553a 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -452,8 +452,8 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *value)
 {
 	struct em28xx *dev = snd_kcontrol_chip(kcontrol);
-	u16 val = (value->value.integer.value[0] & 0x1f) |
-		  (value->value.integer.value[1] & 0x1f) << 8;
+	u16 val = (0x1f - (value->value.integer.value[0] & 0x1f)) |
+		  (0x1f - (value->value.integer.value[1] & 0x1f)) << 8;
 	int rc;
 
 	mutex_lock(&dev->lock);
@@ -482,8 +482,8 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
 	if (val < 0)
 		return val;
 
-	value->value.integer.value[0] = val & 0x1f;
-	value->value.integer.value[1] = (val << 8) & 0x1f;
+	value->value.integer.value[0] = 0x1f - (val & 0x1f);
+	value->value.integer.value[1] = 0x1f - ((val << 8) & 0x1f);
 
 	return 0;
 }
@@ -501,9 +501,9 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol,
 		goto err;
 
 	if (val)
+		rc &= 0x1f1f;
+	else
 		rc |= 0x8000;
-	else
-		rc &= 0x7f7f;
 
 	rc = em28xx_write_ac97(dev, kcontrol->private_value, rc);
 
@@ -525,9 +525,9 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol,
 		return val;
 
 	if (val & 0x8000)
-		value->value.integer.value[0] = 1;
-	else
 		value->value.integer.value[0] = 0;
+	else
+		value->value.integer.value[0] = 1;
 
 	return 0;
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 09/11] [media] em28xx-audio: Some Alsa API fixes
       [not found] <cover.1308503857.git.mchehab@redhat.com>
                   ` (9 preceding siblings ...)
  2011-06-19 17:42 ` [PATCH 06/11] [media] em28xx-audio: volumes are inverted Mauro Carvalho Chehab
@ 2011-06-19 17:42 ` Mauro Carvalho Chehab
  10 siblings, 0 replies; 11+ messages in thread
From: Mauro Carvalho Chehab @ 2011-06-19 17:42 UTC (permalink / raw)
  Cc: Linux Media Mailing List, alsa-devel

Mark the alsa stream with SNDRV_PCM_INFO_BATCH,
as the timing to get audio streams can vary.

Also, add SNDRV_PCM_TRIGGER for pause/release.

while here, fix the stop indicator, to be sure that audio
will be properly released at the stop events.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 5381f6d..47f21a3 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -249,6 +249,7 @@ static struct snd_pcm_hardware snd_em28xx_hw_capture = {
 	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
 		SNDRV_PCM_INFO_MMAP           |
 		SNDRV_PCM_INFO_INTERLEAVED    |
+		SNDRV_PCM_INFO_BATCH	      |
 		SNDRV_PCM_INFO_MMAP_VALID,
 
 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -401,11 +402,15 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
 	int retval = 0;
 
 	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
+	case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
 	case SNDRV_PCM_TRIGGER_START:
 		atomic_set(&dev->stream_started, 1);
 		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
+	case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
 	case SNDRV_PCM_TRIGGER_STOP:
-		atomic_set(&dev->stream_started, 1);
+		atomic_set(&dev->stream_started, 0);
 		break;
 	default:
 		retval = -EINVAL;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-06-19 17:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <cover.1308503857.git.mchehab@redhat.com>
2011-06-19 17:42 ` [PATCH 10/11] [media] em28xx: Add support for devices with a separate audio interface Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 01/11] [media] em28xx: Don't initialize a var if won't be using it Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 11/11] [media] em28xx: Mark Kworld 305 as validated Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 02/11] [media] em28xx: Fix a wrong enum at the ac97 control tables Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 03/11] [media] em28xx: Allow to compile it without RC/input support Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 07/11] [media] em28xx-audio: add debug info for the volume control Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 08/11] [media] em28xx-audio: Properly report failures to start stream Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 04/11] [media] em28xx-alsa: add mixer support for AC97 volume controls Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 05/11] [media] em28xx-audio: add support for mute controls Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 06/11] [media] em28xx-audio: volumes are inverted Mauro Carvalho Chehab
2011-06-19 17:42 ` [PATCH 09/11] [media] em28xx-audio: Some Alsa API fixes Mauro Carvalho Chehab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox