cregit-Linux how code gets into the kernel

Release 4.7 drivers/rtc/rtc-ds1742.c

Directory: drivers/rtc
/*
 * An rtc driver for the Dallas DS1742
 *
 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Copyright (C) 2006 Torsten Ertbjerg Rasmussen <tr@newtec.dk>
 *  - nvram size determined from resource
 *  - this ds1742 driver now supports ds1743.
 */

#include <linux/bcd.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/rtc.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/module.h>


#define RTC_SIZE		8


#define RTC_CONTROL		0

#define RTC_CENTURY		0

#define RTC_SECONDS		1

#define RTC_MINUTES		2

#define RTC_HOURS		3

#define RTC_DAY			4

#define RTC_DATE		5

#define RTC_MONTH		6

#define RTC_YEAR		7


#define RTC_CENTURY_MASK	0x3f

#define RTC_SECONDS_MASK	0x7f

#define RTC_DAY_MASK		0x07

/* Bits in the Control/Century register */

#define RTC_WRITE		0x80

#define RTC_READ		0x40

/* Bits in the Seconds register */

#define RTC_STOP		0x80

/* Bits in the Day register */

#define RTC_BATT_FLAG		0x80


struct rtc_plat_data {
	
void __iomem *ioaddr_nvram;
	
void __iomem *ioaddr_rtc;
	
size_t size_nvram;
	
unsigned long last_jiffies;
	
struct bin_attribute nvram_attr;
};


static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr_rtc; u8 century; century = bin2bcd((tm->tm_year + 1900) / 100); writeb(RTC_WRITE, ioaddr + RTC_CONTROL); writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR); writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH); writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE); writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS); writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES); writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); /* RTC_CENTURY and RTC_CONTROL share same register */ writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto19995.67%133.33%
adrian bunkadrian bunk83.85%133.33%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen10.48%133.33%
Total208100.00%3100.00%


static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr_rtc; unsigned int year, month, day, hour, minute, second, week; unsigned int century; /* give enough time to update RTC in case of continuous read */ if (pdata->last_jiffies == jiffies) msleep(1); pdata->last_jiffies = jiffies; writeb(RTC_READ, ioaddr + RTC_CONTROL); second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK; minute = readb(ioaddr + RTC_MINUTES); hour = readb(ioaddr + RTC_HOURS); day = readb(ioaddr + RTC_DATE); week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK; month = readb(ioaddr + RTC_MONTH); year = readb(ioaddr + RTC_YEAR); century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; writeb(0, ioaddr + RTC_CONTROL); tm->tm_sec = bcd2bin(second); tm->tm_min = bcd2bin(minute); tm->tm_hour = bcd2bin(hour); tm->tm_mday = bcd2bin(day); tm->tm_wday = bcd2bin(week); tm->tm_mon = bcd2bin(month) - 1; /* year is 1900 + tm->tm_year */ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; return rtc_valid_tm(tm); }

Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto25296.18%125.00%
adrian bunkadrian bunk83.05%125.00%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen10.38%125.00%
alexander shiyanalexander shiyan10.38%125.00%
Total262100.00%4100.00%

static const struct rtc_class_ops ds1742_rtc_ops = { .read_time = ds1742_rtc_read_time, .set_time = ds1742_rtc_set_time, };
static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr_nvram; ssize_t count; for (count = 0; count < size; count++) *buf++ = readb(ioaddr + pos++); return count; }

Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto9387.74%233.33%
rui zhangrui zhang54.72%116.67%
chris wrightchris wright54.72%116.67%
vladimir zapolskiyvladimir zapolskiy21.89%116.67%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen10.94%116.67%
Total106100.00%6100.00%


static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr_nvram; ssize_t count; for (count = 0; count < size; count++) writeb(*buf++, ioaddr + pos++); return count; }

Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto9387.74%233.33%
rui zhangrui zhang54.72%116.67%
chris wrightchris wright54.72%116.67%
vladimir zapolskiyvladimir zapolskiy21.89%116.67%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen10.94%116.67%
Total106100.00%6100.00%


static int ds1742_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; unsigned int cen, sec; struct rtc_plat_data *pdata; void __iomem *ioaddr; int ret = 0; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ioaddr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ioaddr)) return PTR_ERR(ioaddr); pdata->ioaddr_nvram = ioaddr; pdata->size_nvram = resource_size(res) - RTC_SIZE; pdata->ioaddr_rtc = ioaddr + pdata->size_nvram; sysfs_bin_attr_init(&pdata->nvram_attr); pdata->nvram_attr.attr.name = "nvram"; pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR; pdata->nvram_attr.read = ds1742_nvram_read; pdata->nvram_attr.write = ds1742_nvram_write; pdata->nvram_attr.size = pdata->size_nvram; /* turn RTC on if it was not on */ ioaddr = pdata->ioaddr_rtc; sec = readb(ioaddr + RTC_SECONDS); if (sec & RTC_STOP) { sec &= RTC_SECONDS_MASK; cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; writeb(RTC_WRITE, ioaddr + RTC_CONTROL); writeb(sec, ioaddr + RTC_SECONDS); writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); } if (!(readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG)) dev_warn(&pdev->dev, "voltage-low detected.\n"); pdata->last_jiffies = jiffies; platform_set_drvdata(pdev, pdata); rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &ds1742_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); if (ret) dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", pdata->nvram_attr.attr.name); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto24065.40%333.33%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen7520.44%222.22%
alessandro zummoalessandro zummo236.27%111.11%
alexander shiyanalexander shiyan174.63%111.11%
wolfram sangwolfram sang82.18%111.11%
jingoo hanjingoo han41.09%111.11%
Total367100.00%9100.00%


static int ds1742_rtc_remove(struct platform_device *pdev) { struct rtc_plat_data *pdata = platform_get_drvdata(pdev); sysfs_remove_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto3692.31%150.00%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen37.69%150.00%
Total39100.00%2100.00%

static const struct of_device_id __maybe_unused ds1742_rtc_of_match[] = { { .compatible = "maxim,ds1742", }, { } }; MODULE_DEVICE_TABLE(of, ds1742_rtc_of_match); static struct platform_driver ds1742_rtc_driver = { .probe = ds1742_rtc_probe, .remove = ds1742_rtc_remove, .driver = { .name = "rtc-ds1742", .of_match_table = of_match_ptr(ds1742_rtc_of_match), }, }; module_platform_driver(ds1742_rtc_driver); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:rtc-ds1742");

Overall Contributors

PersonTokensPropCommitsCommitProp
atsushi nemotoatsushi nemoto107080.88%520.83%
torsten ertbjerg rasmussentorsten ertbjerg rasmussen1088.16%28.33%
alexander shiyanalexander shiyan554.16%416.67%
alessandro zummoalessandro zummo231.74%14.17%
adrian bunkadrian bunk161.21%14.17%
chris wrightchris wright100.76%14.17%
rui zhangrui zhang100.76%14.17%
wolfram sangwolfram sang80.60%14.17%
jingoo hanjingoo han50.38%28.33%
kay sieverskay sievers50.38%14.17%
vladimir zapolskiyvladimir zapolskiy40.30%14.17%
tejun heotejun heo30.23%14.17%
paul gortmakerpaul gortmaker30.23%14.17%
axel linaxel lin20.15%14.17%
david brownelldavid brownell10.08%14.17%
Total1323100.00%24100.00%
Directory: drivers/rtc
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}