From patchwork Thu Apr 18 21:35:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 2462641 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 73487DF2E5 for ; Thu, 18 Apr 2013 21:36:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936542Ab3DRVgW (ORCPT ); Thu, 18 Apr 2013 17:36:22 -0400 Received: from moutng.kundenserver.de ([212.227.126.186]:49228 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S936498Ab3DRVgB (ORCPT ); Thu, 18 Apr 2013 17:36:01 -0400 Received: from axis700.grange (dslb-088-077-162-170.pools.arcor-ip.net [88.77.162.170]) by mrelayeu.kundenserver.de (node=mrbap0) with ESMTP (Nemesis) id 0Lsfxh-1UeG8b2Kdt-012LH5; Thu, 18 Apr 2013 23:35:57 +0200 Received: from 6a.grange (6a.grange [192.168.1.11]) by axis700.grange (Postfix) with ESMTPS id 7DCB340BCC; Thu, 18 Apr 2013 23:35:55 +0200 (CEST) Received: from lyakh by 6a.grange with local (Exim 4.72) (envelope-from ) id 1USwUl-0005ds-1S; Thu, 18 Apr 2013 23:35:55 +0200 From: Guennadi Liakhovetski To: linux-media@vger.kernel.org Cc: Laurent Pinchart , Guennadi Liakhovetski Subject: [PATCH 16/24] V4L2: mt9p031: add support for V4L2 clock and asynchronous probing Date: Thu, 18 Apr 2013 23:35:37 +0200 Message-Id: <1366320945-21591-17-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1366320945-21591-1-git-send-email-g.liakhovetski@gmx.de> References: <1366320945-21591-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V02:K0:JBbHV15CbBDFwoo3qAFBJLa7nMvHpYK1iWtLYYm6UvE dL7v8BZBaxIrnzBFVmqMwA9MG2UNy1kfOm807M8/5WMFXYjSOq EyUuJXviz3zeOBjOh5NbIryoxRIvC6e4vz9F5g9Q1wSuoBBU0B 1zuHz/5hIXzkfGQ6MsvLzFFkKLMarOeFJVW2sszfGLMq8Wm+Xa 0+sk3VYdJO4L+6WaLpkKbDW1ePZ88rEf78MWttpZ5k3l4cB5iE e4Ha/fd9fL9u1PzsEN7NVnxfSeKT7XkRBXDIPiFEsrBqVgIFSD z2pCiOAlTmfDiNPC84QD7kJhJcReQFLxCTYYQc1+Qtiba0v75E H0YqLjo62KzOupkusM8zUFL23pLjHNjLroKFTjAApCc1aBeETz pdbGI7VA+VBC/f4BBAqBilRXcqWUZbJrS4= Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This adds support for V4L2 clock and asynchronous subdevice probing. Signed-off-by: Guennadi Liakhovetski --- drivers/media/i2c/mt9p031.c | 31 +++++++++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index e328332..9ba38f5 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -23,7 +23,9 @@ #include #include +#include #include +#include #include #include #include @@ -117,6 +119,7 @@ struct mt9p031 { struct media_pad pad; struct v4l2_rect crop; /* Sensor window */ struct v4l2_mbus_framefmt format; + struct v4l2_clk *clk; struct mt9p031_platform_data *pdata; struct mutex power_lock; /* lock to protect power_count */ int power_count; @@ -258,6 +261,10 @@ static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031) static int mt9p031_power_on(struct mt9p031 *mt9p031) { + int ret = v4l2_clk_enable(mt9p031->clk); + if (ret < 0) + return ret; + /* Ensure RESET_BAR is low */ if (mt9p031->reset != -1) { gpio_set_value(mt9p031->reset, 0); @@ -287,6 +294,8 @@ static void mt9p031_power_off(struct mt9p031 *mt9p031) if (mt9p031->pdata->set_xclk) mt9p031->pdata->set_xclk(&mt9p031->subdev, 0); + + v4l2_clk_disable(mt9p031->clk); } static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on) @@ -912,6 +921,7 @@ static int mt9p031_probe(struct i2c_client *client, { struct mt9p031_platform_data *pdata = client->dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct v4l2_clk *clk; struct mt9p031 *mt9p031; unsigned int i; int ret; @@ -927,11 +937,20 @@ static int mt9p031_probe(struct i2c_client *client, return -EIO; } + clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(clk)) { + dev_info(&client->dev, "Error %ld getting clock\n", PTR_ERR(clk)); + return -EPROBE_DEFER; + } + mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL); - if (mt9p031 == NULL) - return -ENOMEM; + if (mt9p031 == NULL) { + ret = -ENOMEM; + goto done; + } mt9p031->pdata = pdata; + mt9p031->clk = clk; mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; mt9p031->model = did->driver_data; @@ -1010,6 +1029,11 @@ static int mt9p031_probe(struct i2c_client *client, } ret = mt9p031_pll_setup(mt9p031); + if (ret < 0) + goto done; + + mt9p031->subdev.dev = &client->dev; + ret = v4l2_async_register_subdev(&mt9p031->subdev); done: if (ret < 0) { @@ -1019,6 +1043,7 @@ done: v4l2_ctrl_handler_free(&mt9p031->ctrls); media_entity_cleanup(&mt9p031->subdev.entity); kfree(mt9p031); + v4l2_clk_put(clk); } return ret; @@ -1029,11 +1054,13 @@ static int mt9p031_remove(struct i2c_client *client) struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct mt9p031 *mt9p031 = to_mt9p031(subdev); + v4l2_async_unregister_subdev(subdev); v4l2_ctrl_handler_free(&mt9p031->ctrls); v4l2_device_unregister_subdev(subdev); media_entity_cleanup(&subdev->entity); if (mt9p031->reset != -1) gpio_free(mt9p031->reset); + v4l2_clk_put(mt9p031->clk); kfree(mt9p031); return 0;