Commit 6d79468d authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (6951): Integrates em28xx-audio.c into em28xx kernel module

Also fixes the remaining CodingStyle issues that Lindent didn't fix.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 1a6f11e0
......@@ -11,3 +11,18 @@ config VIDEO_EM28XX
To compile this driver as a module, choose M here: the
module will be called em28xx
config VIDEO_EM28XX_ALSA
depends on VIDEO_EM28XX
tristate "Empia EM28xx ALSA audio module"
---help---
This is an ALSA driver for some Empia 28xx based TV cards.
This is not required for em2800/em2820/em2821 boards. However,
newer em28xx devices uses Vendor Class for audio, instead of
implementing the USB Audio Class. For those chips, this module
will enable digital audio.
To compile this driver as a module, choose M here: the
module will be called em28xx-alsa
em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
em28xx-input.o
em28xx-alsa-objs := em28xx-audio.o
obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
EXTRA_CFLAGS += -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
......
This diff is collapsed.
......@@ -1599,9 +1599,48 @@ static const struct video_device em28xx_video_template = {
.current_norm = V4L2_STD_PAL,
};
/******************************** usb interface *****************************************/
static LIST_HEAD(em28xx_extension_devlist);
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;
mutex_lock(&em28xx_extension_devlist_lock);
list_add_tail(&ops->next, &em28xx_extension_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;
list_for_each_entry(h, &em28xx_devlist, devlist)
dev = h;
if (dev)
ops->fini(dev);
mutex_lock(&em28xx_extension_devlist_lock);
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
list_del(&ops->next);
mutex_unlock(&em28xx_extension_devlist_lock);
}
EXPORT_SYMBOL(em28xx_unregister_extension);
/*
* em28xx_init_dev()
* allocates and inits the device structs, registers i2c bus and v4l device
......@@ -1609,6 +1648,7 @@ static const struct video_device em28xx_video_template = {
static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
int minor)
{
struct em28xx_ops *ops = NULL;
struct em28xx *dev = *devhandle;
int retval = -ENOMEM;
int errCode;
......@@ -1742,6 +1782,15 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
mutex_lock(&em28xx_extension_devlist_lock);
if (!list_empty(&em28xx_extension_devlist)) {
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->id)
ops->init(dev);
}
}
mutex_unlock(&em28xx_extension_devlist_lock);
return 0;
}
......@@ -1862,6 +1911,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
static void em28xx_usb_disconnect(struct usb_interface *interface)
{
struct em28xx *dev;
struct em28xx_ops *ops = NULL;
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
......@@ -1891,15 +1941,20 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
dev->state |= DEV_DISCONNECTED;
em28xx_release_resources(dev);
}
mutex_unlock(&dev->lock);
mutex_lock(&em28xx_extension_devlist_lock);
if (!list_empty(&em28xx_extension_devlist)) {
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
ops->fini(dev);
}
}
mutex_unlock(&em28xx_extension_devlist_lock);
if (!dev->users) {
kfree(dev->alt_max_pkt_size);
kfree(dev);
}
}
static struct usb_driver em28xx_usb_driver = {
......
......@@ -212,6 +212,28 @@ enum em28xx_dev_state {
DEV_MISCONFIGURED = 0x04,
};
#define EM28XX_AUDIO_BUFS 5
#define EM28XX_NUM_AUDIO_PACKETS 64
#define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */
#define EM28XX_CAPTURE_STREAM_EN 1
#define EM28XX_AUDIO 0x10
struct em28xx_audio {
char name[50];
char *transfer_buffer[EM28XX_AUDIO_BUFS];
struct urb *urb[EM28XX_AUDIO_BUFS];
struct usb_device *udev;
unsigned int capture_transfer_done;
struct snd_pcm_substream *capture_pcm_substream;
unsigned int hwptr_done_capture;
struct snd_card *sndcard;
int users, shutdown;
enum em28xx_stream_state capture_stream;
spinlock_t slock;
};
/* main device struct */
struct em28xx {
/* generic device properties */
......@@ -266,6 +288,8 @@ struct em28xx {
unsigned long hash; /* eeprom hash - for boards with generic ID */
unsigned long i2c_hash; /* i2c devicelist hash - for boards with generic ID */
struct em28xx_audio *adev;
/* states */
enum em28xx_dev_state state;
enum em28xx_stream_state stream;
......@@ -302,6 +326,15 @@ struct em28xx {
struct em28xx_fh {
struct em28xx *dev;
unsigned int stream_on:1; /* Locks streams */
int radio;
};
struct em28xx_ops {
struct list_head next;
char *name;
int id;
int (*init)(struct em28xx *);
int (*fini)(struct em28xx *);
};
/* Provided by em28xx-i2c.c */
......@@ -341,6 +374,10 @@ int em28xx_init_isoc(struct em28xx *dev);
void em28xx_uninit_isoc(struct em28xx *dev);
int em28xx_set_alternate(struct em28xx *dev);
/* Provided by em28xx-video.c */
int em28xx_register_extension(struct em28xx_ops *dev);
void em28xx_unregister_extension(struct em28xx_ops *dev);
/* Provided by em28xx-cards.c */
extern int em2800_variant_detect(struct usb_device* udev,int model);
extern void em28xx_pre_card_setup(struct em28xx *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment