Data type declarations - Can be moded to a header file later
****************************************************************************/
-static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
static int devno;
struct cx25821_audio_buffer {
MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
-/*
- * Not used in the function snd_cx25821_dev_free so removing
- * from the file.
- */
-/*
-static int snd_cx25821_free(struct cx25821_audio_dev *chip)
-{
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- cx25821_dev_unregister(chip->dev);
- pci_disable_device(chip->pci);
-
- return 0;
-}
-*/
-
-/*
- * Component Destructor
- */
-static void snd_cx25821_dev_free(struct snd_card *card)
-{
- struct cx25821_audio_dev *chip = card->private_data;
-
- /* snd_cx25821_free(chip); */
- snd_card_free(chip->card);
-}
-
/*
* Alsa Constructor - Component probe
*/
strcpy(card->driver, "cx25821");
/* Card "creation" */
- card->private_free = snd_cx25821_dev_free;
chip = card->private_data;
spin_lock_init(&chip->reg_lock);
goto error;
}
- snd_cx25821_cards[devno] = card;
-
+ dev->card = card;
devno++;
return 0;
/****************************************************************************
LINUX MODULE INIT
****************************************************************************/
+
+static int cx25821_alsa_exit_callback(struct device *dev, void *data)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+ struct cx25821_dev *cxdev = get_cx25821(v4l2_dev);
+
+ snd_card_free(cxdev->card);
+ return 0;
+}
+
static void cx25821_audio_fini(void)
{
- snd_card_free(snd_cx25821_cards[0]);
+ struct device_driver *drv = driver_find("cx25821", &pci_bus_type);
+ int ret;
+
+ ret = driver_for_each_device(drv, NULL, NULL, cx25821_alsa_exit_callback);
+}
+
+static int cx25821_alsa_init_callback(struct device *dev, void *data)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+ struct cx25821_dev *cxdev = get_cx25821(v4l2_dev);
+
+ cx25821_audio_initdev(cxdev);
+ return 0;
}
/*
*/
static int cx25821_alsa_init(void)
{
- struct cx25821_dev *dev = NULL;
- struct list_head *list;
+ struct device_driver *drv = driver_find("cx25821", &pci_bus_type);
- mutex_lock(&cx25821_devlist_mutex);
- list_for_each(list, &cx25821_devlist) {
- dev = list_entry(list, struct cx25821_dev, devlist);
- cx25821_audio_initdev(dev);
- }
- mutex_unlock(&cx25821_devlist_mutex);
-
- if (dev == NULL)
- pr_info("ERROR ALSA: no cx25821 cards found\n");
-
- return 0;
+ return driver_for_each_device(drv, NULL, NULL, cx25821_alsa_init_callback);
}
late_initcall(cx25821_alsa_init);
module_exit(cx25821_audio_fini);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(card, "card type");
-static unsigned int cx25821_devcount;
-
-DEFINE_MUTEX(cx25821_devlist_mutex);
-EXPORT_SYMBOL(cx25821_devlist_mutex);
-LIST_HEAD(cx25821_devlist);
-EXPORT_SYMBOL(cx25821_devlist);
-
const struct sram_channel cx25821_sram_channels[] = {
[SRAM_CH00] = {
.i = SRAM_CH00,
static int cx25821_dev_setup(struct cx25821_dev *dev)
{
+ static unsigned int cx25821_devcount;
int i;
pr_info("\n***********************************\n");
mutex_init(&dev->lock);
- atomic_inc(&dev->refcount);
-
dev->nr = ++cx25821_devcount;
sprintf(dev->name, "cx25821[%d]", dev->nr);
- mutex_lock(&cx25821_devlist_mutex);
- list_add_tail(&dev->devlist, &cx25821_devlist);
- mutex_unlock(&cx25821_devlist_mutex);
-
if (dev->pci->device != 0x8210) {
pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
__func__, dev->pci->device);
release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
- if (!atomic_dec_and_test(&dev->refcount))
- return;
-
for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) {
if (i == SRAM_CH08) /* audio channel */
continue;
if (pci_dev->irq)
free_irq(pci_dev->irq, dev);
- mutex_lock(&cx25821_devlist_mutex);
- list_del(&dev->devlist);
- mutex_unlock(&cx25821_devlist_mutex);
-
cx25821_dev_unregister(dev);
v4l2_device_unregister(v4l2_dev);
kfree(dev);
static int video_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *h, *dev = video_drvdata(file);
+ struct cx25821_dev *dev = video_drvdata(file);
struct cx25821_fh *fh;
- struct list_head *list;
- int minor = video_devdata(file)->minor;
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
u32 pix_format;
- int ch_id = 0;
- int i;
+ int ch_id;
dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev),
v4l2_type_names[type]);
+ for (ch_id = 0; ch_id < MAX_VID_CHANNEL_NUM - 1; ch_id++)
+ if (dev->channels[ch_id].video_dev == vdev)
+ break;
+
+ /* Can't happen */
+ if (ch_id >= MAX_VID_CHANNEL_NUM - 1)
+ return -ENODEV;
+
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (NULL == fh)
return -ENOMEM;
- mutex_lock(&cx25821_devlist_mutex);
-
- list_for_each(list, &cx25821_devlist)
- {
- h = list_entry(list, struct cx25821_dev, devlist);
-
- for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) {
- if (h->channels[i].video_dev &&
- h->channels[i].video_dev->minor == minor) {
- dev = h;
- ch_id = i;
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- }
- }
- }
-
- if (NULL == dev) {
- mutex_unlock(&cx25821_devlist_mutex);
- kfree(fh);
- return -ENODEV;
- }
-
file->private_data = fh;
fh->dev = dev;
fh->type = type;
fh, NULL);
dprintk(1, "post videobuf_queue_init()\n");
- mutex_unlock(&cx25821_devlist_mutex);
return 0;
}
int cif_width;
};
+struct snd_card;
+
struct cx25821_dev {
- struct list_head devlist;
- atomic_t refcount;
struct v4l2_device v4l2_dev;
/* pci stuff */
u8 __iomem *bmmio;
int pci_irqmask;
int hwrevision;
+ /* used by cx25821-alsa */
+ struct snd_card *card;
u32 clk_freq;
#define cx25821_call_all(dev, o, f, args...) \
v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
-extern struct list_head cx25821_devlist;
-extern struct mutex cx25821_devlist_mutex;
-
extern struct cx25821_board cx25821_boards[];
extern struct cx25821_subid cx25821_subids[];