From patchwork Tue Mar 16 02:50:59 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitri Belimov X-Patchwork-Id: 2937 Return-path: Envelope-to: mchehab@infradead.org Delivery-date: Tue, 16 Mar 2010 02:50:06 +0000 Received: from bombadil.infradead.org [18.85.46.34] by pedra with IMAP (fetchmail-6.3.6) for (single-drop); Mon, 15 Mar 2010 23:53:35 -0300 (BRT) Received: from vger.kernel.org ([209.132.180.67]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1NrMr8-0006W3-7u; Tue, 16 Mar 2010 02:50:06 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936905Ab0CPCuE (ORCPT + 1 other); Mon, 15 Mar 2010 22:50:04 -0400 Received: from mail-bw0-f209.google.com ([209.85.218.209]:58133 "EHLO mail-bw0-f209.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934469Ab0CPCuD (ORCPT ); Mon, 15 Mar 2010 22:50:03 -0400 Received: by bwz1 with SMTP id 1so3535801bwz.21 for ; Mon, 15 Mar 2010 19:50:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:subject :message-id:x-mailer:mime-version:content-type; bh=AfYLD+TAnXpFryoyhAtKjxCn88i233EYw/HKemO7BS0=; b=ftspeLeJnezHF2he4obaoEsaksi71TbyVfFyz1318TIV1VKp9bBy4Pod27KGK3sl/U UVRzlPwuxHUeqX3ywDYSq1eEe5z8hCaV2g8q0A4l8KTUgpsrgKvTB5R0+6Ns9ri3Djhg 8r+97Nh0VzPR+sv1eauXmMAUj/uo2wPzvQRfc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:subject:message-id:x-mailer:mime-version:content-type; b=VaPg2V6t5PztLPZDYK+8Y3p3ayZpoFAscrBSt5g4bnWjpQMTF3LwY1HbY25CKpdl7g P1Db1lvHsunjVpjQAVOON5PAPxKRFvyBQECGs0d+6kpaIo2tFlX9Z0CXYfSgFSj1/6IN 5lGflp8OrRFimL7FcrrGGegL4f1mw1V8b0B+0= Received: by 10.204.131.82 with SMTP id w18mr6644391bks.29.1268707800795; Mon, 15 Mar 2010 19:50:00 -0700 (PDT) Received: from glory.loctelecom.ru (ns2.openhardware.ru [84.19.183.172]) by mx.google.com with ESMTPS id x16sm23832734bku.23.2010.03.15.19.49.59 (version=SSLv3 cipher=RC4-MD5); Mon, 15 Mar 2010 19:50:00 -0700 (PDT) Date: Tue, 16 Mar 2010 11:50:59 +0900 From: Dmitri Belimov To: linux-media@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH] Add SPI support to V4L2 Message-ID: <20100316115059.7e1c0530@glory.loctelecom.ru> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.16.1; i486-pc-linux-gnu) Mime-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Hi Add support SPI bus to v4l2. Useful for control some device with SPI bus like hardware MPEG2 encoders and etc. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov With my best regards, Dmitry. diff -r b6b82258cf5e linux/drivers/media/video/v4l2-common.c --- a/linux/drivers/media/video/v4l2-common.c Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/v4l2-common.c Tue Mar 16 05:06:04 2010 +0900 @@ -63,6 +63,10 @@ #include #include "compat.h" + +#if defined(CONFIG_SPI) +#include +#endif MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr"); MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers"); @@ -1069,6 +1073,66 @@ #endif /* defined(CONFIG_I2C) */ +#if defined(CONFIG_SPI) + +/* Load a spi sub-device. */ + +void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, + const struct v4l2_subdev_ops *ops) +{ + v4l2_subdev_init(sd, ops); + sd->flags |= V4L2_SUBDEV_FL_IS_SPI; + /* the owner is the same as the spi_device's driver owner */ + sd->owner = spi->dev.driver->owner; + /* spi_device and v4l2_subdev point to one another */ + v4l2_set_subdevdata(sd, spi); + spi_set_drvdata(spi, sd); + /* initialize name */ + strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name)); +} +EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init); + +struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, + struct spi_master *master, struct spi_board_info *info) +{ + struct v4l2_subdev *sd = NULL; + struct spi_device *spi = NULL; + + BUG_ON(!v4l2_dev); + + if (info->modalias) + request_module(info->modalias); + + spi = spi_new_device(master, info); + + if (spi == NULL || spi->dev.driver == NULL) + goto error; + + if (!try_module_get(spi->dev.driver->owner)) + goto error; + + sd = spi_get_drvdata(spi); + + /* Register with the v4l2_device which increases the module's + use count as well. */ + if (v4l2_device_register_subdev(v4l2_dev, sd)) + sd = NULL; + + /* Decrease the module use count to match the first try_module_get. */ + module_put(spi->dev.driver->owner); + +error: + /* If we have a client but no subdev, then something went wrong and + we must unregister the client. */ + if (spi && sd == NULL) + spi_unregister_device(spi); + + return sd; +} +EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev); + +#endif /* defined(CONFIG_SPI) */ + /* Clamp x to be between min and max, aligned to a multiple of 2^align. min * and max don't have to be aligned, but there must be at least one valid * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples diff -r b6b82258cf5e linux/drivers/media/video/v4l2-device.c --- a/linux/drivers/media/video/v4l2-device.c Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/v4l2-device.c Tue Mar 16 05:06:04 2010 +0900 @@ -24,6 +24,10 @@ #include #include #include "compat.h" + +#if defined(CONFIG_SPI) +#include +#endif int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) { @@ -100,6 +104,14 @@ } #endif #endif +#if defined(CONFIG_SPI) + if (sd->flags & V4L2_SUBDEV_FL_IS_SPI) { + struct spi_device *spi = v4l2_get_subdevdata(sd); + + if (spi) + spi_unregister_device(spi); + } +#endif } } EXPORT_SYMBOL_GPL(v4l2_device_unregister); diff -r b6b82258cf5e linux/include/media/v4l2-common.h --- a/linux/include/media/v4l2-common.h Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/include/media/v4l2-common.h Tue Mar 16 05:06:04 2010 +0900 @@ -191,6 +191,24 @@ /* ------------------------------------------------------------------------- */ +/* SPI Helper functions */ +#if defined(CONFIG_SPI) + +#include + +struct spi_device; + +/* Load an spi module and return an initialized v4l2_subdev struct. + The client_type argument is the name of the chip that's on the adapter. */ +struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, + struct spi_master *master, struct spi_board_info *info); + +/* Initialize an v4l2_subdev with data from an spi_device struct */ +void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, + const struct v4l2_subdev_ops *ops); +#endif +/* ------------------------------------------------------------------------- */ + /* Note: these remaining ioctls/structs should be removed as well, but they are still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup diff -r b6b82258cf5e linux/include/media/v4l2-subdev.h --- a/linux/include/media/v4l2-subdev.h Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/include/media/v4l2-subdev.h Tue Mar 16 05:06:04 2010 +0900 @@ -387,6 +387,8 @@ /* Set this flag if this subdev is a i2c device. */ #define V4L2_SUBDEV_FL_IS_I2C (1U << 0) +/* Set this flag if this subdev is a spi device. */ +#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) /* Each instance of a subdev driver should create this struct, either stand-alone or embedded in a larger struct. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov