From patchwork Mon Feb 14 12:20:57 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 555311 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p1ECPq2s031238 for ; Mon, 14 Feb 2011 12:25:54 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753942Ab1BNMZj (ORCPT ); Mon, 14 Feb 2011 07:25:39 -0500 Received: from perceval.ideasonboard.com ([95.142.166.194]:58169 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753889Ab1BNMVM (ORCPT ); Mon, 14 Feb 2011 07:21:12 -0500 Received: from localhost.localdomain (unknown [91.178.218.226]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 36D22359E7; Mon, 14 Feb 2011 12:21:10 +0000 (UTC) From: Laurent Pinchart To: linux-media@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Cc: sakari.ailus@maxwell.research.nokia.com Subject: [PATCH v9 02/12] media: Media device Date: Mon, 14 Feb 2011 13:20:57 +0100 Message-Id: <1297686067-9666-3-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1297686067-9666-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1297686067-9666-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.6 (demeter1.kernel.org [140.211.167.41]); Mon, 14 Feb 2011 12:25:54 +0000 (UTC) diff --git a/Documentation/ABI/testing/sysfs-bus-media b/Documentation/ABI/testing/sysfs-bus-media new file mode 100644 index 0000000..7057e57 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-media @@ -0,0 +1,6 @@ +What: /sys/bus/media/devices/.../model +Date: January 2011 +Contact: Laurent Pinchart + linux-media@vger.kernel.org +Description: Contains the device model name in UTF-8. The device version is + is not be appended to the model name. diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index be34dcb..61d6f11 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl @@ -321,6 +321,8 @@ + + diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl index a99088a..88f2cc6 100644 --- a/Documentation/DocBook/media.tmpl +++ b/Documentation/DocBook/media.tmpl @@ -106,6 +106,9 @@ Foundation. A copy of the license is included in the chapter entitled &sub-remote_controllers; + +&sub-media-controller; + &sub-fdl-appendix; diff --git a/Documentation/DocBook/v4l/media-controller.xml b/Documentation/DocBook/v4l/media-controller.xml new file mode 100644 index 0000000..253ddb4 --- /dev/null +++ b/Documentation/DocBook/v4l/media-controller.xml @@ -0,0 +1,56 @@ + + + + Laurent + Pinchart +
laurent.pinchart@ideasonboard.com
+ Initial version. +
+
+ + 2010 + Laurent Pinchart + + + + + + 1.0.0 + 2010-11-10 + lp + Initial revision + + +
+ +Media Controller API + + + Media Controller + +
+ 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 modelled as 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 controller API aims at solving those problems. +
+
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt new file mode 100644 index 0000000..1844c3f --- /dev/null +++ b/Documentation/media-framework.txt @@ -0,0 +1,67 @@ +Linux kernel media framework +============================ + +This document describes the Linux kernel media framework, its data structures, +functions and their usage. + + +Introduction +------------ + +The media controller API is documented in DocBook format in +Documentation/DocBook/v4l/media-controller.xml. This document will focus on +the kernel-side implementation of the media framework. + + +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 must point to the parent device (usually a pci_dev, usb_interface or + platform_device instance). + + - model must be filled with the device model name as a NUL-terminated UTF-8 + string. The device/model revision must not be stored in this field. + +The following fields are optional: + + - serial is a unique serial number stored as a NUL-terminated ASCII string. + The field is big enough to store a GUID in text form. If the hardware + doesn't provide a unique serial number this field must be left empty. + + - bus_info represents the location of the device in the system as a + NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to + "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, + the usb_make_path() function must be used. This field is used by + applications to distinguish between otherwise identical devices that don't + provide a serial number. + + - hw_revision is the hardware device revision in a driver-specific format. + When possible the revision should be formatted with the KERNEL_VERSION + macro. + + - driver_version is formatted with the KERNEL_VERSION macro. The version + minor must be incremented when new features are added to the userspace API + without breaking binary compatibility. The version major must be + incremented when binary compatibility is broken. + +Upon successful registration a character device named media[0-9]+ is created. +The device major and minor numbers are dynamic. The model name is exported as +a sysfs attribute. + +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 d56349f..36731aa 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 ifeq ($(CONFIG_MEDIA_CONTROLLER),y) 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..bcd3985 --- /dev/null +++ b/drivers/media/media-device.c @@ -0,0 +1,100 @@ +/* + * Media device + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, +}; + +/* ----------------------------------------------------------------------------- + * sysfs + */ + +static ssize_t show_model(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct media_device *mdev = to_media_device(to_media_devnode(cd)); + + return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model); +} + +static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); + +/* ----------------------------------------------------------------------------- + * Registration/unregistration + */ + +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 must point to the parent device + * - model must be filled with the device model name + */ +int __must_check media_device_register(struct media_device *mdev) +{ + int ret; + + if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) + return -EINVAL; + + /* Register the device node. */ + mdev->devnode.fops = &media_device_fops; + mdev->devnode.parent = mdev->dev; + mdev->devnode.release = media_device_release; + ret = media_devnode_register(&mdev->devnode); + if (ret < 0) + return ret; + + ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); + if (ret < 0) { + media_devnode_unregister(&mdev->devnode); + return ret; + } + + return 0; +} +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) +{ + device_remove_file(&mdev->devnode.dev, &dev_attr_model); + 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..30857f7 --- /dev/null +++ b/include/media/media-device.h @@ -0,0 +1,69 @@ +/* + * Media device + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 + +/** + * struct media_device - Media device + * @dev: Parent device + * @devnode: Media device node + * @model: Device model name + * @serial: Device serial number (optional) + * @bus_info: Unique and stable device location identifier + * @hw_revision: Hardware device revision + * @driver_version: Device driver version + * + * This structure represents an abstract high-level media device. It allows easy + * access to entities and provides basic media device-level support. The + * structure can be allocated directly or embedded in a larger structure. + * + * The parent @dev is a physical device. It must be set before registering the + * media device. + * + * @model is a descriptive model name exported through sysfs. It doesn't have to + * be unique. + */ +struct media_device { + /* dev->driver_data points to this struct. */ + struct device *dev; + struct media_devnode devnode; + + char model[32]; + char serial[40]; + char bus_info[32]; + u32 hw_revision; + u32 driver_version; +}; + +/* media_devnode to media_device */ +#define to_media_device(node) container_of(node, struct media_device, devnode) + +int __must_check media_device_register(struct media_device *mdev); +void media_device_unregister(struct media_device *mdev); + +#endif