[Armadeus-commitlog] armadeus branch, master, updated. armadeus-5.2-323-g6e41bce
Brought to you by:
sszy
|
From: Fabien M <fa...@us...> - 2013-07-22 13:27:07
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 6e41bce7fdb32f98e4c19700bf34234864c8286f (commit)
from e2665b5cc15ffd8d0e3f3bc58cbb7e2a5d239662 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 6e41bce7fdb32f98e4c19700bf34234864c8286f
Author: Fabien Marteau <fab...@ar...>
Date: Mon Jul 22 15:23:47 2013 +0200
linux: driver: rtc: mcp7940x manage alarm
-----------------------------------------------------------------------
Summary of changes:
.../464-armadeus-add_mcp7940x_rtc_driver.patch | 539 ++++++++++++++++++++
1 files changed, 539 insertions(+), 0 deletions(-)
create mode 100644 patches/linux/2.6.35/464-armadeus-add_mcp7940x_rtc_driver.patch
diff --git a/patches/linux/2.6.35/464-armadeus-add_mcp7940x_rtc_driver.patch b/patches/linux/2.6.35/464-armadeus-add_mcp7940x_rtc_driver.patch
new file mode 100644
index 0000000..fe63f02
--- /dev/null
+++ b/patches/linux/2.6.35/464-armadeus-add_mcp7940x_rtc_driver.patch
@@ -0,0 +1,539 @@
+Index: linux-2.6.35.3/drivers/rtc/rtc-mcp7940x.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35.3/drivers/rtc/rtc-mcp7940x.c 2013-07-22 14:48:37.045061568 +0200
+@@ -0,0 +1,501 @@
++/*
++ * RTC client/driver for the Microchip MCP7940x Real-Time Clock over I2C
++ *
++ * Based on code by Scott Wood <sco...@fr...>
++ * which was based on code by Randy Vinson <rv...@mv...>,
++ * which was based on the m41t00.c by Mark Greer <mg...@mv...>.
++ *
++ * Copyright (C) 2012 Armadeus Systems
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++/*
++ * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
++ * recommened in .../Documentation/i2c/writing-clients section
++ * "Sending and receiving", using SMBus level communication is preferred.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/i2c.h>
++#include <linux/rtc.h>
++#include <linux/bcd.h>
++#include <linux/slab.h>
++
++/* Time of Day */
++#define MCP7940X_REG_TD_SECONDS 0x00
++#define MCP7940X_REG_TD_MINUTES 0x01
++#define MCP7940X_REG_TD_HOURS 0x02
++#define MCP7940X_REG_TD_DAY 0x03
++#define MCP7940X_REG_TD_DATE 0x04
++#define MCP7940X_REG_TD_MONTH 0x05
++#define MCP7940X_REG_TD_YEAR 0x06
++/* Controls */
++#define MCP7940X_REG_CONTROL 0x07
++#define MCP7940X_REG_CALIBRATION 0x08
++#define MCP7940X_REG_UNLOCK_ID 0x08
++/* Alarm 0 */
++
++#define MCP7940X_REG_ALRM0_SECONDS 0x0A
++#define MCP7940X_REG_ALRM0_MINUTES 0x0B
++#define MCP7940X_REG_ALRM0_HOURS 0x0C
++#define MCP7940X_REG_ALRM0_DAY 0x0D
++#define MCP7940X_REG_ALRM0_DATE 0x0E
++#define MCP7940X_REG_ALRM0_MONTH 0x0F
++/* Alarm 1 */
++#define MCP7940X_REG_ALRM1_SECONDS 0x11
++#define MCP7940X_REG_ALRM1_MINUTES 0x12
++#define MCP7940X_REG_ALRM1_HOURS 0x13
++#define MCP7940X_REG_ALRM1_DAY 0x14
++#define MCP7940X_REG_ALRM1_DATE 0x15
++#define MCP7940X_REG_ALRM1_MONTH 0x16
++/* Timestamp 0 */
++#define MCP7940X_REG_TS0_MINUTES 0x18
++#define MCP7940X_REG_TS0_HOURS 0x19
++#define MCP7940X_REG_TS0_DATE 0x1A
++#define MCP7940X_REG_TS0_MONTH 0x1B
++/* Timestamp 1 */
++#define MCP7940X_REG_TS1_MINUTES 0x1C
++#define MCP7940X_REG_TS1_HOURS 0x1D
++#define MCP7940X_REG_TS1_DATE 0x1E
++#define MCP7940X_REG_TS1_MONTH 0x1F
++
++
++/* bits definitions */
++#define MCP7940X_START_BITS 0x80
++#define MCP7940X_24H_BITS 0x40
++#define MCP7940X_VBATEN 0x08
++
++static const struct i2c_device_id mcp7940x_id[] = {
++ { "mcp79400", 0 }, /* no unique ID */
++ { "mcp79401", 1 }, /* EUI-48 */
++ { "mcp79402", 2 }, /* EUI-64 */
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, mcp7940x_id);
++
++struct mcp7940x {
++ struct rtc_device *rtc;
++ struct i2c_client *client;
++ int exiting;
++ int irq;
++ unsigned int irqen;
++ int alrm_sec;
++ int alrm_min;
++ int alrm_hour;
++ int alrm_mday;
++ spinlock_t lock;
++};
++
++static struct i2c_driver mcp7940x_driver;
++
++static void mcp7940x_reg_dump(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++
++ printk(" MCP7940X_REG_TD_SECONDS (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_SECONDS ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_SECONDS));
++ printk(" MCP7940X_REG_TD_MINUTES (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_MINUTES ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_MINUTES));
++ printk(" MCP7940X_REG_TD_HOURS (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_HOURS ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_HOURS));
++ printk(" MCP7940X_REG_TD_DAY (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_DAY ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_DAY));
++ printk(" MCP7940X_REG_TD_DATE (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_DATE ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_DATE));
++ printk(" MCP7940X_REG_TD_MONTH (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_MONTH ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_MONTH));
++ printk(" MCP7940X_REG_TD_YEAR (0x%02X) -> 0x%02X\n", MCP7940X_REG_TD_YEAR ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TD_YEAR));
++ printk(" MCP7940X_REG_CONTROL (0x%02X) -> 0x%02X\n", MCP7940X_REG_CONTROL ,i2c_smbus_read_byte_data(client,MCP7940X_REG_CONTROL));
++ printk(" MCP7940X_REG_CALIBRATION (0x%02X) -> 0x%02X\n", MCP7940X_REG_CALIBRATION ,i2c_smbus_read_byte_data(client,MCP7940X_REG_CALIBRATION));
++ printk(" MCP7940X_REG_UNLOCK_ID (0x%02X) -> 0x%02X\n", MCP7940X_REG_UNLOCK_ID ,i2c_smbus_read_byte_data(client,MCP7940X_REG_UNLOCK_ID));
++ printk(" MCP7940X_REG_ALRM0_SECONDS (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM0_SECONDS,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM0_SECONDS));
++ printk(" MCP7940X_REG_ALRM0_MINUTES (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM0_MINUTES,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM0_MINUTES));
++ printk(" MCP7940X_REG_ALRM0_HOURS (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM0_HOURS ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM0_HOURS));
++ printk(" MCP7940X_REG_ALRM0_DAY (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM0_DAY ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM0_DAY));
++ printk(" MCP7940X_REG_ALRM0_DATE (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM0_DATE ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM0_DATE));
++ printk(" MCP7940X_REG_ALRM0_MONTH (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM0_MONTH ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM0_MONTH));
++ printk(" MCP7940X_REG_ALRM1_SECONDS (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM1_SECONDS,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM1_SECONDS));
++ printk(" MCP7940X_REG_ALRM1_MINUTES (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM1_MINUTES,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM1_MINUTES));
++ printk(" MCP7940X_REG_ALRM1_HOURS (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM1_HOURS ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM1_HOURS));
++ printk(" MCP7940X_REG_ALRM1_DAY (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM1_DAY ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM1_DAY));
++ printk(" MCP7940X_REG_ALRM1_DATE (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM1_DATE ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM1_DATE));
++ printk(" MCP7940X_REG_ALRM1_MONTH (0x%02X) -> 0x%02X\n", MCP7940X_REG_ALRM1_MONTH ,i2c_smbus_read_byte_data(client,MCP7940X_REG_ALRM1_MONTH));
++ printk(" MCP7940X_REG_TS0_MINUTES (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS0_MINUTES ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS0_MINUTES));
++ printk(" MCP7940X_REG_TS0_HOURS (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS0_HOURS ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS0_HOURS));
++ printk(" MCP7940X_REG_TS0_DATE (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS0_DATE ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS0_DATE));
++ printk(" MCP7940X_REG_TS0_MONTH (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS0_MONTH ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS0_MONTH));
++ printk(" MCP7940X_REG_TS1_MINUTES (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS1_MINUTES ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS1_MINUTES));
++ printk(" MCP7940X_REG_TS1_HOURS (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS1_HOURS ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS1_HOURS));
++ printk(" MCP7940X_REG_TS1_DATE (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS1_DATE ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS1_DATE));
++ printk(" MCP7940X_REG_TS1_MONTH (0x%02X) -> 0x%02X\n", MCP7940X_REG_TS1_MONTH ,i2c_smbus_read_byte_data(client,MCP7940X_REG_TS1_MONTH));
++}
++
++static int mcp7940x_read_time(struct device *dev, struct rtc_time *time)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ int ret;
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_SECONDS);
++ if (ret < 0)
++ return ret;
++ time->tm_sec = ((ret&0x70)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_MINUTES);
++ if (ret < 0)
++ return ret;
++ time->tm_min = ((ret&0x70)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_HOURS);
++ if (ret < 0)
++ return ret;
++ time->tm_hour = ((ret&0x30)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_DATE);
++ if (ret < 0)
++ return ret;
++ time->tm_mday = ((ret&0x30)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_MONTH);
++ if (ret < 0)
++ return ret;
++ time->tm_mon = (((ret&0x10)>>4)*10 + (ret&0x0F)) - 1;
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_YEAR);
++ if (ret < 0)
++ return ret;
++ time->tm_year = ((((ret&0xF0)>>4)*10 + (ret&0x0F))) + 100;
++
++ return 0;
++}
++
++static int mcp7940x_set_time(struct device *dev, struct rtc_time *time)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ int ret;
++ int value;
++ int day;
++
++ value = ((((time->tm_sec/10)&0x07)<<4)|(time->tm_sec % 10))|
++ MCP7940X_START_BITS;
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_SECONDS,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = (((time->tm_min/10)&0x07)<<4)|(time->tm_min % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_MINUTES,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = ((((time->tm_hour/10)&0x03)<<4)|(time->tm_hour % 10));
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_HOURS,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = (((time->tm_mday/10)&0x03)<<4)|(time->tm_mday % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_DATE,
++ value);
++ if (ret < 0)
++ return ret;
++
++ /*****/
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_TD_DAY);
++ if (ret < 0)
++ return ret;
++ day = (time->tm_wday == 0)?7:time->tm_wday;
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_DAY,
++ (ret&0xF8)|day);
++ if (ret < 0)
++ return ret;
++ /*****/
++
++ value = ((((time->tm_mon+1)/10)&0x01)<<4)|((time->tm_mon+1) % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_MONTH,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = ((((time->tm_year-100)/10)&0x0F)<<4)|((time->tm_year-100) % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_TD_YEAR,
++ value);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++//struct rtc_wkalrm {
++// unsigned char enabled; /* 0 = alarm disabled, 1 = alarm enabled */
++// unsigned char pending; /* 0 = alarm not pending, 1 = alarm pending */
++// struct rtc_time time; /* time the alarm is set to */
++//};
++
++static int mcp79400_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) {
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rtc_time *time = &wkalrm->time;
++ int ret;
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_SECONDS);
++ if (ret < 0)
++ return ret;
++ time->tm_sec = ((ret&0x70)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_MINUTES);
++ if (ret < 0)
++ return ret;
++ time->tm_min = ((ret&0x70)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_HOURS);
++ if (ret < 0)
++ return ret;
++ time->tm_hour = ((ret&0x30)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_DATE);
++ if (ret < 0)
++ return ret;
++ time->tm_mday = ((ret&0x30)>>4)*10 + (ret&0x0F);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_MONTH);
++ if (ret < 0)
++ return ret;
++ time->tm_mon = (((ret&0x10)>>4)*10 + (ret&0x0F)) - 1;
++
++ time->tm_year = -1;
++ time->tm_wday = -1;
++ time->tm_yday = -1;
++ time->tm_isdst= -1;
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_CONTROL);
++ if (ret < 0)
++ return ret;
++ wkalrm->enabled = ((ret&0x10)>>4);
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_DAY);
++ if (ret < 0)
++ return ret;
++ wkalrm->pending = ((ret&0x08)>>3);
++
++ return 0;
++}
++
++static int mcp79400_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) {
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rtc_time *time = &wkalrm->time;
++ int ret;
++ int value;
++ int day;
++
++ /* clear pending alarm */
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_ALRM0_DAY);
++ if (ret < 0)
++ return ret;
++ day = (time->tm_wday == 0)?7:time->tm_wday;
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_ALRM0_DAY,
++ ((ret|0x70)&0x70)|day);
++ if (ret < 0)
++ return ret;
++
++ value = ((((time->tm_sec/10)&0x07)<<4)|(time->tm_sec % 10))|
++ MCP7940X_START_BITS;
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_ALRM0_SECONDS,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = (((time->tm_min/10)&0x07)<<4)|(time->tm_min % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_ALRM0_MINUTES,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = ((((time->tm_hour/10)&0x03)<<4)|(time->tm_hour % 10));
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_ALRM0_HOURS,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = (((time->tm_mday/10)&0x03)<<4)|(time->tm_mday % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_ALRM0_DATE,
++ value);
++ if (ret < 0)
++ return ret;
++
++ value = ((((time->tm_mon+1)/10)&0x01)<<4)|((time->tm_mon+1) % 10);
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_ALRM0_MONTH,
++ value);
++ if (ret < 0)
++ return ret;
++
++ ret = i2c_smbus_read_byte_data(client, MCP7940X_REG_CONTROL);
++ if (ret < 0)
++ return ret;
++ if (wkalrm->enabled) {
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_CONTROL,
++ ret | 0x10);
++ } else {
++ ret = i2c_smbus_write_byte_data(client,
++ MCP7940X_REG_CONTROL,
++ ret & ~(0x10));
++ }
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++
++/* TODO: see rtc-ds1511.c */
++static int mcp79400_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++ return 0;
++}
++
++static int mcp79400_update_irq_enable(struct device *dev, unsigned int enabled)
++{
++ return 0;
++}
++
++
++static const struct rtc_class_ops mcp7940x_rtc_ops = {
++ .read_time = mcp7940x_read_time,
++ .set_time = mcp7940x_set_time,
++ .read_alarm = mcp79400_read_alarm, /* Use ALARM0 only */
++ .set_alarm = mcp79400_set_alarm,
++ .alarm_irq_enable= mcp79400_alarm_irq_enable,
++ .update_irq_enable=mcp79400_update_irq_enable,
++};
++
++static int mcp7940x_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct mcp7940x *mcp7940x;
++ int ret;
++
++ mcp7940x = kzalloc(sizeof(struct mcp7940x), GFP_KERNEL);
++ if (!mcp7940x)
++ return -ENOMEM;
++
++ mcp7940x->client = client;
++ i2c_set_clientdata(client, mcp7940x);
++
++ ret = i2c_smbus_read_byte_data(mcp7940x->client, MCP7940X_REG_TD_HOURS);
++ if (ret < 0)
++ goto out_free;
++
++ /* set rtc to 24h format */
++ if ((ret & MCP7940X_24H_BITS)) {
++ ret = i2c_smbus_write_byte_data(mcp7940x->client,
++ MCP7940X_REG_TD_HOURS,
++ (u8)(ret & ~MCP7940X_24H_BITS));
++ if(ret < 0)
++ goto out_free;
++ }
++
++ ret = i2c_smbus_read_byte_data(mcp7940x->client, MCP7940X_REG_TD_DAY);
++ if (ret < 0)
++ goto out_free;
++ /* Use external baterie if Vcc fails */
++ if (!(ret & MCP7940X_VBATEN)) {
++ ret = i2c_smbus_write_byte_data(mcp7940x->client,
++ MCP7940X_REG_TD_DAY,
++ (u8)(ret | MCP7940X_VBATEN));
++ if(ret < 0)
++ goto out_free;
++ }
++
++ ret = i2c_smbus_read_byte_data(mcp7940x->client, MCP7940X_REG_TD_SECONDS);
++ if (ret < 0)
++ goto out_free;
++
++ /* If time counter not launched, launch it */
++ if (!(ret & MCP7940X_START_BITS)) {
++ ret = i2c_smbus_write_byte_data(mcp7940x->client,
++ MCP7940X_REG_TD_SECONDS,
++ (u8)(ret | MCP7940X_START_BITS));
++ if(ret < 0)
++ goto out_free;
++
++ }
++
++ device_set_wakeup_capable(&client->dev, 1);
++ mcp7940x->rtc = rtc_device_register(client->name, &client->dev,
++ &mcp7940x_rtc_ops, THIS_MODULE);
++ if (IS_ERR(mcp7940x->rtc)) {
++ ret = PTR_ERR(mcp7940x->rtc);
++ dev_err(&client->dev, "unable to register the class device\n");
++ goto out_free;
++ }
++
++ return 0;
++
++out_free:
++ kfree(mcp7940x);
++ return ret;
++}
++
++static int __devexit mcp7940x_remove(struct i2c_client *client)
++{
++ struct mcp7940x *mcp7940x = i2c_get_clientdata(client);
++
++ rtc_device_unregister(mcp7940x->rtc);
++ kfree(mcp7940x);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int mcp7940x_suspend(struct i2c_client *client, pm_message_t state)
++{
++ return 0;
++}
++
++static int mcp7940x_resume(struct i2c_client *client)
++{
++ return 0;
++}
++#else
++#define mcp7940x_suspend NULL
++#define mcp7940x_resume NULL
++#endif
++
++static struct i2c_driver mcp7940x_driver = {
++ .driver = {
++ .name = "rtc-mcp7940x",
++ .owner = THIS_MODULE,
++ },
++ .probe = mcp7940x_probe,
++ .suspend = mcp7940x_suspend,
++ .resume = mcp7940x_resume,
++ .remove = __devexit_p(mcp7940x_remove),
++ .id_table = mcp7940x_id,
++};
++
++static int __init mcp7940x_init(void)
++{
++ return i2c_add_driver(&mcp7940x_driver);
++}
++
++static void __exit mcp7940x_exit(void)
++{
++ i2c_del_driver(&mcp7940x_driver);
++}
++
++module_init(mcp7940x_init);
++module_exit(mcp7940x_exit);
++
++MODULE_AUTHOR("Fabien Marteau <fab...@ar...>");
++MODULE_DESCRIPTION("Microchip mcp7940x RTC Driver");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.35.3/drivers/rtc/Kconfig
+===================================================================
+--- linux-2.6.35.3.orig/drivers/rtc/Kconfig 2013-07-22 10:15:39.469490871 +0200
++++ linux-2.6.35.3/drivers/rtc/Kconfig 2013-07-22 15:07:23.917032031 +0200
+@@ -245,6 +245,16 @@
+ This driver can also be built as a module. If so, the module
+ will be called rtc-m41t80.
+
++config RTC_DRV_MCP7940X
++ tristate "Microchip MCP7940X"
++ depends on RTC_CLASS && I2C
++ help
++ If you say yes here you get support for Microchip
++ MCP7940x real-time clock chips.
++
++ This driver can also be built as a module. If so, the module
++ will be called rtc-mcp7940x.
++
+ config RTC_DRV_M41T80_WDT
+ bool "ST M41T65/M41T80 series RTC watchdog timer"
+ depends on RTC_DRV_M41T80
+Index: linux-2.6.35.3/drivers/rtc/Makefile
+===================================================================
+--- linux-2.6.35.3.orig/drivers/rtc/Makefile 2013-07-22 10:15:39.469490871 +0200
++++ linux-2.6.35.3/drivers/rtc/Makefile 2013-07-22 15:08:09.837030826 +0200
+@@ -57,6 +57,7 @@
+ obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
+ obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
+ obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
++obj-$(CONFIG_RTC_DRV_MCP7940X) += rtc-mcp7940x.o
+ obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
+ obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o
+ obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
hooks/post-receive
--
armadeus
|