6959
- 收藏
- 点赞
- 分享
- 举报
海思平台rtc驱动参考
海思平台rtc驱动参考
头文件如下
[code]/*
* include/hi_rtc.h for Linux .
*
* This file defines hi_rtc micro-definitions for driver developer.
*
* History:
* 10-April-2006 create this file
*/
#ifndef __HI_RTC__
#define __HI_RTC__
#define OSDRV_MODULE_VERSION_STRING "HISI_RTC-MDC030001 @Hi3511v110_OSDrv_1_0_0_7 2009-03-18 20:53:48"
#define HI_RTC_AIE_ON _IO('p', 0x01)
#define HI_RTC_AIE_OFF _IO('p', 0x02)
#define HI_RTC_ALM_SET _IOW('p', 0x07, rtc_time_t)
#define HI_RTC_ALM_READ _IOR('p', 0x08, rtc_time_t)
#define HI_RTC_RD_TIME _IOR('p', 0x09, rtc_time_t)
#define HI_RTC_SET_TIME _IOW('p', 0x0a, rtc_time_t)
typedef struct
{
unsigned int year;
unsigned int month;
unsigned int date;
unsigned int hour;
unsigned int minute;
unsigned int second;
unsigned int weekday;
} rtc_time_t;
#endif
[/code]
.c文件
[code]/* extdrv/peripheral/rtc/hi_rtc.c
*
* Copyright (c) 2006 Hisilicon Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program;
*
* History:
* 10-April-2006 create this file
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "hi_rtc.h"
#define RTC_PHY_ADDR IO_ADDRESS(0x101e8000)
#define RTC_DR RTC_PHY_ADDR + 0x000
#define RTC_MR RTC_PHY_ADDR + 0x004
#define RTC_LR RTC_PHY_ADDR + 0x008
#define RTC_CR RTC_PHY_ADDR + 0x00c
#define RTC_CR_MASK 0x00000001
#define RTC_CR_START 0x00000001
#define RTC_CR_STOP 0x00000000
#define RTC_IMSC RTC_PHY_ADDR + 0x010
#define RTC_IMSC_MASK 0x00000001
#define RTC_IMSC_ENABLE 0x00000001
#define RTC_IMSC_DISABLE 0x00000000
#define RTC_RIS RTC_PHY_ADDR + 0x014
#define RTC_RIS_MASK 0x00000001
#define RTC_MIS RTC_PHY_ADDR + 0x018
#define RTC_MIS_MASK 0x00000001
#define RTC_ICR RTC_PHY_ADDR + 0x01C
#define RTC_ICR_MASK 0x00000001
#define RTC_ICR_CLEAR 0x00000001
#define IRQ_RTC 10
#define SC_PERCTRL0 IO_ADDRESS(0x101e001c)
spinlock_t rtc_lock;
static unsigned long rtc_status = 0;
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
/*
* interrupt function
* do nothing. left for future
*/
static irqreturn_t rtc_alm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int handled;
writel(0x01,RTC_ICR);
handled = 1;
return IRQ_RETVAL(handled);
}
/*
* converse the data type from year.mouth.data.hour.minite.second to second
* define 2000.1.1.0.0.0 as jumping-off point
*/
static int rtcdate2second(rtc_time_t compositetime, unsigned long *ptimeOfsecond)
{
struct rtc_time tmp;
if (compositetime.weekday > 6){
return -1;
}
tmp.tm_year = compositetime.year - 1900;
tmp.tm_mon = compositetime.month - 1;
tmp.tm_mday = compositetime.date;
tmp.tm_wday = compositetime.weekday;
tmp.tm_hour = compositetime.hour;
tmp.tm_min = compositetime.minute;
tmp.tm_sec = compositetime.second;
return rtc_valid_tm(&tmp) == 0 ? rtc_tm_to_time(&tmp, ptimeOfsecond) : -1;
}
/*
* converse the data type from second to year.mouth.data.hour.minite.second
* define 2000.1.1.0.0.0 as jumping-off point
*/
int rtcSecond2Date(rtc_time_t *compositetime,unsigned long timeOfsecond)
{
struct rtc_time tmp ;
rtc_time_to_tm(timeOfsecond,&tmp);
compositetime->year = (unsigned int)tmp.tm_year + 1900;
compositetime->month = (unsigned int)tmp.tm_mon + 1;
compositetime->date = (unsigned int)tmp.tm_mday;
compositetime->hour = (unsigned int)tmp.tm_hour;
compositetime->minute = (unsigned int)tmp.tm_min;
compositetime->second = (unsigned int)tmp.tm_sec;
compositetime->weekday = (unsigned int)tmp.tm_wday;
return 0;
}
/*
* set time
*/
int rtc_set(rtc_time_t compositetime)
{
int status;
unsigned long timeofsecond;
status = rtcdate2second(compositetime , &timeofsecond);
if (0 != status)
{
return status;
}
writel(timeofsecond,RTC_LR);
writel(0x01,RTC_CR);
return 0;
}
/*
* get current time
* the type of return value is rtc_time_t
*/
int rtc_get(rtc_time_t *pcompositetime)
{
int status;
unsigned int timeofsecond;
timeofsecond = readl(RTC_DR);
status = rtcSecond2Date(pcompositetime , timeofsecond);
return status;
}
/*
* get current ALM time
* the type of return value is rtc_time_t
*/
int rtc_getalm(rtc_time_t *pcompositetime)
{
int status;
unsigned int timeofsecond;
timeofsecond = readl(RTC_MR);
status = rtcSecond2Date(pcompositetime , timeofsecond);
return 0;
}
/*
* set alarm. param type is second
* After u32DelaySecond(s), a int will generate
*/
int rtc_alarm_simple_set(unsigned int u32DelaySecond)
{
unsigned int PdataRegValue = 0;
unsigned int matchRegValue = 0;
if ((u32DelaySecond <= 0) || (u32DelaySecond == 0xFFFFFFFF))
{
#ifdef DEBUG_AMBA_RTC
printk("\nERRER:RTC delay time low than 1 second or too long! \n");
#endif
return - EINVAL;
}
PdataRegValue = readl(RTC_DR);
matchRegValue = PdataRegValue + u32DelaySecond;
/* Judge whether the value (dataRegValue + delaySecond)> 0xFFFFFFFF or not*/
if (matchRegValue < PdataRegValue )
{
#ifdef DEBUG_AMBA_RTC
printk("\nWarning:RTC alarm time wraps arounded ! \n");
#endif
}
writel(matchRegValue,RTC_MR);
return 0;
}
/*
* set alam. param type is rtc_time_t
* when the time comes to stCompositeTime, a init will generate
*/
int rtc_alarm_complex_set(rtc_time_t stCompositeTime)
{
unsigned long timeofsecond;
unsigned int dataRegValue = 0;
unsigned int matchRegValue = 0;
if(rtcdate2second(stCompositeTime,&timeofsecond) == 0)
{
if ((timeofsecond <= 0) || (timeofsecond == 0xFFFFFFFF))
{
#ifdef DEBUG_AMBA_RTC
printk("\nERRER:RTC delay time low than 1 second or too long! \n");
#endif
return - EINVAL;
}
matchRegValue = timeofsecond;
/* Judge whether the value (dataRegValue + delaySecond)> 0xFFFFFFFF or not*/
if (matchRegValue < dataRegValue )
{
#ifdef DEBUG_AMBA_RTC
printk("\nWarning:RTC alarm time wraps arounded ! \n");
#endif
}
writel(matchRegValue,RTC_MR);
return 0;
}
else
{
printk("set time error!");
return - EINVAL;
}
}
/*
* ioctl function. for usr to control RTC
* parameter:
* RTC_AIE_ON: enable interrupt
* RTC_AIE_OFF: disable interrupt
* RTC_ALM_READ: get current alm time
* RTC_ALM_SET: set alm. type of input is rtc_time_t.
* RTC_RD_TIME: get current time
* RTC_SET_TIME: set time. type of input is rtc_time_t.
*/
static int hi_rtc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
rtc_time_t tm;
switch (cmd)
{
/* Alarm interrupt on/off */
case HI_RTC_AIE_ON:
writel(RTC_IMSC_ENABLE , RTC_IMSC);
return 0;
case HI_RTC_AIE_OFF:
writel(RTC_IMSC_DISABLE , RTC_IMSC);
return 0;
case HI_RTC_ALM_READ:
rtc_getalm(&tm);
if (copy_to_user((void *)arg, &tm, sizeof(tm)))
return -EFAULT;
return 0;
case HI_RTC_ALM_SET:
if (copy_from_user(&tm, (struct rtc_time_t*) arg, sizeof(tm)))
return -EFAULT;
return rtc_alarm_complex_set(tm);
case HI_RTC_RD_TIME:
rtc_get(&tm);
return copy_to_user((void *)arg, &tm, sizeof(tm)) ? -EFAULT : 0;
case HI_RTC_SET_TIME:
if (copy_from_user(&tm, (struct rtc_time_t *) arg, sizeof(tm)))
return -EFAULT;
return rtc_set(tm);
default:
return -EINVAL;
}
}
#ifdef CONFIG_PROC_FS
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
char *p = page;
int len;
rtc_time_t tm;
rtc_get(&tm);
p += sprintf(
p, "rtc_time\t: %02d:%02d:%02d\n"
"rtc_date\t: %04d-%02d-%02d\n",
tm.hour, tm.minute, tm.second,
tm.year + 1900, tm.month + 1, tm.date
);
len = (p - page) - off;
if (len < 0)len = 0;
*eof = (len <= count) ? 1 : 0;
*start = page + off;
return len;
}
#endif
/* open device*/
static int hi_rtc_open(struct inode *inode, struct file *file)
{
spin_lock_init(&rtc_lock);
spin_lock_irq(&rtc_lock);
if (rtc_status)
{
spin_unlock_irq(&rtc_lock);
return -EBUSY;
}
/* set dev is busy */
rtc_status = 1;
spin_unlock_irq(&rtc_lock);
return 0;
}
static int hi_rtc_release(struct inode *inode, struct file *file)
{
rtc_status = 0;
return 0;
}
static struct file_operations hi_rtc_fops =
{
owner: THIS_MODULE,
ioctl: hi_rtc_ioctl,
open: hi_rtc_open,
release: hi_rtc_release,
};
static struct miscdevice hi_rtc_dev=
{
RTC_MINOR,
"hi_rtc",
&hi_rtc_fops
};
/*
* int hi_rtc_init(void)
* default time is 2000.1.1.0.0.0
*/
static int __init rtc_init(void)
{
int ret;
ret = misc_register(&hi_rtc_dev);
if (0 != ret)
{
printk("rtc device register failed!\n");
return -EFAULT;
}
#ifdef CONFIG_PROC_FS
create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL);
#endif
ret = request_irq(IRQ_RTC, &rtc_alm_interrupt, 0, \
"RTC Alarm", NULL);
if (0 != ret)
{
printk(" hi3511 rtc: failed to register IRQ_RTC(%d)\n", IRQ_RTC);
goto IRQ_RTC_failed;
}
/*cancel reset status, l60018938 added*/
{
unsigned int d;
d = readl(SC_PERCTRL0);
d |= 0x800000;
writel(d,SC_PERCTRL0);
}
writel(0x01,RTC_ICR);
writel(0x01,RTC_CR);
printk(KERN_INFO OSDRV_MODULE_VERSION_STRING);
return 0;
IRQ_RTC_failed:
#ifdef CONFIG_PROC_FS
remove_proc_entry("driver/rtc", NULL);
#endif
misc_deregister(&hi_rtc_dev);
return ret;
}
static void __exit rtc_exit(void)
{
free_irq(IRQ_RTC, NULL);
#ifdef CONFIG_PROC_FS
remove_proc_entry("driver/rtc", NULL);
#endif
misc_deregister(&hi_rtc_dev);
}
module_init(rtc_init);
module_exit(rtc_exit);
MODULE_AUTHOR("Digital Media Team ,Hisilicon crop ");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Real Time Clock interface for HI3511");
MODULE_ALIAS_MISCDEV(RTC_MINOR);
MODULE_VERSION("HI_VERSION=" OSDRV_MODULE_VERSION_STRING);
[/code]
make file
[code]#
# Makefile for the Linux kernel device drivers.
#
# 2006-04-04, designed by huawei corp.
# written as internal module's Makefile.
#
#KERNEL_MAKE := -C /home/shared/snapshoot/Hi3511v100_FPGA_OSDrv-LastRelease/sdk/pub/kbuild/
KERNEL_MAKE := -C ../../../pub/kbuild-LESS_REL
obj-m += hirtc.o
hirtc-y := hi_rtc.o
default:
make $(KERNEL_MAKE) M=$(PWD) modules
clean:
make $(KERNEL_MAKE) M=$(PWD) clean
[/code]
头文件如下
[code]/*
* include/hi_rtc.h for Linux .
*
* This file defines hi_rtc micro-definitions for driver developer.
*
* History:
* 10-April-2006 create this file
*/
#ifndef __HI_RTC__
#define __HI_RTC__
#define OSDRV_MODULE_VERSION_STRING "HISI_RTC-MDC030001 @Hi3511v110_OSDrv_1_0_0_7 2009-03-18 20:53:48"
#define HI_RTC_AIE_ON _IO('p', 0x01)
#define HI_RTC_AIE_OFF _IO('p', 0x02)
#define HI_RTC_ALM_SET _IOW('p', 0x07, rtc_time_t)
#define HI_RTC_ALM_READ _IOR('p', 0x08, rtc_time_t)
#define HI_RTC_RD_TIME _IOR('p', 0x09, rtc_time_t)
#define HI_RTC_SET_TIME _IOW('p', 0x0a, rtc_time_t)
typedef struct
{
unsigned int year;
unsigned int month;
unsigned int date;
unsigned int hour;
unsigned int minute;
unsigned int second;
unsigned int weekday;
} rtc_time_t;
#endif
[/code]
.c文件
[code]/* extdrv/peripheral/rtc/hi_rtc.c
*
* Copyright (c) 2006 Hisilicon Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program;
*
* History:
* 10-April-2006 create this file
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "hi_rtc.h"
#define RTC_PHY_ADDR IO_ADDRESS(0x101e8000)
#define RTC_DR RTC_PHY_ADDR + 0x000
#define RTC_MR RTC_PHY_ADDR + 0x004
#define RTC_LR RTC_PHY_ADDR + 0x008
#define RTC_CR RTC_PHY_ADDR + 0x00c
#define RTC_CR_MASK 0x00000001
#define RTC_CR_START 0x00000001
#define RTC_CR_STOP 0x00000000
#define RTC_IMSC RTC_PHY_ADDR + 0x010
#define RTC_IMSC_MASK 0x00000001
#define RTC_IMSC_ENABLE 0x00000001
#define RTC_IMSC_DISABLE 0x00000000
#define RTC_RIS RTC_PHY_ADDR + 0x014
#define RTC_RIS_MASK 0x00000001
#define RTC_MIS RTC_PHY_ADDR + 0x018
#define RTC_MIS_MASK 0x00000001
#define RTC_ICR RTC_PHY_ADDR + 0x01C
#define RTC_ICR_MASK 0x00000001
#define RTC_ICR_CLEAR 0x00000001
#define IRQ_RTC 10
#define SC_PERCTRL0 IO_ADDRESS(0x101e001c)
spinlock_t rtc_lock;
static unsigned long rtc_status = 0;
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
/*
* interrupt function
* do nothing. left for future
*/
static irqreturn_t rtc_alm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int handled;
writel(0x01,RTC_ICR);
handled = 1;
return IRQ_RETVAL(handled);
}
/*
* converse the data type from year.mouth.data.hour.minite.second to second
* define 2000.1.1.0.0.0 as jumping-off point
*/
static int rtcdate2second(rtc_time_t compositetime, unsigned long *ptimeOfsecond)
{
struct rtc_time tmp;
if (compositetime.weekday > 6){
return -1;
}
tmp.tm_year = compositetime.year - 1900;
tmp.tm_mon = compositetime.month - 1;
tmp.tm_mday = compositetime.date;
tmp.tm_wday = compositetime.weekday;
tmp.tm_hour = compositetime.hour;
tmp.tm_min = compositetime.minute;
tmp.tm_sec = compositetime.second;
return rtc_valid_tm(&tmp) == 0 ? rtc_tm_to_time(&tmp, ptimeOfsecond) : -1;
}
/*
* converse the data type from second to year.mouth.data.hour.minite.second
* define 2000.1.1.0.0.0 as jumping-off point
*/
int rtcSecond2Date(rtc_time_t *compositetime,unsigned long timeOfsecond)
{
struct rtc_time tmp ;
rtc_time_to_tm(timeOfsecond,&tmp);
compositetime->year = (unsigned int)tmp.tm_year + 1900;
compositetime->month = (unsigned int)tmp.tm_mon + 1;
compositetime->date = (unsigned int)tmp.tm_mday;
compositetime->hour = (unsigned int)tmp.tm_hour;
compositetime->minute = (unsigned int)tmp.tm_min;
compositetime->second = (unsigned int)tmp.tm_sec;
compositetime->weekday = (unsigned int)tmp.tm_wday;
return 0;
}
/*
* set time
*/
int rtc_set(rtc_time_t compositetime)
{
int status;
unsigned long timeofsecond;
status = rtcdate2second(compositetime , &timeofsecond);
if (0 != status)
{
return status;
}
writel(timeofsecond,RTC_LR);
writel(0x01,RTC_CR);
return 0;
}
/*
* get current time
* the type of return value is rtc_time_t
*/
int rtc_get(rtc_time_t *pcompositetime)
{
int status;
unsigned int timeofsecond;
timeofsecond = readl(RTC_DR);
status = rtcSecond2Date(pcompositetime , timeofsecond);
return status;
}
/*
* get current ALM time
* the type of return value is rtc_time_t
*/
int rtc_getalm(rtc_time_t *pcompositetime)
{
int status;
unsigned int timeofsecond;
timeofsecond = readl(RTC_MR);
status = rtcSecond2Date(pcompositetime , timeofsecond);
return 0;
}
/*
* set alarm. param type is second
* After u32DelaySecond(s), a int will generate
*/
int rtc_alarm_simple_set(unsigned int u32DelaySecond)
{
unsigned int PdataRegValue = 0;
unsigned int matchRegValue = 0;
if ((u32DelaySecond <= 0) || (u32DelaySecond == 0xFFFFFFFF))
{
#ifdef DEBUG_AMBA_RTC
printk("\nERRER:RTC delay time low than 1 second or too long! \n");
#endif
return - EINVAL;
}
PdataRegValue = readl(RTC_DR);
matchRegValue = PdataRegValue + u32DelaySecond;
/* Judge whether the value (dataRegValue + delaySecond)> 0xFFFFFFFF or not*/
if (matchRegValue < PdataRegValue )
{
#ifdef DEBUG_AMBA_RTC
printk("\nWarning:RTC alarm time wraps arounded ! \n");
#endif
}
writel(matchRegValue,RTC_MR);
return 0;
}
/*
* set alam. param type is rtc_time_t
* when the time comes to stCompositeTime, a init will generate
*/
int rtc_alarm_complex_set(rtc_time_t stCompositeTime)
{
unsigned long timeofsecond;
unsigned int dataRegValue = 0;
unsigned int matchRegValue = 0;
if(rtcdate2second(stCompositeTime,&timeofsecond) == 0)
{
if ((timeofsecond <= 0) || (timeofsecond == 0xFFFFFFFF))
{
#ifdef DEBUG_AMBA_RTC
printk("\nERRER:RTC delay time low than 1 second or too long! \n");
#endif
return - EINVAL;
}
matchRegValue = timeofsecond;
/* Judge whether the value (dataRegValue + delaySecond)> 0xFFFFFFFF or not*/
if (matchRegValue < dataRegValue )
{
#ifdef DEBUG_AMBA_RTC
printk("\nWarning:RTC alarm time wraps arounded ! \n");
#endif
}
writel(matchRegValue,RTC_MR);
return 0;
}
else
{
printk("set time error!");
return - EINVAL;
}
}
/*
* ioctl function. for usr to control RTC
* parameter:
* RTC_AIE_ON: enable interrupt
* RTC_AIE_OFF: disable interrupt
* RTC_ALM_READ: get current alm time
* RTC_ALM_SET: set alm. type of input is rtc_time_t.
* RTC_RD_TIME: get current time
* RTC_SET_TIME: set time. type of input is rtc_time_t.
*/
static int hi_rtc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
rtc_time_t tm;
switch (cmd)
{
/* Alarm interrupt on/off */
case HI_RTC_AIE_ON:
writel(RTC_IMSC_ENABLE , RTC_IMSC);
return 0;
case HI_RTC_AIE_OFF:
writel(RTC_IMSC_DISABLE , RTC_IMSC);
return 0;
case HI_RTC_ALM_READ:
rtc_getalm(&tm);
if (copy_to_user((void *)arg, &tm, sizeof(tm)))
return -EFAULT;
return 0;
case HI_RTC_ALM_SET:
if (copy_from_user(&tm, (struct rtc_time_t*) arg, sizeof(tm)))
return -EFAULT;
return rtc_alarm_complex_set(tm);
case HI_RTC_RD_TIME:
rtc_get(&tm);
return copy_to_user((void *)arg, &tm, sizeof(tm)) ? -EFAULT : 0;
case HI_RTC_SET_TIME:
if (copy_from_user(&tm, (struct rtc_time_t *) arg, sizeof(tm)))
return -EFAULT;
return rtc_set(tm);
default:
return -EINVAL;
}
}
#ifdef CONFIG_PROC_FS
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
char *p = page;
int len;
rtc_time_t tm;
rtc_get(&tm);
p += sprintf(
p, "rtc_time\t: %02d:%02d:%02d\n"
"rtc_date\t: %04d-%02d-%02d\n",
tm.hour, tm.minute, tm.second,
tm.year + 1900, tm.month + 1, tm.date
);
len = (p - page) - off;
if (len < 0)len = 0;
*eof = (len <= count) ? 1 : 0;
*start = page + off;
return len;
}
#endif
/* open device*/
static int hi_rtc_open(struct inode *inode, struct file *file)
{
spin_lock_init(&rtc_lock);
spin_lock_irq(&rtc_lock);
if (rtc_status)
{
spin_unlock_irq(&rtc_lock);
return -EBUSY;
}
/* set dev is busy */
rtc_status = 1;
spin_unlock_irq(&rtc_lock);
return 0;
}
static int hi_rtc_release(struct inode *inode, struct file *file)
{
rtc_status = 0;
return 0;
}
static struct file_operations hi_rtc_fops =
{
owner: THIS_MODULE,
ioctl: hi_rtc_ioctl,
open: hi_rtc_open,
release: hi_rtc_release,
};
static struct miscdevice hi_rtc_dev=
{
RTC_MINOR,
"hi_rtc",
&hi_rtc_fops
};
/*
* int hi_rtc_init(void)
* default time is 2000.1.1.0.0.0
*/
static int __init rtc_init(void)
{
int ret;
ret = misc_register(&hi_rtc_dev);
if (0 != ret)
{
printk("rtc device register failed!\n");
return -EFAULT;
}
#ifdef CONFIG_PROC_FS
create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL);
#endif
ret = request_irq(IRQ_RTC, &rtc_alm_interrupt, 0, \
"RTC Alarm", NULL);
if (0 != ret)
{
printk(" hi3511 rtc: failed to register IRQ_RTC(%d)\n", IRQ_RTC);
goto IRQ_RTC_failed;
}
/*cancel reset status, l60018938 added*/
{
unsigned int d;
d = readl(SC_PERCTRL0);
d |= 0x800000;
writel(d,SC_PERCTRL0);
}
writel(0x01,RTC_ICR);
writel(0x01,RTC_CR);
printk(KERN_INFO OSDRV_MODULE_VERSION_STRING);
return 0;
IRQ_RTC_failed:
#ifdef CONFIG_PROC_FS
remove_proc_entry("driver/rtc", NULL);
#endif
misc_deregister(&hi_rtc_dev);
return ret;
}
static void __exit rtc_exit(void)
{
free_irq(IRQ_RTC, NULL);
#ifdef CONFIG_PROC_FS
remove_proc_entry("driver/rtc", NULL);
#endif
misc_deregister(&hi_rtc_dev);
}
module_init(rtc_init);
module_exit(rtc_exit);
MODULE_AUTHOR("Digital Media Team ,Hisilicon crop ");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Real Time Clock interface for HI3511");
MODULE_ALIAS_MISCDEV(RTC_MINOR);
MODULE_VERSION("HI_VERSION=" OSDRV_MODULE_VERSION_STRING);
[/code]
make file
[code]#
# Makefile for the Linux kernel device drivers.
#
# 2006-04-04, designed by huawei corp.
# written as internal module's Makefile.
#
#KERNEL_MAKE := -C /home/shared/snapshoot/Hi3511v100_FPGA_OSDrv-LastRelease/sdk/pub/kbuild/
KERNEL_MAKE := -C ../../../pub/kbuild-LESS_REL
obj-m += hirtc.o
hirtc-y := hi_rtc.o
default:
make $(KERNEL_MAKE) M=$(PWD) modules
clean:
make $(KERNEL_MAKE) M=$(PWD) clean
[/code]
我来回答
回答2个
时间排序
认可量排序
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2015-03-31 16:47:32
-
2017-06-16 15:04:40
-
2018-01-22 17:59:17
-
2019-09-23 16:12:05
-
2018-10-16 21:42:09
-
2016-02-26 13:41:45
-
2015-03-31 18:05:13
-
2016-09-05 21:47:19
-
2024-03-12 09:23:24
-
2016-01-22 11:32:00
-
2019-12-30 09:31:50
-
2019-12-30 09:44:52
-
2018-04-20 17:55:15
-
2019-07-19 14:43:00
-
2018-01-28 22:46:04
-
2018-04-11 17:29:03
-
2023-02-15 17:07:43
-
2020-04-22 18:14:36
-
2018-12-09 10:43:49
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认