From patchwork Thu Apr 9 07:42:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Machek X-Patchwork-Id: 6183951 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C068D9F2EC for ; Thu, 9 Apr 2015 07:45:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CBB14202F0 for ; Thu, 9 Apr 2015 07:45:06 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B482220279 for ; Thu, 9 Apr 2015 07:45:05 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Yg77F-0000gf-Jf; Thu, 09 Apr 2015 07:43:09 +0000 Received: from atrey.karlin.mff.cuni.cz ([195.113.26.193]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Yg778-0000Xd-NH for linux-arm-kernel@lists.infradead.org; Thu, 09 Apr 2015 07:43:05 +0000 Received: by atrey.karlin.mff.cuni.cz (Postfix, from userid 512) id F1CF981F2C; Thu, 9 Apr 2015 09:42:38 +0200 (CEST) Date: Thu, 9 Apr 2015 09:42:38 +0200 From: Pavel Machek To: Sakari Ailus Subject: [PATCHv7] media: i2c/adp1653: Devicetree support for adp1653 Message-ID: <20150409074238.GA22603@amd> References: <20150402143846.GA11687@amd> <20150402203417.GA6336@amd> <20150403083353.GA21070@amd> <20150403113216.GK20756@valkosipuli.retiisi.org.uk> <20150403202624.GA4308@amd> <20150403213655.GO20756@valkosipuli.retiisi.org.uk> <20150404074337.GA31064@amd> <20150404102435.GR20756@valkosipuli.retiisi.org.uk> <20150404171116.GA15025@Nokia-N900> <20150404200307.GS20756@valkosipuli.retiisi.org.uk> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20150404200307.GS20756@valkosipuli.retiisi.org.uk> User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150409_004303_152681_D5A83142 X-CRM114-Status: GOOD ( 21.42 ) X-Spam-Score: -2.3 (--) Cc: Andrew Morton , devicetree@vger.kernel.org, ivo.g.dimitrov.75@gmail.com, khilman@kernel.org, tony@atomide.com, sre@debian.org, mchehab@osg.samsung.com, aaro.koskinen@iki.fi, kernel list , hverkuil@xs4all.nl, sre@ring0.de, galak@codeaurora.org, bcousson@baylibre.com, pali.rohar@gmail.com, linux-omap@vger.kernel.org, patrikbachan@gmail.com, linux-arm-kernel , m.chehab@samsung.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add device tree support for adp1653 flash LED driver. Signed-off-by: Pavel Machek --- Second part of a patch after documentation was merged. Please apply, Pavel diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 873fe19..d703636 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -8,6 +8,7 @@ * Contributors: * Sakari Ailus * Tuukka Toivonen + * Pavel Machek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -306,9 +309,17 @@ adp1653_init_device(struct adp1653_flash *flash) static int __adp1653_set_power(struct adp1653_flash *flash, int on) { - int ret; + int ret = 0; + + if (flash->platform_data->power) { + ret = flash->platform_data->power(&flash->subdev, on); + } else { + gpiod_set_value(flash->platform_data->enable_gpio, on); + if (on) + /* Some delay is apparently required. */ + udelay(20); + } - ret = flash->platform_data->power(&flash->subdev, on); if (ret < 0) return ret; @@ -316,8 +327,13 @@ __adp1653_set_power(struct adp1653_flash *flash, int on) return 0; ret = adp1653_init_device(flash); - if (ret < 0) + if (ret >= 0) + return ret; + + if (flash->platform_data->power) flash->platform_data->power(&flash->subdev, 0); + else + gpiod_set_value(flash->platform_data->enable_gpio, 0); return ret; } @@ -407,21 +423,78 @@ static int adp1653_resume(struct device *dev) #endif /* CONFIG_PM */ +static int adp1653_of_init(struct i2c_client *client, + struct adp1653_flash *flash, + struct device_node *node) +{ + u32 val; + struct adp1653_platform_data *pd; + struct device_node *child = NULL; + + if (!node) + return -EINVAL; + + pd = devm_kzalloc(&client->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + flash->platform_data = pd; + + child = of_get_child_by_name(node, "flash"); + if (!child) + return -EINVAL; + + if (of_property_read_u32(child, "flash-timeout-us", &val)) + goto err; + + pd->max_flash_timeout = val; + if (of_property_read_u32(child, "flash-max-microamp", &val)) + goto err; + pd->max_flash_intensity = val/1000; + + if (of_property_read_u32(child, "max-microamp", &val)) + goto err; + pd->max_torch_intensity = val/1000; + of_node_put(child); + + child = of_get_child_by_name(node, "indicator"); + if (!child) + return -EINVAL; + if (of_property_read_u32(child, "max-microamp", &val)) + goto err; + pd->max_indicator_intensity = val; + + of_node_put(child); + + pd->enable_gpio = devm_gpiod_get(&client->dev, "enable"); + if (!pd->enable_gpio) { + dev_err(&client->dev, "Error getting GPIO\n"); + return -EINVAL; + } + + return 0; +err: + dev_err(&client->dev, "Required property not found\n"); + of_node_put(child); + return -EINVAL; +} + + static int adp1653_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct adp1653_flash *flash; int ret; - /* we couldn't work without platform data */ - if (client->dev.platform_data == NULL) - return -ENODEV; - flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); if (flash == NULL) return -ENOMEM; flash->platform_data = client->dev.platform_data; + if (client->dev.of_node) { + ret = adp1653_of_init(client, flash, client->dev.of_node); + if (ret) + return ret; + } mutex_init(&flash->power_lock); @@ -442,6 +515,7 @@ static int adp1653_probe(struct i2c_client *client, return 0; free_and_quit: + dev_err(&client->dev, "adp1653: failed to register device\n"); v4l2_ctrl_handler_free(&flash->ctrls); return ret; } @@ -464,7 +538,7 @@ static const struct i2c_device_id adp1653_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, adp1653_id_table); -static struct dev_pm_ops adp1653_pm_ops = { +static const struct dev_pm_ops adp1653_pm_ops = { .suspend = adp1653_suspend, .resume = adp1653_resume, }; diff --git a/include/media/adp1653.h b/include/media/adp1653.h index 1d9b48a..34b505e 100644 --- a/include/media/adp1653.h +++ b/include/media/adp1653.h @@ -100,9 +100,11 @@ struct adp1653_platform_data { int (*power)(struct v4l2_subdev *sd, int on); u32 max_flash_timeout; /* flash light timeout in us */ - u32 max_flash_intensity; /* led intensity, flash mode */ - u32 max_torch_intensity; /* led intensity, torch mode */ - u32 max_indicator_intensity; /* indicator led intensity */ + u32 max_flash_intensity; /* led intensity, flash mode, mA */ + u32 max_torch_intensity; /* led intensity, torch mode, mA */ + u32 max_indicator_intensity; /* indicator led intensity, uA */ + + struct gpio_desc *enable_gpio; /* for device-tree based boot */ }; #define to_adp1653_flash(sd) container_of(sd, struct adp1653_flash, subdev)