#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/workqueue.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <asm/delay.h>
#include <linux/delay.h>
#define MODULE_VERSION_STRING "RTC-DS3231"
#define DS3232_DRIVER_VERSION "v1.0.0"
#define DS3231_REG_SECONDS 0x00
#define DS3231_REG_MINUTES 0x01
#define DS3231_REG_HOURS 0x02
#define DS3231_REG_AMPM 0x02
#define DS3231_REG_DAY 0x03
#define DS3231_REG_DATE 0x04
#define DS3231_REG_MONTH 0x05
#define DS3231_REG_CENTURY 0x05
#define DS3231_REG_YEAR 0x06
#define DS3231_REG_ALARM1 0x07 /* Alarm 1 BASE */
#define DS3231_REG_ALARM2 0x0B /* Alarm 2 BASE */
#define DS3231_REG_CR 0x0E /* Control register */
#define DS3231_REG_CR_nEOSC 0x80
#define DS3231_REG_CR_INTCN 0x04
#define DS3231_REG_CR_A2IE 0x02
#define DS3231_REG_CR_A1IE 0x01
#define DS3231_REG_SR 0x0F /* control/status register */
#define DS3231_REG_SR_OSF 0x80
#define DS3231_REG_SR_BSY 0x04
#define DS3231_REG_SR_A2F 0x02
#define DS3231_REG_SR_A1F 0x01
#define DEVICE_NAME "ds3231rtc"
#define I2C_ADDR_DS3231 0xD0
#ifdef DS3231_DEBUG
#define HI_MSG(x...) \
do { \
printk("%s->%d: ", __FUNCTION__, __LINE__); \
printk(x); \
printk("\n"); \
} while (0)
#else
#define HI_MSG(args...) do { } while (0)
#endif
#define HI_ERR(x...) \
do { \
printk(KERN_ALERT "%s->%d: ", __FUNCTION__, __LINE__); \
printk(KERN_ALERT x); \
printk(KERN_ALERT "\n"); \
} while (0)
#ifdef DS3231_DEBUG
static void display_rtc_time_in_bcd(struct rtc_time *rtime)
{
printk("tm_sec: %u\n", rtime->tm_sec);
printk("tm_min: %u\n", rtime->tm_min);
printk("tm_hour: %u\n", rtime->tm_hour);
printk("tm_mday: %u\n", rtime->tm_mday);
printk("tm_mon: %u\n", rtime->tm_mon);
printk("tm_year: %u\n", rtime->tm_year);
printk("tm_wday: %u\n", rtime->tm_wday);
printk("tm_yday: %u\n", rtime->tm_yday);
printk("tm_isdst: %u\n", rtime->tm_isdst);
}
#endif
struct i2c_client *rtc_client;
struct rtc_time *time;
struct rtc_device *rtc;
struct ds3231rtc {
struct i2c_client *client;
struct rtc_device *rtc;
struct work_struct work;
/* The mutex protects alarm operations, and prevents a race
* between the enable_irq() in the workqueue and the free_irq()
* in the remove function.
*/
struct mutex mutex;
bool suspended;
int exiting;
};
extern int hi_i2c_dma_read(const struct i2c_client *client, unsigned int data_addr,
unsigned int reg_addr, unsigned int reg_addr_num,
unsigned int length);
extern int hi_i2c_dma_write(const