From patchwork Tue Sep 21 08:49:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Nikula X-Patchwork-Id: 196662 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 o8L8nksq007816 for ; Tue, 21 Sep 2010 08:49:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756413Ab0IUIto (ORCPT ); Tue, 21 Sep 2010 04:49:44 -0400 Received: from mail-ey0-f174.google.com ([209.85.215.174]:65526 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756365Ab0IUItn (ORCPT ); Tue, 21 Sep 2010 04:49:43 -0400 Received: by mail-ey0-f174.google.com with SMTP id 6so1842068eyb.19 for ; Tue, 21 Sep 2010 01:49:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=a2tBz0BZmgUBvd06bZ0qyk9au3DHng1I/grRr7Rhugk=; b=KYAIhUAGu4+lce+9gzwRX+38i+lJunr+5teacYE1X7HgF+Kq5FayNItT5fXrqTjX8m QDAW2VvPmLtsRsXZCaAkhSgN4joC7hs4iIacLQRYzvtBhDolFHF2HlWuTSy/2kUd9zI7 wov7updnM16sLJXlSB3K4v6ccPujU4Gh1U0as= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=IC+cc3rz6V7B6IyPpE1Q1G15BWOPBMa3sEAgUthHmETM1BYh+wOBfOgsgTraiZRF3j mSP+yCfWOnBoC89xFjjO7sUe+acYb7KGTsaTJMXMhSfXhTpWQ4gprOK0heGRXSjZRBYl ffLAweGVehbSkk0CvAveshG6LLvNMnp3Jt1nc= Received: by 10.213.3.14 with SMTP id 14mr7921187ebl.51.1285058982892; Tue, 21 Sep 2010 01:49:42 -0700 (PDT) Received: from localhost (host-94-101-4-66.igua.fi [94.101.4.66]) by mx.google.com with ESMTPS id u9sm12462558eeh.11.2010.09.21.01.49.41 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 21 Sep 2010 01:49:41 -0700 (PDT) From: Jarkko Nikula To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Eduardo Valentin , Jarkko Nikula Subject: [PATCHv2 2/2] V4L/DVB: radio-si4713: Add regulator framework support Date: Tue, 21 Sep 2010 11:49:43 +0300 Message-Id: <1285058983-28657-3-git-send-email-jhnikula@gmail.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1285058983-28657-1-git-send-email-jhnikula@gmail.com> References: <1285058983-28657-1-git-send-email-jhnikula@gmail.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 (demeter1.kernel.org [140.211.167.41]); Tue, 21 Sep 2010 08:49:46 +0000 (UTC) diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index fc7f4b7..f1502c6 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -43,6 +45,11 @@ MODULE_AUTHOR("Eduardo Valentin "); MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter"); MODULE_VERSION("0.0.1"); +static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = { + "vio", + "vdd", +}; + #define DEFAULT_RDS_PI 0x00 #define DEFAULT_RDS_PTY 0x00 #define DEFAULT_RDS_PS_NAME "" @@ -369,7 +376,17 @@ static int si4713_powerup(struct si4713_device *sdev) if (sdev->power_state) return 0; - sdev->platform_data->set_power(1); + err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies), + sdev->supplies); + if (err) { + v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err); + return err; + } + if (gpio_is_valid(sdev->gpio_reset)) { + udelay(50); + gpio_set_value(sdev->gpio_reset, 1); + } + err = si4713_send_command(sdev, SI4713_CMD_POWER_UP, args, ARRAY_SIZE(args), resp, ARRAY_SIZE(resp), @@ -384,7 +401,13 @@ static int si4713_powerup(struct si4713_device *sdev) err = si4713_write_property(sdev, SI4713_GPO_IEN, SI4713_STC_INT | SI4713_CTS); } else { - sdev->platform_data->set_power(0); + if (gpio_is_valid(sdev->gpio_reset)) + gpio_set_value(sdev->gpio_reset, 0); + err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies), + sdev->supplies); + if (err) + v4l2_err(&sdev->sd, + "Failed to disable supplies: %d\n", err); } return err; @@ -411,7 +434,13 @@ static int si4713_powerdown(struct si4713_device *sdev) v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n", resp[0]); v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); - sdev->platform_data->set_power(0); + if (gpio_is_valid(sdev->gpio_reset)) + gpio_set_value(sdev->gpio_reset, 0); + err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies), + sdev->supplies); + if (err) + v4l2_err(&sdev->sd, + "Failed to disable supplies: %d\n", err); sdev->power_state = POWER_OFF; } @@ -1967,7 +1996,8 @@ static int si4713_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct si4713_device *sdev; - int rval; + struct si4713_platform_data *pdata = client->dev.platform_data; + int rval, i; sdev = kzalloc(sizeof *sdev, GFP_KERNEL); if (!sdev) { @@ -1976,11 +2006,26 @@ static int si4713_probe(struct i2c_client *client, goto exit; } - sdev->platform_data = client->dev.platform_data; - if (!sdev->platform_data) { - v4l2_err(&sdev->sd, "No platform data registered.\n"); - rval = -ENODEV; - goto free_sdev; + sdev->gpio_reset = -1; + if (pdata && gpio_is_valid(pdata->gpio_reset)) { + rval = gpio_request(pdata->gpio_reset, "si4713 reset"); + if (rval) { + dev_err(&client->dev, + "Failed to request gpio: %d\n", rval); + goto free_sdev; + } + sdev->gpio_reset = pdata->gpio_reset; + gpio_direction_output(sdev->gpio_reset, 0); + } + + for (i = 0; i < ARRAY_SIZE(sdev->supplies); i++) + sdev->supplies[i].supply = si4713_supply_names[i]; + + rval = regulator_bulk_get(&client->dev, ARRAY_SIZE(sdev->supplies), + sdev->supplies); + if (rval) { + dev_err(&client->dev, "Cannot get regulators: %d\n", rval); + goto free_gpio; } v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops); @@ -1994,7 +2039,7 @@ static int si4713_probe(struct i2c_client *client, client->name, sdev); if (rval < 0) { v4l2_err(&sdev->sd, "Could not request IRQ\n"); - goto free_sdev; + goto put_reg; } v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n"); } else { @@ -2012,6 +2057,11 @@ static int si4713_probe(struct i2c_client *client, free_irq: if (client->irq) free_irq(client->irq, sdev); +put_reg: + regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); +free_gpio: + if (gpio_is_valid(sdev->gpio_reset)) + gpio_free(sdev->gpio_reset); free_sdev: kfree(sdev); exit: @@ -2031,7 +2081,9 @@ static int si4713_remove(struct i2c_client *client) free_irq(client->irq, sdev); v4l2_device_unregister_subdev(sd); - + regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); + if (gpio_is_valid(sdev->gpio_reset)) + gpio_free(sdev->gpio_reset); kfree(sdev); return 0; diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713-i2c.h index faf8cff..c6dfa7f 100644 --- a/drivers/media/radio/si4713-i2c.h +++ b/drivers/media/radio/si4713-i2c.h @@ -211,6 +211,8 @@ struct acomp_info { u32 enabled; }; +#define SI4713_NUM_SUPPLIES 2 + /* * si4713_device - private data */ @@ -220,11 +222,12 @@ struct si4713_device { /* private data structures */ struct mutex mutex; struct completion work; - struct si4713_platform_data *platform_data; struct rds_info rds_info; struct limiter_info limiter_info; struct pilot_info pilot_info; struct acomp_info acomp_info; + struct regulator_bulk_data supplies[SI4713_NUM_SUPPLIES]; + int gpio_reset; u32 frequency; u32 preemphasis; u32 mute;