From patchwork Fri Oct 2 09:17:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 525428 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-wi0-x23d.google.com (mail-wi0-x23d.google.com [IPv6:2a00:1450:400c:c05::23d]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 398951402B2 for ; Fri, 2 Oct 2015 19:17:35 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b=XEyEKVDm; dkim-atps=neutral Received: by wiku15 with SMTP id u15sf4030495wik.1 for ; Fri, 02 Oct 2015 02:17:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20120806; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding :x-original-sender:x-original-authentication-results:reply-to :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:sender:list-subscribe:list-unsubscribe; bh=8dqFrU4YB+oMrZH9RKspPEDy+1x+myuQPrZIttKBCvI=; b=XEyEKVDmb9Ff+JuJbcVHTOJis1bRB1Ywu1c/3e3F/tUVgCXAAIaqORGLKqeurQPThS BHxgDGqBNcZ2j00yf/6qBRpoHqCZWMYBc14en1hQRI4Rd0RAdBPMdWZzK0GT6GBOfK6+ /yU2T3WPtM1Th0PX2xEYpuu4aKBxGjdI7X5jsyIBtV0boXr742T2VuxbvcuULhYDhgAP gXCFBwCxld6s+/Oha6Wu5iDQ7eGXvNJW9zn6vLNj5KimGBILKycwuJC/eAyk3WT75Yl5 ojmzuSxaNtfcWfdhMS3MC7dib0v3Ms2hUNKVa5zAcwhSm4NCWKtZSfQKFeXT/jhGaVka GIHw== X-Received: by 10.25.41.8 with SMTP id p8mr52935lfp.18.1443777452195; Fri, 02 Oct 2015 02:17:32 -0700 (PDT) X-BeenThere: rtc-linux@googlegroups.com Received: by 10.25.218.207 with SMTP id r198ls217392lfg.40.gmail; Fri, 02 Oct 2015 02:17:31 -0700 (PDT) X-Received: by 10.112.142.195 with SMTP id ry3mr2408528lbb.22.1443777451334; Fri, 02 Oct 2015 02:17:31 -0700 (PDT) Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de. [2001:67c:670:201:290:27ff:fe1d:cc33]) by gmr-mx.google.com with ESMTPS id bj4si218638wib.1.2015.10.02.02.17.31 for (version=TLS1_2 cipher=AES128-SHA256 bits=128/128); Fri, 02 Oct 2015 02:17:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of ukl@pengutronix.de designates 2001:67c:670:201:290:27ff:fe1d:cc33 as permitted sender) client-ip=2001:67c:670:201:290:27ff:fe1d:cc33; Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1ZhwT4-0001P3-9S; Fri, 02 Oct 2015 11:17:30 +0200 Received: from ukl by dude.hi.pengutronix.de with local (Exim 4.86) (envelope-from ) id 1ZhwT3-0004DM-0X; Fri, 02 Oct 2015 11:17:29 +0200 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= To: Alexandre Belloni Cc: Alessandro Zummo , rtc-linux@googlegroups.com, kernel@pengutronix.de, Greg Kroah-Hartman , linux-kernel@vger.kernel.org Subject: [rtc-linux] [PATCH v1 4/4 RFC] rtc: pcf2127: implement access to nvram Date: Fri, 2 Oct 2015 11:17:22 +0200 Message-Id: <1443777442-15920-5-git-send-email-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.6.0 In-Reply-To: <1443777442-15920-1-git-send-email-u.kleine-koenig@pengutronix.de> References: <1443777442-15920-1-git-send-email-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: rtc-linux@googlegroups.com X-Original-Sender: u.kleine-koenig@pengutronix.de X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: best guess record for domain of ukl@pengutronix.de designates 2001:67c:670:201:290:27ff:fe1d:cc33 as permitted sender) smtp.mailfrom=ukl@pengutronix.de Reply-To: rtc-linux@googlegroups.com Precedence: list Mailing-list: list rtc-linux@googlegroups.com; contact rtc-linux+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: rtc-linux@googlegroups.com X-Google-Group-Id: 712029733259 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , The rtc features a 512 byte battery backed RAM. Make it available via sysfs. Signed-off-by: Uwe Kleine-König --- Notes: This patch is broken in the same way as the previous one. Don't merge! drivers/rtc/rtc-pcf2127.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index db057db88031..e21dc5dfc9fb 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -35,6 +35,10 @@ #define PCF2127_REG_MO (0x08) #define PCF2127_REG_YR (0x09) +#define PCF2127_REG_RAM_addr_MSB 0x1a +#define PCF2127_REG_RAM_wrt_cmd 0x1c +#define PCF2127_REG_RAM_rd_cmd 0x1d + #define PCF2127_OSF BIT(7) /* Oscillator Fail flag */ static struct i2c_driver pcf2127_driver; @@ -295,6 +299,106 @@ static const struct attribute *pcf2127_attributes[] = { NULL }; +#define PCF2127_NVRAM_SIZE 512 + +static ssize_t pcf2127_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + struct i2c_client *client; + int ret; + unsigned char i2cbuf[3] = { PCF2127_REG_RAM_addr_MSB, off >> 8, off }; + + if (off >= PCF2127_NVRAM_SIZE) + return 0; + + if (count > PCF2127_NVRAM_SIZE - off) + count = PCF2127_NVRAM_SIZE - off; + + if (!count) + return 0; + + client = kobj_to_i2c_client(kobj); + + /* set offset */ + ret = i2c_master_send(client, i2cbuf, 3); + if (!ret) + ret = -EIO; + if (ret < 0) { + dev_err(&client->dev, "failed to set RAM address\n"); + return ret; + } + + i2cbuf[0] = PCF2127_REG_RAM_rd_cmd; + ret = i2c_master_send(client, i2cbuf, 1); + if (!ret) + ret = -EIO; + if (ret < 0) { + dev_err(&client->dev, "failed to issue read command\n"); + return ret; + } + + ret = i2c_master_recv(client, buf, count); + if (!ret) + ret = -EIO; + if (ret < 0) + dev_err(&client->dev, "failed to read data\n"); + + return ret; +} + +static ssize_t pcf2127a_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + struct i2c_client *client; + int ret; + unsigned char i2cbuf[PCF2127_NVRAM_SIZE + 1] = { + PCF2127_REG_RAM_addr_MSB, off >> 8, off }; + + if (off >= PCF2127_NVRAM_SIZE) + return 0; + + if (count > PCF2127_NVRAM_SIZE - off) + count = PCF2127_NVRAM_SIZE - off; + + if (!count) + return 0; + + client = kobj_to_i2c_client(kobj); + + /* set offset */ + ret = i2c_master_send(client, i2cbuf, 3); + if (!ret) + ret = -EIO; + if (ret < 0) { + dev_err(&client->dev, "failed to set RAM address\n"); + return ret; + } + + i2cbuf[0] = PCF2127_REG_RAM_wrt_cmd; + memcpy(i2cbuf + 1, buf, count); + ret = i2c_master_send(client, i2cbuf, count + 1); + if (!ret) + ret = -EIO; + if (ret < 0) { + dev_err(&client->dev, "failed to issue write command\n"); + return ret; + } + + return ret - 1; +} + +static const struct bin_attribute pcf2127_nvram = { + .attr = { + .name = "nvram", + .mode = S_IWUSR | S_IRUGO, + }, + .read = pcf2127_nvram_read, + .write = pcf2127a_nvram_write, + .size = PCF2127_NVRAM_SIZE, +}; + static int pcf2127_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -319,12 +423,21 @@ static int pcf2127_probe(struct i2c_client *client, return ret; } + ret = sysfs_create_bin_file(&client->dev.kobj, &pcf2127_nvram); + if (ret < 0) { + dev_err(&client->dev, + "failed to register sysfs nvram attribute\n"); + goto err_create_bin_file; + } + pcf2127->rtc = devm_rtc_device_register(&client->dev, pcf2127_driver.driver.name, &pcf2127_rtc_ops, THIS_MODULE); if (IS_ERR(pcf2127->rtc)) { ret = PTR_ERR(pcf2127->rtc); + sysfs_remove_bin_file(&client->dev.kobj, &pcf2127_nvram); +err_create_bin_file: sysfs_remove_files(&client->dev.kobj, pcf2127_attributes); } @@ -333,6 +446,7 @@ static int pcf2127_probe(struct i2c_client *client, static int pcf2127_remove(struct i2c_client *client) { + sysfs_remove_bin_file(&client->dev.kobj, &pcf2127_nvram); sysfs_remove_files(&client->dev.kobj, pcf2127_attributes); return 0; }