13 Replies Latest reply: Nov 9, 2012 11:52 AM by timsoft RSS

has anyone got a linux kernel driver for mcp79410 rtc  -solved

timsoft

I originally ordered a BQ320000DR from farnell to make a rtc module for my raspberrypi. there is a kernel driver for this rtc i2c chip.

unfortunately, the chip still hasn't arrived, and in the mean-time I ordered a MCP79410-I/SN RTCC (i2c).

I can see this on the i2c bus (address 6F) but there doesn't appear to be kernel drivers for this device (mcp7941x series)

If there was another chip which was functionally the same, but with a kernel driver, I could just copy it's driver and change the chip name throughout the code.

 

does anyone know of a i2c chip for which there is kernel support, which is similar to the mcp79410?

 

I have the list of currently supported rtc chips (see drivers/rtc in the kernel source)

 

88pm80x,88pm860x,ab3100,ab8500,at32ap700x,at91rm9200,at91sam9,au1xxx,bfin,bq32k,bq4802,cmos,coh901331,core,da9052,davinci,dev,dm355evm,

ds1216,ds1286,ds1302,ds1305,ds1307,ds1374,ds1390,ds1511,ds1553,ds1672,ds1742,ds3232,ds3234,efi,em3027,ep93xx,fm3130,generic,imxdi,isl12022,

isl1208,jz4740,lib,lpc32xx,ls1x,m41t80,m41t93,m41t94,m48t35,m48t59,m48t86,max6900,max6902,max8925,max8998,mc13xxx,mpc5121,mrst,msm6242,

mv,mxc,nuc900,omap,pcap,pcf2123,pcf50633,pcf8563,pcf8583,pl030,pl031,pm8xxx,proc,ps3,puv3,pxa,r9701,rp5c01,rs5c313,rs5c348,rs5c372,rv3029c2,

rx8025,rx8581,s35390a,s3c,sa1100,sh,spear,starfire,stk17ta8,stmp3xxx,sun4v,sysfs,tegra,test,tile,twl,tx4939,v3020,vr41xx,vt8500,wm831x,wm8350,x1205

 

thanks

  • 1. Re: has anyone got a linux kernel driver for mcp79410 rtc

    Hi Tim!

     

    You want the ds1307 driver, however it sort of depends which kernel you're running, the patch to add the mcp7941x series isn't in the 3.1.9+ kernel that's default in most of the current distros.  If you're ok with patching your kernel and re-compling it then you can find the patch here: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=43fcb81550f7a16be192b19c77a379c9b27b1585 but be aware that it may not apply cleanly to the older kernel depending on what other changes there were.

     

    However the patch did make it into 3.2, so if you don't want to mess with kernel compiling then have a look at Chris Boots kernel http://www.bootc.net/projects/raspberry-pi-kernel/

     

    I'd also suggest asking Raspberry Pi questions over in the Raspberry Pi section http://www.element14.com/community/groups/raspberry-pi?ICID=technologies_rpi_menubar. There's a fair number of us over there willing to help, but we're not necessarily going to see stuff here in the Experts section.

  • 2. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    thanks very much selsinork.

    My next challenge will be to get the 3.1.9 kernel source for my current armedslack install on my raspberrypi, as the source is not at kernel.org anymore;

    or, find out the config with special raspberrypi blobs and patches and see if I can get the 3.6rc1 kernel built instead. I'll post in the raspberry pi section in future, but there still seams to be a problem with posts dissapearing entirely on all the forums here at element14/farnell

  • 3. Re: has anyone got a linux kernel driver for mcp79410 rtc

    http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.1.9.tar.gz still seems to be there..

     

    'official' 3.1.9 kernel source for the Pi is available here https://github.com/raspberrypi/linux and this will include all the necessary drivers.

     

    You're unlikely to get 3.6rc1 working, there are too many missing pieces and there's a lot of changes to arm code between 3.1.9 and 3.6 making forward porting it far from simple..

    That said, if you're a wizard kernel developer then you should go look at  https://github.com/lp0/linux Simon Arlott and Chris Boot have done a bunch of work in this direction. You'll need this too https://github.com/raspberrypi/linux/wiki/Device-Tree-port and you probably want to sign up to the mailing list http://lists.infradead.org/mailman/listinfo/linux-rpi-kernel

     

    It appears that either an admin moved the thread into the Raspberry Pi area, or it magically disappeared only to turn up in the right place on it's own

  • 4. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    well I'm not a wizard kernel developer, I've compiled a few custom kernels for pc's but that's about it. Thanks for the pointer to the 3.1.9 kernel source. I should have hunted further on the site. I'l get that downloaded and see I can get the rtc module happy.

  • 5. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    just an update. I tried the patch on the kernel and it didn't like it, so I manually put in the changes roughly comparing them with the 3.6rc1. with modifying the include/linux/vermagic.h I can get the module to compile, but when I try insmod rtc-ds1307.ko it complains of an "-1 unknown symbol in module". the joys :-(

  • 6. Re: has anyone got a linux kernel driver for mcp79410 rtc
    Drew Fustini

    What version of the kernel were you modifying for those changes in 3.6rc1?  The Foundation's 3.1.9+?

     

    (btw, in case it's any help, I wrote this document awhile back http://www.element14.com/community/docs/DOC-44948/l/compiling-linux-kernel-staging-driver-modules)


  • 7. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    yes, the 3.1.9+ one from github/raspberrypi/linux, although it looks like it may now have moved up a subversion - see https://github.com/raspberrypi/linux/blob/rpi-3.2.27/Makefile

    I'll have a look at your kernel (cross) compiling guide drew, and try that. I think part of the problem is that my slackware distribution was using the 3.1.9 kernel, but still had 2.6.38.4 source present as well. (in /usr/src). I used david (spencer's) kernel+installer from http://www.daves-collective.co.uk/raspi/images/raspi-slack-installer_01Aug12.img.xz

     

    since this post slackware 14.0 (and armedslack 14.0 ) has come out. this updates the source framework to 3.4.11

    hopefully dave will update his kernel installer/package for slackware from the 3.1.9 version to a 3.2.x or higher, as I belive that is required to add the rtc device to the kernel using the method posted http://www.element14.com/community/groups/raspberry-pi/blog/2012/07/19/what-time-is-it-adding-a-rtc-to-the-raspberry-pi-via-i2c 

    I am looking forward to testing the little module I made to see if it works!

  • 8. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    I've just updated to the 3.6.1 kernel,(with slackware 14.0) and have been able to compile the rtc-ds1703 kernel module.

    I can install it with modprobe, but don't know how to tell the module that the device is at 0x6f on the i2c-0 port (ie. mcp79410) instead of 0x68 (ds1307) .

    i have /dev/i2c-0 and /dev/i2c-1 and if i do a i2cdetect 0 -y it shows the device at 0x6f

    i have tried

    echo mcp7941x 0x6f > /sys/class/i2c-adapter/i2c-0/new_device

    but I just get "no such file or directory" which is not a suprise as /sys/class/i2c-adapter does not exist. /sys/class/i2c-dev does, but substituting (ie using echo mcp7941x 0x6f > /sys/class/i2c-dev/i2c-0/new_device  ) still complains with error

    -bash /sys/class/i2c-dev/i2c-0/new_device: No such file or directory

  • 9. Re: has anyone got a linux kernel driver for mcp79410 rtc

    modprobe rtc-ds1307

    echo mcp7941x 0x6f > /sys/bus/i2c/devices/i2c-0/new_device

     

    works for me on a slightly older kernel.. I've not checked 3.6.1 (why can't they stick to mainline ?) but if /sys/class/i2c-adapter doesn't exist, it's possible you're missing some other stuff. Do you have i2c-dev compiled in or loaded as a module ?

     

    Based on my older kernel it appears you'd want to use /sys/class/i2c-dev/i2c-0/device/new_device if you use that path.

     

    Have you read Documentation/i2c/instantiating-devices in the kernel tree ?   There's a couple of ways in there to get the device configured, my personal choice is to use platform data (i.e. method 1) which also lets you configure the kernel to automatically set the clock on boot.

  • 10. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    you hit the nail on the head, thanks. I just had a thought last night to look for "new_device" anywhere in the /sys/class/i2c-dev path and came up with the same location.

    so, once the rtc module is loaded with modprobe i2c:mcp7941x  (or insmod rtc_ds1307   )

     

    echo mcp7941x 0x6f > /sys/class/i2c-dev/i2c-0/device/new_device

     

    creates the /dev/rtc0 device, and after a bit of prodding*, hwclock -w set the time on the rtc, and hwclock -s can now be used in /etc/rc.d/rc.local to set the system time from the rtc (and hwclock -r shows the rtc time and date)

    *(to explain the prodding. initially after running above, I got ioctl errors when running hwclock. I then did

    cat /dev/rtc0

      (and ctl-c ), and that seemed to fix the problem. I could then set the rtc with hwclock -w   .the proper behaviour was preserved after a cold restart of the raspberrypi  )

     

    Info for other armedslack raspberrypi users

    you need to recompile the kernel and add rtc support. specifically

    CONFIG_RTC_LIB=y

    CONFIG_RTC_CLASS=y

    CONFIG_RTC_HCTOSYS=y

    CONFIG_RTC_HCTOSYS_DEVICE="rtc0"

    CONFIG_RTC_INTF_SYSFS=y

    CONFIG_RTC_INTF_PROC=y

    CONFIG_RTC_INTF_DEV=y

     

    CONFIG_RTC_DRV_DS1307=m

    I used the the kernel, modules and kernel source from http://ponce.cc/slackware/slackwarearm-14.0/raspi-slackbuild-3.6.y/  (thanks to ponce) as a starting point.

     

    then compile and install i2c-tools from slackbuilds.org (sbopkg). this gives the i2c-dev module, so you can "talk" to i2c bus and provides the i2cdetect and i2cdump and similar tools for

    probing the i2c busses.

     

    my /etc/rc.d/rc.local includes the following lines at the bottom

    modprobe i2c-dev

    modprobe i2c:mcp7941x

    echo mcp7941x 0x6f > /sys/class/i2c-dev/i2c-0/device/new_device

    hwclock -s

    Now I know my rtc gadget works, I'll have to find somewhere to post the circuit layouts for folks so they can make their own. The mcp79410 is quite a bit cheaper than the ds1307 and happens to run at 3.3v so you don't need any 5v-3.3v 2way buffering on the i2c bus. It also has battery backup function.

     

    thanks again for your assistance selsinork et-al

  • 11. Re: has anyone got a linux kernel driver for mcp79410 rtc

    creates the /dev/rtc0 device, and after a bit of prodding*, hwclock -w set the time on the rtc, and hwclock -s can now be used in /etc/rc.d/rc.local to set the system time from the rtc (and hwclock -r shows the rtc time and date)

    *(to explain the prodding. initially after running above, I got ioctl errors when running hwclock. I then did

    There's a bit in one of the registers needs setting to start the oscillator running, probably you'll have problems until the oscilaltor is running and the initial date/time is set. Theoretically you only need to do it once - or at least until you loose both main power and battery.

     

    I'd imagine you could do it properly with i2cset having read the datasheet to find the right bit.

  • 12. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    i've looked at the datasheet, and according to it, one should set the highest bit (bit7 if you start at bit0) to 1 to start the oscillator. because the ports are not symetrical (you read from control address 0x6f for the rtc registers, but write to 0x6e) you have to do things a little more manually. -update: following tests, it would appear that dispite what the datasheet says, you can only write using the same control address as the read address.

    get byte from location 0 and i2c0 location 0x6f.

    HEXVAL=`i2cdump -f -r 0-0 -y 0 0x6f b|tail -n1|awk '{printf("%#x\n",$2)}'`  

    then or the value with 0x80 to turn on the oscillator bit

     

    NEWHEX=`echo $HEXVAL|awk '{printf("%#x\n", or($1,0x80)) }'`

     

    then write the new value back to the rtc . note: the rtc driver must be unloaded to sucessfully run i2cset on the rtc. even with -f it will not write unless you   rmmod rtc_ds1307

    i2cset -f -y 0 0x6f 0 $NEWHEX

     

    you can now reload the driver  modprobe i2c:mcp7941x

    and if it hasn't been configured, echo mcp7941x 0x6f > /sys/class/i2c-dev/i2c-0/device/new_device

  • 13. Re: has anyone got a linux kernel driver for mcp79410 rtc
    timsoft

    below is a sample script I wrote which does the turning on/off of the oscillator on the mcp79410 rtc usual disclaimer. it works for me. try it at your own peril. i release it public domain. it probably works on all sorts of distributions, but is only tested on slackware 14.0 with custom 3.6.1 kernel with rtc support compiled in and rtc-ds1307 compiled as a module. (and it requires i2c-tools to be installed, and i2c-dev module to be loaded.)

     

    #!/bin/sh
    #this must be run as root.
    if [ "`id -u`" != 0 ]; then
      echo "this script must be run with root priviledges to access the hardware"
      exit 1
    fi
    #and i2c-dev needs to be installed
    if [ ! -e /usr/sbin/i2cdetect ]; then
      echo "you must install i2c-tools package to be able to configure"
      echo "devices on the i2c buses."
      if [ -e /etc/slackware-version ]; then
        echo "you can build a package using the slackbuild from www.slackbuilds.org"
        echo "or by using sbopkg, or your method of choice"
      fi
      exit 1
    fi
    FORCEFLAG=""
    if [ -e /dev/rtc0 ]; then
      echo "warning. the kernel has already got the rtc driver loaded"
      echo "you will need to unload it with   rmmod rtc_ds1307"
      echo "then reload it with               modprobe i2c:mcp7941x"
      echo "when you have set the oscillator."
      exit 1
    fi
    #make sure we have a mcp7941x rtc present on the i2c bus
    RTC_READ_PORT="0x6f"
    #RTC_WRITE_PORT="0x6e"
    #write port doesn't seem to work but you can write to the read port!
    I2CBUS=""
    if [ -e /dev/i2c-0 ]; then
      #we have an i2c-0 bus so lets see if the rtc is here
      ISRTC_HERE=`i2cdetect -y 0|grep "60:"|cut -c50|awk '($1!="--") {print "YES"}'`
      if [ "$ISRTC_HERE" = "YES" ]; then
        I2CBUS=0
      fi
    fi
    if [ "$I2CBUS" = "" ]&&[ -e /dev/i2c-1 ]; then
      #clock wasn't on i2c-0 but we have an i2c-1 so lets check it
      ISRTC_HERE=`i2cdetect -y 1|grep "60:"|cut -c50|awk '($1!="--") {print "YES"}'`
      if [ "$ISRTC_HERE" = "YES" ]; then
        I2CBUS=1
      fi
    fi
    if [ "$I2CBUS" = "" ]; then
      echo "no mcp7941x rtc detected."
      exit 1
    fi
    echo i2cbus is $I2CBUS
    #now get the current seconds (bcd with oscillator control flag in top bit)
    #and switch the oscillator bit on by or'ing the output with 0x80
    HEXBYTE=`i2cdump $FORCEFLAG -r 0-0 -y $I2CBUS $RTC_READ_PORT b |tail -n1|awk '{print "0x" $2 }'`
    echo "hexbyte is $HEXBYTE which is $(($HEXBYTE))"
    
    if [ `echo $(($HEXBYTE))` -lt 128 ]; then
      echo "oscillator is not running"
      NEWHEXBYTE=`echo $(($HEXBYTE))|awk '{oscon=or($1, 128);printf("%#x\n", oscon) }'`
      echo "new hexbyte is $NEWHEXBYTE"
      #now lets write the new value to the writable address for the rtc
      #the writable address is the same as the read one, but with the 0 bit cleared
      i2cset $FORCEFAG -y $I2CBUS $RTC_READ_PORT 0 $NEWHEXBYTE b
      echo "started the oscillator"
    else
      echo "oscillator is already running"
      echo "do you want to stop the oscillator y/n:"
      read i
      if [ "$i" = "y" ]||[ "$i" = "Y" ]; then
        #remove top bit from byte
        NEWHEXBYTE=`echo $((HEXBYTE))|awk '{oscoff=and($1,127);printf("%#x\n",oscoff) }'`
        echo "new hexbyte is $NEWHEXBYTE"
        i2cset $FORCEFLAG -y $I2CBUS $RTC_READ_PORT 0 $NEWHEXBYTE b
        echo "stopped the oscillator"
      fi
    fi
    

    have fun :-)