From patchwork Thu Jul 29 16:06:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 115243 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6TG8lQJ005669 for ; Thu, 29 Jul 2010 16:08:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758013Ab0G2QI2 (ORCPT ); Thu, 29 Jul 2010 12:08:28 -0400 Received: from perceval.irobotique.be ([92.243.18.41]:36475 "EHLO perceval.irobotique.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757926Ab0G2QHE (ORCPT ); Thu, 29 Jul 2010 12:07:04 -0400 Received: from localhost.localdomain (unknown [91.178.154.203]) by perceval.irobotique.be (Postfix) with ESMTPSA id DE93035DF7; Thu, 29 Jul 2010 16:07:02 +0000 (UTC) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: sakari.ailus@maxwell.research.nokia.com Subject: [RFC/PATCH v3 02/10] media: Media device Date: Thu, 29 Jul 2010 18:06:35 +0200 Message-Id: <1280419616-7658-3-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1280419616-7658-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1280419616-7658-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 29 Jul 2010 16:08:49 +0000 (UTC) diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt new file mode 100644 index 0000000..b942c8f --- /dev/null +++ b/Documentation/media-framework.txt @@ -0,0 +1,68 @@ +Linux kernel media framework +============================ + +This document describes the Linux kernel media framework, its data structures, +functions and their usage. + + +Introduction +------------ + +Media devices increasingly handle multiple related functions. Many USB cameras +include microphones, video capture hardware can also output video, or SoC +camera interfaces also perform memory-to-memory operations similar to video +codecs. + +Independent functions, even when implemented in the same hardware, can be +modeled by separate devices. A USB camera with a microphone will be presented +to userspace applications as V4L2 and ALSA capture devices. The devices +relationships (when using a webcam, end-users shouldn't have to manually +select the associated USB microphone), while not made available directly to +applications by the drivers, can usually be retrieved from sysfs. + +With more and more advanced SoC devices being introduced, the current approach +will not scale. Device topologies are getting increasingly complex and can't +always be represented by a tree structure. Hardware blocks are shared between +different functions, creating dependencies between seemingly unrelated +devices. + +Kernel abstraction APIs such as V4L2 and ALSA provide means for applications +to access hardware parameters. As newer hardware expose an increasingly high +number of those parameters, drivers need to guess what applications really +require based on limited information, thereby implementing policies that +belong to userspace. + +The media kernel API aims at solving those problems. + + +Media device +------------ + +A media device is represented by a struct media_device instance, defined in +include/media/media-device.h. Allocation of the structure is handled by the +media device driver, usually by embedding the media_device instance in a +larger driver-specific structure. + +Drivers register media device instances by calling + + media_device_register(struct media_device *mdev); + +The caller is responsible for initializing the media_device structure before +registration. The following fields must be set: + + - dev should point to the parent device (usually a pci_dev, usb_interface or + platform_device instance). In the rare case when no parent device is + available (with ISA devices for instance), the field can be set to NULL. + - name should be set to the device name. If the name is empty a parent device + must be set. In that case the name will be set to the parent device driver + name followed by a space and the parent device name. + +Upon successful registration a character device named media[0-9]+ is created. +The device major and minor numbers are dynamic. + +Drivers unregister media device instances by calling + + media_device_unregister(struct media_device *mdev); + +Unregistering a media device that hasn't been registered is *NOT* safe. + diff --git a/drivers/media/Makefile b/drivers/media/Makefile index c1b5938..f8d8dcb 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel multimedia device drivers. # -media-objs := media-devnode.o +media-objs := media-device.o media-devnode.o obj-$(CONFIG_MEDIA_SUPPORT) += media.o diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c new file mode 100644 index 0000000..75eaccd --- /dev/null +++ b/drivers/media/media-device.c @@ -0,0 +1,76 @@ +/* + * Media device support. + * + * Copyright (C) 2010 Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include +#include + +static const struct media_file_operations media_device_fops = { + .owner = THIS_MODULE, +}; + +static void media_device_release(struct media_devnode *mdev) +{ +} + +/** + * media_device_register - register a media device + * @mdev: The media device + * + * The caller is responsible for initializing the media device before + * registration. The following fields must be set: + * + * - dev should point to the parent device. The field can be NULL when no + * parent device is available (for instance with ISA devices). + * - devnode.name should be set to the device name. If the name is empty a + * parent device must be set. In that case the name will be set to the parent + * device driver name followed by a space and the parent device name. + */ +int __must_check media_device_register(struct media_device *mdev) +{ + /* If dev == NULL, then name must be filled in by the caller */ + if (mdev->dev == NULL && WARN_ON(!mdev->devnode.name[0])) + return 0; + + /* Set name to driver name + device name if it is empty. */ + if (!mdev->devnode.name[0]) + snprintf(mdev->devnode.name, sizeof(mdev->devnode.name), + "%s %s", mdev->dev->driver->name, dev_name(mdev->dev)); + + /* Register the device node. */ + mdev->devnode.fops = &media_device_fops; + mdev->devnode.parent = mdev->dev; + mdev->devnode.release = media_device_release; + return media_devnode_register(&mdev->devnode); +} +EXPORT_SYMBOL_GPL(media_device_register); + +/** + * media_device_unregister - unregister a media device + * @mdev: The media device + * + */ +void media_device_unregister(struct media_device *mdev) +{ + media_devnode_unregister(&mdev->devnode); +} +EXPORT_SYMBOL_GPL(media_device_unregister); diff --git a/include/media/media-device.h b/include/media/media-device.h new file mode 100644 index 0000000..bd559b0 --- /dev/null +++ b/include/media/media-device.h @@ -0,0 +1,48 @@ +/* + * Media device support header. + * + * Copyright (C) 2010 Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _MEDIA_DEVICE_H +#define _MEDIA_DEVICE_H + +#include +#include + +#include + +/* Each instance of a media device should create the media_device struct, + * either stand-alone or embedded in a larger struct. + * + * It allows easy access to sub-devices (see v4l2-subdev.h) and provides + * basic media device-level support. + */ + +struct media_device { + /* dev->driver_data points to this struct. + * Note: dev might be NULL if there is no parent device + * as is the case with e.g. ISA devices. + */ + struct device *dev; + struct media_devnode devnode; +}; + +int __must_check media_device_register(struct media_device *mdev); +void media_device_unregister(struct media_device *mdev); + +#endif