On Thu, 17 Oct 2002, Der Herr Hofrat wrote:

> > On Thu, 17 Oct 2002, leeyang wrote:
> >
> > Hi,
> >
> > I've written a rtc driver for the mpc860.  See attached files.
>
> you seem to have atached the object file not the source file - could
> you resend ?
>

Yes, sorry everyone!  See attached.

Alex

> thx !
> hofrat
>

Hope it helps.
-------------- next part --------------
/*
 * Linux/PowerPC Real Time Clock Driver
 *
 * heavily based on:
 * Linux/SPARC Real Time Clock Driver
 * Copyright (C) 1996 Thomas K. Dyas (tdyas at eden.rutgers.edu)
 *
 * This is a little driver that lets a user-level program access
 * the PPC clocks chip. It is no use unless you
 * use the modified clock utility.
 *
 * Get the modified clock utility from:
 *   ftp://vger.rutgers.edu/pub/linux/Sparc/userland/clock.c
 */

#ifndef USERLAND_TESTCODE
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/mc146818rtc.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>

#include <asm/time.h>

static int rtc_busy = 0;

/* Retrieve the current date and time from the real time clock. */
void get_rtc_time(struct rtc_time *t)
{
        unsigned long nowtime;
    
        nowtime = (ppc_md.get_rtc_time)();

        to_tm(nowtime, t);

        t->tm_year -= 1900;
        t->tm_mon -= 1;
        t->tm_wday -= 1;
}

/* Set the current date and time in the real time clock. */
void set_rtc_time(struct rtc_time *t)
{
        unsigned long nowtime;

        printk(KERN_INFO "rtc.c:set_rtc_time: %04d-%02d-%02d 
%02d:%02d:%02d.\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, 
t->tm_min, t->tm_sec);

        nowtime = mktime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, 
t->tm_min, t->tm_sec);

        printk(KERN_INFO "rtc.c:set_rtc_time: set rtc time to %ld seconds.\n", 
nowtime);

        (ppc_md.set_rtc_time)(nowtime);
}

static loff_t rtc_lseek(struct file *file, loff_t offset, int origin)
{
        return -ESPIPE;
}

static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
{
        struct rtc_time rtc_tm;

        switch (cmd)
        {
        case RTC_RD_TIME:
                if (ppc_md.get_rtc_time)
                {
                        get_rtc_time(&rtc_tm);

                        if (copy_to_user((struct rtc_time*)arg, &rtc_tm, 
sizeof(struct rtc_time)))
                                return -EFAULT;

                        return 0;
                }
                else
                        return -EINVAL;

        case RTC_SET_TIME:
                if (!capable(CAP_SYS_TIME))
                        return -EPERM;

                if (ppc_md.set_rtc_time)
                {
                        if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, 
sizeof(struct rtc_time)))
                                return -EFAULT;

                        set_rtc_time(&rtc_tm);

                        return 0;
                }
                else
                        return -EINVAL;

        default:
                return -EINVAL;
        }
}

static int rtc_open(struct inode *inode, struct file *file)
{
        if (rtc_busy)
                return -EBUSY;

        rtc_busy = 1;

        MOD_INC_USE_COUNT;

        return 0;
}

static int rtc_release(struct inode *inode, struct file *file)
{
        MOD_DEC_USE_COUNT;
        rtc_busy = 0;
        return 0;
}

static struct file_operations rtc_fops = {
        owner:          THIS_MODULE,
        llseek:         rtc_lseek,
        ioctl:          rtc_ioctl,
        open:           rtc_open,
        release:        rtc_release
};

static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };

EXPORT_NO_SYMBOLS;

static int __init rtc_init(void)
{
        int error;

        error = misc_register(&rtc_dev);
        if (error) {
                printk(KERN_ERR "rtc: unable to get misc minor\n");
                return error;
        }

        return 0;
}

static void __exit rtc_exit(void)
{
        misc_deregister(&rtc_dev);
}

module_init(rtc_init);
module_exit(rtc_exit);

#else /* ifndef USERLAND_TESTCODE */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <asm/ioctls.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <time.h>
#include <linux/rtc.h>                  /* get the user-level API */

static char * days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
static char * months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", 
"Aug", "Sep", "Oct", "Nov", "Dec"};
static void print_time(struct rtc_time * t)
{
    printf("%s %s %d %02d:%02d:%02d (DST=%s) %d\n",
           days[t->tm_wday],
           months[t->tm_mon],
           t->tm_mday,
           t->tm_hour,t->tm_min,t->tm_sec,
           (t->tm_isdst)?"On":"Off",
           t->tm_year+1900);
}

int main (int argc, char **argv)
{
    int s; 
    struct rtc_time rtctime;

    s = open("/dev/rtc", O_RDWR);

    if (argc < 2)
        goto usage;
    
    if (strcmp(argv[1],"r") == 0)
    {
        if(ioctl(s, RTC_RD_TIME, &rtctime))
            perror("ioctl");
        else
            print_time(&rtctime);
    }
    else if (strcmp(argv[1],"w") == 0)
    {
        if (argc == 2) {
            time_t t = time(NULL);
            struct tm *systime = localtime(&t);
            rtctime.tm_sec = systime->tm_sec;
            rtctime.tm_min = systime->tm_min;
            rtctime.tm_hour = systime->tm_hour;
            rtctime.tm_mday = systime->tm_mday;
            rtctime.tm_mon = systime->tm_mon;
            rtctime.tm_year = systime->tm_year;
            rtctime.tm_wday = systime->tm_wday;
            rtctime.tm_yday = 0; /* unused by mpc8xx */
            rtctime.tm_isdst = systime->tm_isdst;
        } else {
            if (argc < 10)
                goto usage;
            if (sscanf(argv[2],"%d", &rtctime.tm_sec) != 1)
                goto usage;
            if (sscanf(argv[3],"%d", &rtctime.tm_min) != 1)
                goto usage;
            if (sscanf(argv[4],"%d", &rtctime.tm_hour) != 1)
                goto usage;
            if (sscanf(argv[5],"%d", &rtctime.tm_mday) != 1)
                goto usage;
            if (sscanf(argv[6],"%d", &rtctime.tm_mon) != 1)
                goto usage;
            if (sscanf(argv[7],"%d", &rtctime.tm_year) != 1)
                goto usage;
            if (sscanf(argv[8],"%d", &rtctime.tm_wday) != 1)
                goto usage;
            rtctime.tm_yday = 0; /* unused by mpc8xx */
            if (sscanf(argv[9],"%d", &rtctime.tm_isdst) != 1)
                goto usage;
        }
        if(ioctl(s, RTC_SET_TIME, &rtctime))
            perror("ioctl");
    }
    else
        goto usage;

    close(s);        
    return 0;

 usage:
    close(s);
    printf("i)   %s r\n"
           "ii)  %s w\n"
           "iii) %s w sec min hour mday mon year wday isdst\n"
           "Notes:\n"
           "\t(i)   reads time from RTC.\n"
           "\t(ii)  writes current system time to RTC.\n"
           "\t(iii) writes remaining params to RTC.\n"
           "\t(All parameters are decimal integers\n"
           "\tSee man mktime for parameter ranges)\n", argv[0],argv[0],argv[0]);
    return -1;
}

#endif /* USERLAND_TESTCODE */
-------------- next part --------------
##########################################################################
#
#            Copyright (C) 2001 Cambridge Broadband Ltd,
#                    Edinburgh House, Cowley Road
#                        Cambridge, England
#                              CB4 0DS
#
#                         ++44 1223 713000
#
#                   enquiries at cambridgebroadband.com
#
#                   http://www.cambridgebroadband.com                    
#
##########################################################################

CC = ppc_8xx-gcc
KERNELDIR = ../../kernel
DEBUG = -g
NODEBUG =
KERN_CFLAGS = -DMODULE -D__KERNEL__ -I$(KERNELDIR)/include -O2 -Wall $(NODEBUG)
USER_CFLAGS = -DUSERLAND_TESTCODE -I$(KERNELDIR)/include -O2 -Wall $(NODEBUG)
TARGETS = rtc.o rtc


all: $(TARGETS)

rtc.o: rtc.c
        $(CC) $(KERN_CFLAGS) -c rtc.c

rtc: rtc.c
        $(CC) $(USER_CFLAGS) -o $@ rtc.c

clean:
        rm -f $(TARGETS)

Reply via email to