From patchwork Fri May 13 05:56:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: venkat.prashanth2498@gmail.com X-Patchwork-Id: 621846 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-ig0-x23f.google.com (mail-ig0-x23f.google.com [IPv6:2607:f8b0:4001:c05::23f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3r5fJF1js4z9t5Y for ; Fri, 13 May 2016 15:57:00 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b=FS/tamXK; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=RalY0mzW; dkim-atps=neutral Received: by mail-ig0-x23f.google.com with SMTP id kj7sf1550059igb.0 for ; Thu, 12 May 2016 22:57:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20120806; h=sender:mime-version:from:to:cc:subject:date:message-id :signed-off-by: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:list-subscribe:list-unsubscribe; bh=LgJgVVZDmlY8y4sGNZZanb76BG/933dMpacnQ6s1yCM=; b=FS/tamXKRyH/xcGDaKdFsU/VY3kbN74I+zA9vWl7UY7bfcYLQeUEQCT68jSXgs+/va 8fknBgPfpDuSRbzQ+dqo9QbHBzSFlVKIXq2PmM3/GuCY0O91B+74aNuC0Kn48JjNEFRD enNoXxfR0Oa5qDSJyofMpls/f1UmVFVVzbIu3CNJQzr4jW7qDW1M3DQ2c+pw8H4/DBY9 ME5g9CJiopbS4Ves8LolL6grq9pW5MHgy8d/QCUroUxFtGmeLVNAap93gtv03hgu3fu8 YOE5SefAvOPgsMQid4EdcoEMYddbk5WOkWZwOk4E6vxi6W+qSzjoY4Z6FNttCbAB7I2g PsSQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:to:cc:subject:date:message-id:signed-off-by :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:list-subscribe:list-unsubscribe; bh=LgJgVVZDmlY8y4sGNZZanb76BG/933dMpacnQ6s1yCM=; b=RalY0mzWTXPb/QJjzAlrlDkYRUQTZHPJ1eRQ39IxcwAP82ubJYTTiwpabQV17pDxs7 QhVm9cS2gZ8rMKQRH0H1leyvKi4Kmkvwqm8oOCxPgY5ebZfobGlhSOaB3sKRnRMNae0A X5SQbCBXH+c6dYWdnO/4/0d4EiV1TCzdMTQd7F56IAEDNeLpZwsYbcApIApCQihwM1qy ygHyXXcEBiejEiJLqIYA6a5P2v7eGoe3HIicR0U0lJPp8vadeAciWDQ5DEkarF+DGxdO QUTQwXSk2Wzr3M8uMRFGLrGCcWTZPlUCoX5CfwPsXwDb+ZS2CDgEqdiSfy+iC6PEcLXb kn7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=sender:x-gm-message-state:mime-version:from:to:cc:subject:date :message-id:signed-off-by: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 :list-subscribe:list-unsubscribe; bh=LgJgVVZDmlY8y4sGNZZanb76BG/933dMpacnQ6s1yCM=; b=HkPwDo1QGiwIggeapZMYXJqf4sYK/1zyUtKExTevb0ykTk+nc+S09z/AH8mjyZYsN4 Zlf/rtcoxTJSDxonNtKV5DIDhcKtzVt/um/CvPHhY102G0SDV8QRYDDEzqAMmvqB1VYO 6ZGTjP34IbdNhW8eLPGk9DzcQ83lmaqfRHWdHa6YltvcixBggWvLAqaVh0Op3AUm88Lb M08Pi+gLuzbBfy9Vcw45QKMbGcsAUT5srtRJVEM10GeaLjYfth3HHLqryUKH+17n3t/i 4bQ43Zq7MvIyB4LAmSmskpqX3QQxJZQC4vy/VqkD6B4Wj1DFrve/SW9pFTTPuYgpM1A3 8bfg== Sender: rtc-linux@googlegroups.com X-Gm-Message-State: AOPr4FXUQs0xH0p3rKZiYAS5LqHeRc0ph0zt3GsB7Dxo9/g8qQg2lP83DtVG/jGmQRqSNw== X-Received: by 10.157.41.250 with SMTP id g55mr76033otd.5.1463119018566; Thu, 12 May 2016 22:56:58 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: rtc-linux@googlegroups.com Received: by 10.157.44.38 with SMTP id f35ls812154otb.58.gmail; Thu, 12 May 2016 22:56:58 -0700 (PDT) X-Received: by 10.157.12.213 with SMTP id o21mr8942199otd.21.1463119018068; Thu, 12 May 2016 22:56:58 -0700 (PDT) Received: from mail-pf0-x244.google.com (mail-pf0-x244.google.com. [2607:f8b0:400e:c00::244]) by gmr-mx.google.com with ESMTPS id ph3si3173388pac.1.2016.05.12.22.56.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 May 2016 22:56:58 -0700 (PDT) Received-SPF: pass (google.com: domain of venkat.prashanth2498@gmail.com designates 2607:f8b0:400e:c00::244 as permitted sender) client-ip=2607:f8b0:400e:c00::244; Received: by mail-pf0-x244.google.com with SMTP id y7so8493962pfb.0 for ; Thu, 12 May 2016 22:56:58 -0700 (PDT) X-Received: by 10.98.109.197 with SMTP id i188mr20034474pfc.88.1463119017818; Thu, 12 May 2016 22:56:57 -0700 (PDT) Received: from localhost ([117.221.91.140]) by smtp.gmail.com with ESMTPSA id g84sm24031029pfj.42.2016.05.12.22.56.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 May 2016 22:56:56 -0700 (PDT) From: venkat.prashanth2498@gmail.com To: a.zummo@towertech.it Cc: rtc-linux@googlegroups.com, linux-kernel@vger.kernel.org, alexandre.belloni@free-electrons.com, marcus.folkesson@gmail.com, venkat-prashanth Subject: [rtc-linux] [PATCH] rtc: add support for Maxim rtc max6916 v3.0 Date: Thu, 12 May 2016 22:56:15 -0700 Message-Id: <1463118975-2941-1-git-send-email-venkat.prashanth2498@gmail.com> X-Mailer: git-send-email 1.9.2 Signed-off-by: Venkat Prashanth B U X-Original-Sender: venkat.prashanth2498@gmail.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@gmail.com; spf=pass (google.com: domain of venkat.prashanth2498@gmail.com designates 2607:f8b0:400e:c00::244 as permitted sender) smtp.mailfrom=venkat.prashanth2498@gmail.com; dmarc=pass (p=NONE dis=NONE) header.from=gmail.com 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: , From: venkat-prashanth #Change Log: from v2.0 to v3.0 - fixed the out-of-tree Makefile and suitably added the modifications in the Makefile - fixed the bad indented Kconfig file -used a define instead of 0x1B as follows #define MAX6916_REG_MAP_ADDRESS 0x1B -moved and placed the test at the begining of the function after the range is properly enforced if (dt->tm_year < 100 || dt->tm_year > 199) { dev_err(&spi->dev,"Year must be between 2000 and 2099. It's %d.\n", dt->tm_year + 1900); return -EINVAL; } - A magic number is a direct usage of a number in the code,instead has been refactored in the current version v3.0 which use defines as follows:- -max6916_read_reg(&spi->dev, int MAX6916_CONTROL_REG = 0x08, &data); -max6916_write_reg(&spi->dev, int MAX6916_CONTROL_REG= 0x08, data); -max6916_write_reg(&spi->dev, int MAX6916_STATUS_REG = 0x0C, data); -max6916_read_reg(&spi->dev, int MAX6916_CONTROL_REG = 0x08, &data); -max6916_read_reg(&spi->dev, int MAX6916_STATUS_REG = 0X0C, &data); -Unnecessary test function if(dt->tm_year >= 100) dt->tm_year -= 100; is deleted after the range is properly enforced. -seperated logical code sections with an empty line and used indentation after if-statements. --- --- Kconfig | 9 ++++ Makefile | 1 + rtc-max6916.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) diff --git a/driver/rtc/Kconfig b/driver/rtc/Kconfig index fcf87da..5321e8f 100644 --- a/driver/rtc/Kconfig +++ b/driver/rtc/Kconfig @@ -699,6 +699,15 @@ This driver can also be built as a module. If so, the module will be called rtc-max6902. + config RTC_DRV_MAX6916 + tristate "Maxim MAX6916" + help + If you say yes here you will get support for the + Maxim MAX6916 SPI RTC chip. + + This driver can also be built as a module. If so, the module + will be called rtc-max6916. + config RTC_DRV_R9701 tristate "Epson RTC-9701JE" diff --git a/driver/rtc/Makefile b/driver/rtc/Makefile index 9421959..0b3fded 100644 --- a/driver/rtc/Makefile +++ b/driver/rtc/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o +obj-$(CONFIG_RTC_DRV_MAX6916) += rtc-max6916.o obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o diff --git a/driver/rtc/rtc-max6916.c b/driver/rtc/rtc-max6916.c index e69de29..ced341a 100644 --- a/driver/rtc/rtc-max6916.c +++ b/driver/rtc/rtc-max6916.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include +#include +#include + +/* Registers in max6916 rtc */ + +#define MAX6916_SECONDS_REG 0x01 +#define MAX6916_MINUTES_REG 0x02 +#define MAX6916_HOURS_REG 0x03 +#define MAX6916_DATE_REG 0x04 +#define MAX6916_MONTH_REG 0x05 +#define MAX6916_DAY_REG 0x06 +#define MAX6916_YEAR_REG 0x07 +#define MAX6916_CONTROL_REG 0x08 +#define MAX6916_STATUS_REG 0x0C +#define MAX6916_CLOCK_BURST 0x3F +#define MAX6916_REG_MAP_ADDRESS 0x1B + +static int max6916_read_reg(struct device *dev, unsigned char address, unsigned char *data) + +{ + struct spi_device *spi = to_spi_device(dev); + + *data = address | 0x80; + + return spi_write_then_read(spi, data, 1, data, 1); +} + +static int max6916_write_reg(struct device *dev, unsigned char address, unsigned char data) + +{ + struct spi_device *spi = to_spi_device(dev); + unsigned char buf[2]; + + buf[0] = address&0x7F; + buf[1] = data; + + return spi_write_then_read(spi, buf, 2, NULL, 0); +} + +static int max6916_read_time(struct device *dev, struct rtc_time *dt) +{ + struct spi_device *spi = to_spi_device(dev); + int err; + unsigned char buf[8]; + + buf[0] = MAX6916_CLOCK_BURST | 0x80; + +err = spi_write_then_read(spi, buf, 1, buf, 8); + if (err) + return err; + + dt->tm_sec = bcd2bin(buf[0]); + dt->tm_min = bcd2bin(buf[1]); + dt->tm_hour = bcd2bin(buf[2] & 0x3F); + dt->tm_mday = bcd2bin(buf[3]); + dt->tm_mon = bcd2bin(buf[4]) - 1; + dt->tm_wday = bcd2bin(buf[5]) - 1; + dt->tm_year = bcd2bin(buf[6]) + 100; + + return rtc_valid_tm(dt); +} + +static int max6916_set_time(struct device *dev, struct rtc_time *dt) +{ + struct spi_device *spi = to_spi_device(dev); + unsigned char buf[9]; + + if (dt->tm_year < 100 || dt->tm_year > 199) { + dev_err(&spi->dev, "Year must be between 2000 and 2099.It's %d.\n", dt->tm_year+1900); + return -EINVAL; +} + + buf[0] = MAX6916_CLOCK_BURST & 0x7F; + buf[1] = bin2bcd(dt->tm_sec); + buf[2] = bin2bcd(dt->tm_min); + buf[3] = (bin2bcd(dt->tm_hour) & 0X3F); + buf[4] = bin2bcd(dt->tm_mday); + buf[5] = bin2bcd(dt->tm_mon + 1); + buf[6] = bin2bcd(dt->tm_wday + 1); + buf[7] = bin2bcd(dt->tm_year % 100); + buf[8] = bin2bcd(0x00); + + /* write the rtc settings */ + return spi_write_then_read(spi, buf, 9, NULL, 0); +} + +static const struct rtc_class_ops max6916_rtc_ops = { + .read_time = max6916_read_time, + .set_time = max6916_set_time, +}; + +static int max6916_probe(struct spi_device *spi) +{ + struct rtc_device *rtc; + unsigned char data; + int res; + + /* spi setup with max6916 in mode 3 and bits per word as 8 */ + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + + /* RTC Settings */ + res = max6916_read_reg(&spi->dev, MAX6916_SECONDS_REG, &data); + + if (res) + return res; + + /* Disable the write protect of rtc */ + max6916_read_reg(&spi->dev, int MAX6916_CONTROL_REG = 0x08, &data); + data = data & ~(1<<7); + max6916_write_reg(&spi->dev, int MAX6916_CONTROL_REG = 0x08, data); + + /*Enable the oscillator,disable the oscillator stop flag, and glitch filter to reduce current consumption*/ + max6916_read_reg(&spi->dev, int MAX6916_STATUS_REG = 0X0C, &data); + data = data & MAX6916_REG_MAP_ADDRESS; + max6916_write_reg(&spi->dev, int MAX6916_STATUS_REG = 0x0C, data); + + /* display the settings */ + max6916_read_reg(&spi->dev, int MAX6916_CONTROL_REG = 0x08, &data); + dev_info(&spi->dev, "MAX6916 RTC CTRL Reg = 0x%02x\n", data); + + max6916_read_reg(&spi->dev, int MAX6916_STATUS_REG = 0X0C, &data); + dev_info(&spi->dev, "MAX6916 RTC Status Reg = 0x%02x\n", data); + + rtc = devm_rtc_device_register(&spi->dev, "max6916", &max6916_rtc_ops, THIS_MODULE); + + + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + spi_set_drvdata(spi, rtc); + + return 0; +} + +static struct spi_driver max6916_driver = { + .driver = { + .name = "max6916", + }, + .probe = max6916_probe, +}; + +module_spi_driver(max6916_driver); + +MODULE_DESCRIPTION("MAX6916 SPI RTC DRIVER"); +MODULE_AUTHOR("Venkat Prashanth B U "); +MODULE_LICENSE("GPL v2"); + + + + + + + + +