diff --git a/sys/arch/arm/iomd/files.iomd b/sys/arch/arm/iomd/files.iomd index 0cd90630d9fe..1abfdc3d9c5e 100644 --- a/sys/arch/arm/iomd/files.iomd +++ b/sys/arch/arm/iomd/files.iomd @@ -1,10 +1,10 @@ -# $NetBSD: files.iomd,v 1.2 2002/06/16 13:20:14 bjh21 Exp $ +# $NetBSD: files.iomd,v 1.3 2003/10/06 16:11:19 thorpej Exp $ # # IOMD-specific configuration data # # IOMD device -# parent to kbd, qms, opms, iic +# parent to kbd, qms, opms, iomdiic # also provides irq and timer services device iomd {} attach iomd at mainbus @@ -16,23 +16,10 @@ file arch/arm/iomd/iomd_irqhandler.c iomd file arch/arm/iomd/iomd_fiq.S iomd file arch/arm/iomd/iomd_dma.c iomd -# IIC device -device iic { addr = -1 } -file arch/arm/iomd/iic.c iic needs-flag - -attach iic at iomd with iic_iomd -file arch/arm/iomd/iic_iomd.c iic_iomd -file arch/arm/iomd/iomd_iic.S iic_iomd - -# IIC based RTC -define todservice {} -device rtc : todservice -attach rtc at iic -file arch/arm/iomd/rtc.c rtc needs-flag - -device todclock -attach todclock at todservice -file arch/arm/iomd/todclock.c todclock needs-count +# I^2C bus (bit-banged through IOMD control register) +device iomdiic: i2cbus, i2c_bitbang +attach iomdiic at iomd +file arch/arm/iomd/iomdiic.c iomdiic # IOMD mouse devices # clock device diff --git a/sys/arch/arm/iomd/iic.c b/sys/arch/arm/iomd/iic.c deleted file mode 100644 index a4a67009c64b..000000000000 --- a/sys/arch/arm/iomd/iic.c +++ /dev/null @@ -1,343 +0,0 @@ -/* $NetBSD: iic.c,v 1.8 2003/07/15 00:24:44 lukem Exp $ */ - -/* - * Copyright (c) 1994-1996 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * iic.c - * - * Routines to communicate with IIC devices - * - * Created : 13/10/94 - * - * Based of kate/display/iiccontrol.c - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: iic.c,v 1.8 2003/07/15 00:24:44 lukem Exp $"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include "locators.h" - -/* Local function prototypes */ - -static int iic_getack __P((void)); -static void iic_write_bit __P((int bit)); -static int iic_write_byte __P((u_char value)); -static u_char iic_read_byte __P((void)); -static void iic_start_bit __P((void)); -static void iic_stop_bit __P((void)); - -static int iicprint __P((void *aux, const char *name)); - -/* External functions that do the bit twiddling */ -extern int iic_getstate __P((void)); -extern void iic_set_state_and_ack __P((int, int)); -extern void iic_set_state __P((int, int)); -extern void iic_delay __P((int)); - -extern struct cfdriver iic_cd; - -dev_type_open(iicopen); -dev_type_close(iicclose); - -const struct cdevsw iic_cdevsw = { - iicopen, iicclose, noread, nowrite, noioctl, - nostop, notty, nopoll, nommap, nokqfilter, -}; - -/* - * Main entry to IIC driver. - */ - -int -iic_control(address, buffer, count) - u_char address; - u_char *buffer; - int count; -{ - int loop; - - /* Send the start bit */ - - iic_start_bit(); - - /* Send the address */ - - if (!iic_write_byte(address)) { - iic_stop_bit(); - return(-1); - } - - /* Read or write the data as required */ - - if ((address & 1) == 0) { - /* Write bytes */ - for (loop = 0; loop < count; ++loop) { - if (!iic_write_byte(buffer[loop])) { - iic_stop_bit(); - return(-1); - } - } - } - else { - /* Read bytes */ - for (loop = 0; loop < count; ++loop) { - buffer[loop] = iic_read_byte(); - - /* Send final acknowledge */ - - if (loop == (count - 1)) - iic_write_bit(1); - else - iic_write_bit(0); - } - } - - /* Send stop bit */ - - iic_stop_bit(); - - return(0); -} - - -static int -iic_getack() -{ - u_int oldirqstate; - int ack; - - iic_set_state(1, 0); - oldirqstate = disable_interrupts(I32_bit); - iic_set_state_and_ack(1, 1); - ack = iic_getstate(); - iic_set_state(1, 0); - restore_interrupts(oldirqstate); - - return((ack & 1) == 0); -} - - -static void -iic_write_bit(bit) - int bit; -{ - u_int oldirqstate; - - iic_set_state(bit, 0); - oldirqstate = disable_interrupts(I32_bit); - iic_set_state_and_ack(bit, 1); - iic_set_state(bit, 0); - restore_interrupts(oldirqstate); -} - - -static int -iic_write_byte(value) - u_char value; -{ - int loop; - int bit; - - for (loop = 0x80; loop != 0; loop = loop >> 1) { - bit = ((value & loop) != 0); - iic_write_bit(bit); - } - - return(iic_getack()); -} - - -static u_char -iic_read_byte() -{ - int loop; - u_char byte; - u_int oldirqstate; - - iic_set_state(1,0); - - byte = 0; - - for (loop = 0; loop < 8; ++loop) { - oldirqstate = disable_interrupts(I32_bit); - iic_set_state_and_ack(1, 1); - byte = (byte << 1) + (iic_getstate() & 1); - iic_set_state(1, 0); - restore_interrupts(oldirqstate); - } - - return(byte); -} - - -static void -iic_start_bit() -{ - iic_set_state(1, 1); - iic_set_state(0, 1); - iic_delay(10); - iic_set_state(0, 0); -} - - -static void -iic_stop_bit() -{ - iic_set_state(0, 1); - iic_set_state(1, 1); -} - -/* driver structures */ - -/* - * int iicprint(void *aux, const char *name) - * - * print function for child device configuration - */ - -static int -iicprint(aux, name) - void *aux; - const char *name; -{ - struct iicbus_attach_args *iba = aux; - - if (!name) { - if (iba->ib_addr) - aprint_normal(" addr 0x%02x", iba->ib_addr); - } - - /* XXXX print flags */ - return (QUIET); -} - -/* - * iic search function - * - * search for devices that are children of the iic device - * fill out the attach arguments and call the probe and - * attach function (as required). - * - * Note: since the offsets of the devices need to be specified in the - * config file we ignore the FSTAT_STAR. - */ - -int -iicsearch(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct iic_softc *sc = (struct iic_softc *)parent; - struct iicbus_attach_args iba; - int tryagain; - - do { - iba.ib_iic_softc = sc; - iba.ib_addr = cf->cf_loc[IICCF_ADDR]; - iba.ib_aux = NULL; - - tryagain = 0; - if (config_match(parent, cf, &iba) > 0) { - config_attach(parent, cf, &iba, iicprint); -/* tryagain = (cf->cf_fstate == FSTATE_STAR);*/ - } - } while (tryagain); - - return (0); -} - -/* - * Q: Do we really need a device interface ? - */ - -int -iicopen(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - struct iic_softc *sc; - int unit = minor(dev); - - if (unit >= iic_cd.cd_ndevs) - return(ENXIO); - - sc = iic_cd.cd_devs[unit]; - - if (!sc) return(ENXIO); - - if (sc->sc_flags & IIC_OPEN) return(EBUSY); - - sc->sc_flags |= IIC_OPEN; - - return(0); -} - - -int -iicclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - int unit = minor(dev); - struct iic_softc *sc = iic_cd.cd_devs[unit]; - - sc->sc_flags &= ~IIC_OPEN; - - return(0); -} - -/* End of iic.c */ diff --git a/sys/arch/arm/iomd/iic.h b/sys/arch/arm/iomd/iic.h deleted file mode 100644 index a55a5aecc405..000000000000 --- a/sys/arch/arm/iomd/iic.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $NetBSD: iic.h,v 1.1 2001/10/05 22:27:40 reinoud Exp $ */ - -/* - * Copyright (c) 1996 Mark Brinicombe. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Brini. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * iic.h - * - * header file for IIC - * - * Created : 15/04/96 - */ - -/* - * IIC bus driver attach arguments - */ - -#ifdef _KERNEL - -struct iicbus_attach_args { - int ib_addr; /* i/o address */ - void *ib_aux; /* driver specific */ - void *ib_iic_softc; /* softc of iic parent */ -}; - -#define iic_bitdelay 10 - -#define IIC_WRITE 0x00 -#define IIC_READ 0x01 - -/* Prototypes for assembly functions */ - -void iic_set_state __P((int data, int clock)); -void iic_set_state_and_ack __P((int data, int clock)); -void iic_delay __P((int delay)); - -/* Prototype for kernel interface to IIC bus */ - -int iic_control __P((u_char address, u_char *buffer, int count)); - -#endif /* _KERNEL */ - -/* End of iic.h */ diff --git a/sys/arch/arm/iomd/iic_iomd.c b/sys/arch/arm/iomd/iic_iomd.c deleted file mode 100644 index 62af9513c9f4..000000000000 --- a/sys/arch/arm/iomd/iic_iomd.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $NetBSD: iic_iomd.c,v 1.6 2003/07/15 00:24:44 lukem Exp $ */ - -/* - * Copyright (c) 1994-1996 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * iic.c - * - * Routines to communicate with IIC devices - * - * Created : 13/10/94 - * - * Based of kate/display/iiccontrol.c - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: iic_iomd.c,v 1.6 2003/07/15 00:24:44 lukem Exp $"); - -#include -#include -#include -#include - -#include -#include -#include -#include - -static int iic_iomd_probe __P((struct device *, struct cfdata *, void *)); -static void iic_iomd_attach __P((struct device *, struct device *, void *)); - -CFATTACH_DECL(iic_iomd, sizeof(struct iic_softc), - iic_iomd_probe, iic_iomd_attach, NULL, NULL); - -/* - * iic device probe function - * - * just validate the attach args - */ - -static int -iic_iomd_probe(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct iic_attach_args *ia = aux; - - if (strcmp(ia->ia_name, "iic") == 0) - return(1); - - return(0); -} - -/* - * iic device attach function - * - * Initialise the softc structure and do a search for children - */ - -static void -iic_iomd_attach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; -{ - struct iic_softc *sc = (void *)self; - struct iic_attach_args *ia = aux; - - sc->sc_iot = ia->ia_iot; - sc->sc_ioh = ia->ia_ioh; - - printf("\n"); - - config_search(iicsearch, self, NULL); -} - -/* End of iic_iomd.c */ diff --git a/sys/arch/arm/iomd/iomd_clock.c b/sys/arch/arm/iomd/iomd_clock.c index fd95607cb8a2..f3ccc6b9e29c 100644 --- a/sys/arch/arm/iomd/iomd_clock.c +++ b/sys/arch/arm/iomd/iomd_clock.c @@ -1,4 +1,4 @@ -/* $NetBSD: iomd_clock.c,v 1.11 2003/07/14 15:17:23 lukem Exp $ */ +/* $NetBSD: iomd_clock.c,v 1.12 2003/10/06 16:11:19 thorpej Exp $ */ /* * Copyright (c) 1994-1997 Mark Brinicombe. @@ -54,6 +54,8 @@ __KERNEL_RCSID(0, "$NetBSD"); #include #include +#include + #include #include @@ -359,4 +361,91 @@ delay(n) } } +todr_chip_handle_t todr_handle; + +/* + * todr_attach: + * + * Set the specified time-of-day register as the system real-time clock. + */ +void +todr_attach(todr_chip_handle_t todr) +{ + + if (todr_handle) + panic("todr_attach: rtc already configured"); + todr_handle = todr; +} + +/* + * inittodr: + * + * Initialize time from the time-of-day register. + */ +#define MINYEAR 2003 /* minimum plausible year */ +void +inittodr(time_t base) +{ + time_t deltat; + int badbase; + + if (base < (MINYEAR - 1970) * SECYR) { + printf("WARNING: preposterous time in file system"); + /* read the system clock anyway */ + base = (MINYEAR - 1970) * SECYR; + badbase = 1; + } else + badbase = 0; + + if (todr_handle == NULL || + todr_gettime(todr_handle, (struct timeval *)&time) != 0 || + time.tv_sec == 0) { + /* + * Believe the time in the file system for lack of + * anything better, resetting the TODR. + */ + time.tv_sec = base; + time.tv_usec = 0; + if (todr_handle != NULL && !badbase) { + printf("WARNING: preposterous clock chip time\n"); + resettodr(); + } + goto bad; + } + + if (!badbase) { + /* + * See if we tained/lost two or more days; if + * so, assume something is amiss. + */ + deltat = time.tv_sec - base; + if (deltat < 0) + deltat = -deltat; + if (deltat < 2 * SECDAY) + return; /* all is well */ + printf("WARNING: clock %s %ld days\n", + time.tv_sec < base ? "lost" : "gained", + (long)deltat / SECDAY); + } + bad: + printf("WARNING: CHECK AND RESET THE DATE!\n"); +} + +/* + * resettodr: + * + * Reset the time-of-day register with the current time. + */ +void +resettodr(void) +{ + + if (time.tv_sec == 0) + return; + + if (todr_handle != NULL && + todr_settime(todr_handle, (struct timeval *)&time) != 0) + printf("resettodr: failed to set time\n"); +} + /* End of iomd_clock.c */ diff --git a/sys/arch/arm/iomd/iomd_iic.S b/sys/arch/arm/iomd/iomd_iic.S deleted file mode 100644 index 5f4024cc63c1..000000000000 --- a/sys/arch/arm/iomd/iomd_iic.S +++ /dev/null @@ -1,247 +0,0 @@ -/* $NetBSD: iomd_iic.S,v 1.3 2001/11/23 16:53:07 thorpej Exp $ */ - -/* - * Copyright (c) 1994-1996 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * iic.s - * - * Low level routines to with IIC devices - * - * Created : 13/10/94 - * - * Based of kate/display/iic.s - */ - -#include "assym.h" /* for __PROG32 */ - -#include -#include -#include - -#define IIC_BITDELAY 10 - -Liomd_base: - .word _C_LABEL(iomd_base) - -ENTRY(iic_set_state) - /* - * Parameters - * r0 - IIC data bit - * r1 - IIC clock bit - */ - - /* Store temporary register */ -/* stmfd sp!, {r4}*/ - - /* - * Mask the data and clock bits - * Since these routines are only called from iiccontrol.c this is not - * really needed - */ - and r0, r0, #0x00000001 - and r1, r1, #0x00000001 - - /* Get address of IOMD control register */ - - ldr r2, Liomd_base - ldr r2, [r2] - - /* Get the current CPSR */ -/* mrs r4, cpsr_all - orr r3, r4, #(I32_bit | F32_bit) - msr cpsr_all, r3 -*/ - - IRQdisable - - /* Get current value of control register */ - - ldrb r3, [r2, #(IOMD_IOCR << 2)] - - /* Preserve non-IIC bits */ - - bic r3, r3, #0x00000003 -/* orr r3, r3, #0x000000c0*/ - - /* Set the IIC clock and data bits */ - - orr r3, r3, r0 - orr r3, r3, r1, lsl #1 - - /* Store the new value of control register */ - - strb r3, [r2, #(IOMD_IOCR << 2)] - - /* Restore CPSR state */ -/* msr cpsr_all, r4 */ - - IRQenable - - /* Restore temporary register */ -/* ldmfd sp!, {r4} */ - - /* Pause a bit */ - - mov r0, #(IIC_BITDELAY) - - /* Exit via iic_delay routine */ - b _C_LABEL(iic_delay) - -ENTRY(iic_set_state_and_ack) - /* - * Parameters - * r0 - IIC data bit - * r1 - IIC clock bit - */ - - /* Store temporary register */ -/* stmfd sp!, {r4} */ - - /* - * Mask the data and clock bits - * Since these routines are only called from iiccontrol.c this is not - * really needed - */ - - and r0, r0, #0x00000001 - and r1, r1, #0x00000001 - - /* Get address of IOMD control register */ - - ldr r2, Liomd_base - ldr r2, [r2] - - /* Get the current CPSR */ -/* mrs r4, cpsr_all - orr r3, r4, #(I32_bit | F32_bit) - msr cpsr_all, r3 -*/ - IRQdisable - - /* Get current value of control register */ - - ldrb r3, [r2, #(IOMD_IOCR << 2)] - - /* Preserve non-IIC bits */ - - bic r3, r3, #0x00000003 -/* orr r3, r3, #0x000000c0*/ - - /* Set the IIC clock and data bits */ - - orr r3, r3, r0 - orr r3, r3, r1, lsl #1 - - /* Store the new value of control register */ - - strb r3, [r2, #(IOMD_IOCR << 2)] - -Liic_set_state_and_ack_loop: - ldrb r3, [r2, #(IOMD_IOCR << 2)] - tst r3, #0x00000002 - beq Liic_set_state_and_ack_loop - - /* Restore CPSR state */ -/* msr cpsr_all, r4 */ - - IRQenable - - /* Restore temporary register */ -/* ldmfd sp!, {r4} */ - - /* Pause a bit */ - - mov r0, #(IIC_BITDELAY) - - /* Exit via iic_delay routine */ - b _C_LABEL(iic_delay) - - -ENTRY(iic_delay) - /* - * Parameters - * r0 - time to wait - */ - - /* Load address of IOMD */ - - ldr r2, Liomd_base - ldr r2, [r2] - - /* Latch current value of timer 1 */ - - strb r2, [r2, #(IOMD_T0LATCH << 2)] - - /* Get the latched value */ - - ldrb r1, [r2, #(IOMD_T0LOW << 2)] - - /* Loop until timer reaches end value */ - -Liic_delay_loop: - - /* Latch the current value of timer1 */ - - strb r2, [r2, #(IOMD_T0LATCH << 2)] - - /* Get the latched value */ - - ldrb r3, [r2, #(IOMD_T0LOW << 2)] - - /* Loop until timer reached expected value */ - - teq r3, r1 - movne r1, r3 - beq Liic_delay_loop - - subs r0, r0, #0x00000001 - bne Liic_delay_loop - - /* Exit */ - mov pc, lr - -ENTRY(iic_getstate) - /* Load address of IOMD */ - - ldr r2, Liomd_base - ldr r2, [r2] - - /* Read IOCR */ - - ldrb r0, [r2, #(IOMD_IOCR << 2)] - mov pc, lr - -/* End of iomd_iic.S */ diff --git a/sys/arch/arm/iomd/iomdiic.c b/sys/arch/arm/iomd/iomdiic.c new file mode 100644 index 000000000000..c24ccdd40187 --- /dev/null +++ b/sys/arch/arm/iomd/iomdiic.c @@ -0,0 +1,232 @@ +/* $NetBSD: iomdiic.c,v 1.1 2003/10/06 16:11:19 thorpej Exp $ */ + +/* + * Copyright (c) 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +struct iomdiic_softc { + struct device sc_dev; + bus_space_tag_t sc_st; + bus_space_handle_t sc_sh; + + struct i2c_controller sc_i2c; + struct lock sc_buslock; + + /* + * The SDA pin is open-drain, so we make it an input by + * writing a 1 to it. + */ + uint8_t sc_iomd_iocr; +}; + +static int iomdiic_acquire_bus(void *, int); +static void iomdiic_release_bus(void *, int); + +static int iomdiic_send_start(void *, int); +static int iomdiic_send_stop(void *, int); +static int iomdiic_initiate_xfer(void *, i2c_addr_t, int); +static int iomdiic_read_byte(void *, uint8_t *, int); +static int iomdiic_write_byte(void *, uint8_t, int); + +#define IOMDIIC_READ *(__volatile uint8_t *)(IOMD_ADDRESS(IOMD_IOCR)) +#define IOMDIIC_WRITE(x) *(__volatile uint8_t *)(IOMD_ADDRESS(IOMD_IOCR)) = (x) + +#define IOMD_IOCR_SDA 0x01 +#define IOMD_IOCR_SCL 0x02 + +static void +iomdiic_bb_set_bits(void *cookie, uint32_t bits) +{ + struct iomdiic_softc *sc = cookie; + + IOMDIIC_WRITE((IOMDIIC_READ & ~(IOMD_IOCR_SDA|IOMD_IOCR_SCL)) | + sc->sc_iomd_iocr | bits); +} + +static void +iomdiic_bb_set_dir(void *cookie, uint32_t bits) +{ + struct iomdiic_softc *sc = cookie; + + sc->sc_iomd_iocr = bits; +} + +static uint32_t +iomdiic_bb_read_bits(void *cookie) +{ + + return (IOMDIIC_READ); +} + +static const struct i2c_bitbang_ops iomdiic_bbops = { + iomdiic_bb_set_bits, + iomdiic_bb_set_dir, + iomdiic_bb_read_bits, + { + IOMD_IOCR_SDA, /* SDA */ + IOMD_IOCR_SCL, /* SCL */ + 0, /* SDA is output */ + IOMD_IOCR_SDA, /* SDA is input */ + } +}; + +static int +iomdiic_match(struct device *parent, struct cfdata *cf, void *aux) +{ + + return (1); +} + +static void +iomdiic_attach(struct device *parent, struct device *self, void *aux) +{ + struct iomdiic_softc *sc = (void *) self; + struct i2cbus_attach_args iba; + + printf("\n"); + + lockinit(&sc->sc_buslock, PRIBIO|PCATCH, "iomdiiclk", 0, 0); + + sc->sc_i2c.ic_cookie = sc; + sc->sc_i2c.ic_acquire_bus = iomdiic_acquire_bus; + sc->sc_i2c.ic_release_bus = iomdiic_release_bus; + sc->sc_i2c.ic_send_start = iomdiic_send_start; + sc->sc_i2c.ic_send_stop = iomdiic_send_stop; + sc->sc_i2c.ic_initiate_xfer = iomdiic_initiate_xfer; + sc->sc_i2c.ic_read_byte = iomdiic_read_byte; + sc->sc_i2c.ic_write_byte = iomdiic_write_byte; + + iba.iba_name = "iic"; + iba.iba_tag = &sc->sc_i2c; + (void) config_found(&sc->sc_dev, &iba, iicbus_print); +} + +CFATTACH_DECL(iomdiic, sizeof(struct iomdiic_softc), + iomdiic_match, iomdiic_attach, NULL, NULL); + +i2c_tag_t +iomdiic_bootstrap_cookie(void) +{ + static struct iomdiic_softc sc; + + /* XXX Yuck. */ + strcpy(sc.sc_dev.dv_xname, "iomdiicboot"); + + sc.sc_i2c.ic_cookie = ≻ + sc.sc_i2c.ic_acquire_bus = iomdiic_acquire_bus; + sc.sc_i2c.ic_release_bus = iomdiic_release_bus; + sc.sc_i2c.ic_send_start = iomdiic_send_start; + sc.sc_i2c.ic_send_stop = iomdiic_send_stop; + sc.sc_i2c.ic_initiate_xfer = iomdiic_initiate_xfer; + sc.sc_i2c.ic_read_byte = iomdiic_read_byte; + sc.sc_i2c.ic_write_byte = iomdiic_write_byte; + + return ((void *) &sc.sc_i2c); +} + +static int +iomdiic_acquire_bus(void *cookie, int flags) +{ + struct iomdiic_softc *sc = cookie; + + /* XXX What should we do for the polling case? */ + if (flags & I2C_F_POLL) + return (0); + + return (lockmgr(&sc->sc_buslock, LK_EXCLUSIVE, NULL)); +} + +static void +iomdiic_release_bus(void *cookie, int flags) +{ + struct iomdiic_softc *sc = cookie; + + /* XXX See above. */ + if (flags & I2C_F_POLL) + return; + + (void) lockmgr(&sc->sc_buslock, LK_RELEASE, NULL); +} + +static int +iomdiic_send_start(void *cookie, int flags) +{ + + return (i2c_bitbang_send_start(cookie, flags, &iomdiic_bbops)); +} + +static int +iomdiic_send_stop(void *cookie, int flags) +{ + + return (i2c_bitbang_send_stop(cookie, flags, &iomdiic_bbops)); +} + +static int +iomdiic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) +{ + + return (i2c_bitbang_initiate_xfer(cookie, addr, flags, &iomdiic_bbops)); +} + +static int +iomdiic_read_byte(void *cookie, uint8_t *bytep, int flags) +{ + + return (i2c_bitbang_read_byte(cookie, bytep, flags, &iomdiic_bbops)); +} + +static int +iomdiic_write_byte(void *cookie, uint8_t byte, int flags) +{ + + return (i2c_bitbang_write_byte(cookie, byte, flags, &iomdiic_bbops)); +} diff --git a/sys/arch/arm/iomd/iomdiicvar.h b/sys/arch/arm/iomd/iomdiicvar.h new file mode 100644 index 000000000000..106c707492a2 --- /dev/null +++ b/sys/arch/arm/iomd/iomdiicvar.h @@ -0,0 +1,44 @@ +/* $NetBSD: iomdiicvar.h,v 1.1 2003/10/06 16:11:19 thorpej Exp $ */ + +/* + * Copyright (c) 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_IOMD_IOMDIICVAR_H_ +#define _ARM_IOMD_IOMDIICVAR_H_ + +/* For use during bootstrap. */ +i2c_tag_t iomdiic_bootstrap_cookie(void); + +#endif /* _ARM_IOMD_IOMDIICVAR_H_ */ diff --git a/sys/arch/arm/iomd/rtc.c b/sys/arch/arm/iomd/rtc.c deleted file mode 100644 index 973bf8cb3de5..000000000000 --- a/sys/arch/arm/iomd/rtc.c +++ /dev/null @@ -1,491 +0,0 @@ -/* $NetBSD: rtc.c,v 1.11 2003/07/15 00:24:46 lukem Exp $ */ - -/* - * Copyright (c) 1994-1996 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Brini. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * rtc.c - * - * Routines to read and write the RTC and CMOS RAM - * - * Created : 13/10/94 - * Updated : 15/07/2000 DD - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.11 2003/07/15 00:24:46 lukem Exp $"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct rtc_softc { - struct device sc_dev; - int sc_flags; -#define RTC_BROKEN 1 -#define RTC_OPEN 2 -}; - -void rtcattach __P((struct device *parent, struct device *self, void *aux)); -int rtcmatch __P((struct device *parent, struct cfdata *cf, void *aux)); -int rtc_read __P((void *, rtc_t *)); -int rtc_write __P((void *, rtc_t *)); - -static __inline int hexdectodec __P((u_char)); -static __inline int dectohexdec __P((u_char)); -static int twodigits __P((char *, int)); - -/* Read a byte from CMOS RAM */ - -int -cmos_read(location) - int location; -{ - u_char buff; - -/* - * This commented code dates from when I was translating CMOS address - * from the RISCOS addresses. Now all addresses are specified as - * actual addresses in the CMOS RAM - */ - -/* - if (location > 0xF0) - return(-1); - - if (location < 0xC0) - buff = location + 0x40; - else - buff = location - 0xB0; -*/ - buff = location; - - if (iic_control(RTC_Write, &buff, 1)) - return(-1); - if (iic_control(RTC_Read, &buff, 1)) - return(-1); - - return(buff); -} - - -/* Write a byte to CMOS RAM */ - -int -cmos_write(location, value) - int location; - int value; -{ - u_char buff[2]; - int oldvalue, oldsum; - -/* - * This commented code dates from when I was translating CMOS address - * from the RISCOS addresses. Now all addresses are specified as - * actual addresses in the CMOS RAM - */ - -/* if (location > 0xF0) - return(-1); - - if (location < 0xC0) - buff = location + 0x40; - else - buff = location - 0xB0; -*/ - buff[0] = location; - buff[1] = value; - -/* Read the old CMOS location value and old checksum */ - oldvalue = cmos_read(location); - if (oldvalue<0) - return(-1); - oldsum = cmos_read(RTC_ADDR_CHECKSUM); - if (oldsum<0) - return(-1); - - if (iic_control(RTC_Write, buff, 2)) - return(-1); - -/* Now update the checksum. This code only modifies the value. It does */ -/* not recalculate it */ - - buff[0] = RTC_ADDR_CHECKSUM; - buff[1] = oldsum - oldvalue + value; - if (iic_control(RTC_Write, buff, 2)) - return(-1); - - return(0); -} - - -/* Hex to BCD and BCD to hex conversion routines */ - -static __inline int -hexdectodec(n) - u_char n; -{ - return(((n >> 4) & 0x0F) * 10 + (n & 0x0F)); -} - -static __inline int -dectohexdec(n) - u_char n; -{ - return(((n / 10) << 4) + (n % 10)); -} - - -/* Write the RTC data from an 8 byte buffer */ - -int -rtc_write(arg, rtc) - void *arg; - rtc_t *rtc; -{ - u_char buff[8]; - - buff[0] = 1; - - buff[1] = dectohexdec(rtc->rtc_centi); - buff[2] = dectohexdec(rtc->rtc_sec); - buff[3] = dectohexdec(rtc->rtc_min); - buff[4] = dectohexdec(rtc->rtc_hour) & 0x3f; - buff[5] = dectohexdec(rtc->rtc_day) | ((rtc->rtc_year & 3) << 6); - buff[6] = dectohexdec(rtc->rtc_mon); - - if (iic_control(RTC_Write, buff, 7)) - return(0); - - if (cmos_write(RTC_ADDR_YEAR, rtc->rtc_year)) - return(0); - if (cmos_write(RTC_ADDR_CENT, rtc->rtc_cen)) - return(0); - - return(1); -} - - -/* Read the RTC data into a 8 byte buffer */ - -int -rtc_read(arg, rtc) - void *arg; - rtc_t *rtc; -{ - u_char buff[8]; - int byte; - - buff[0] = 0; - - if (iic_control(RTC_Write, buff, 1)) - return(0); - - if (iic_control(RTC_Read, buff, 8)) - return(0); - - rtc->rtc_micro = 0; - rtc->rtc_centi = hexdectodec(buff[1] & 0xff); - rtc->rtc_sec = hexdectodec(buff[2] & 0x7f); - rtc->rtc_min = hexdectodec(buff[3] & 0x7f); - rtc->rtc_hour = hexdectodec(buff[4] & 0x3f); - - /* If in 12 hour mode need to look at the AM/PM flag */ - - if (buff[4] & 0x80) - rtc->rtc_hour += (buff[4] & 0x40) ? 12 : 0; - - rtc->rtc_day = hexdectodec(buff[5] & 0x3f); - rtc->rtc_mon = hexdectodec(buff[6] & 0x1f); - - byte = cmos_read(RTC_ADDR_YEAR); - if (byte == -1) - return(0); - rtc->rtc_year = byte; - - byte = cmos_read(RTC_ADDR_CENT); - if (byte == -1) - return(0); - rtc->rtc_cen = byte; - - return(1); -} - -/* device and attach structures */ - -CFATTACH_DECL(rtc, sizeof(struct rtc_softc), - rtcmatch, rtcattach, NULL, NULL); - -extern struct cfdriver rtc_cd; - -dev_type_open(rtcopen); -dev_type_close(rtcclose); -dev_type_read(rtcread); -dev_type_write(rtcwrite); - -const struct cdevsw rtc_cdevsw = { - rtcopen, rtcclose, rtcread, rtcwrite, noioctl, - nostop, notty, nopoll, nommap, nokqfilter, -}; - -/* - * rtcmatch() - * - * Validate the IIC address to make sure its an RTC we understand - */ - -int -rtcmatch(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct iicbus_attach_args *ib = aux; - - if ((ib->ib_addr & IIC_PCF8583_MASK) == IIC_PCF8583_ADDR) - return(1); - - return(0); -} - -/* - * rtcattach() - * - * Attach the rtc device - */ - -void -rtcattach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; -{ - struct rtc_softc *sc = (struct rtc_softc *)self; - struct iicbus_attach_args *ib = aux; - u_char buff[1]; - struct todclock_attach_args ta; - - sc->sc_flags |= RTC_BROKEN; - if ((ib->ib_addr & IIC_PCF8583_MASK) == IIC_PCF8583_ADDR) { - printf(": PCF8583"); - - /* Read RTC register 0 and report info found */ - - buff[0] = 0; - - if (iic_control(RTC_Write, buff, 1)) - return; - - if (iic_control(RTC_Read, buff, 1)) - return; - - printf(" clock base "); - switch (buff[0] & 0x30) { - case 0x00: - printf("32.768KHz"); - break; - case 0x10: - printf("50Hz"); - break; - case 0x20: - printf("event"); - break; - case 0x30: - printf("test mode"); - break; - } - - if (buff[0] & 0x80) - printf(" stopped"); - if (buff[0] & 0x04) - printf(" alarm enabled"); - sc->sc_flags &= ~RTC_BROKEN; - } - - printf("\n"); - - ta.ta_name = "todclock"; - ta.ta_rtc_arg = NULL; - ta.ta_rtc_write = rtc_write; - ta.ta_rtc_read = rtc_read; - ta.ta_flags = 0; - config_found(self, &ta, NULL); -} - - -int -rtcopen(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - struct rtc_softc *sc; - int unit = minor(dev); - - if (unit >= rtc_cd.cd_ndevs) - return(ENXIO); - - sc = rtc_cd.cd_devs[unit]; - - if (!sc) return(ENXIO); - - if (sc->sc_flags & RTC_BROKEN) return(ENXIO); - if (sc->sc_flags & RTC_OPEN) return(EBUSY); - - sc->sc_flags |= RTC_OPEN; - - return(0); -} - - -int -rtcclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - int unit = minor(dev); - struct rtc_softc *sc = rtc_cd.cd_devs[unit]; - - sc->sc_flags &= ~RTC_OPEN; - - return(0); -} - - -int -rtcread(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - rtc_t rtc; - int s; - char buffer[32]; - int length; - - s = splclock(); - if (rtc_read(NULL, &rtc) == 0) { - (void)splx(s); - return(ENXIO); - } - - (void)splx(s); - - sprintf(buffer, "%02d:%02d:%02d.%02d%02d %02d/%02d/%02d%02d\n", - rtc.rtc_hour, rtc.rtc_min, rtc.rtc_sec, rtc.rtc_centi, - rtc.rtc_micro, rtc.rtc_day, rtc.rtc_mon, rtc.rtc_cen, - rtc.rtc_year); - - if (uio->uio_offset > strlen(buffer)) - return 0; - - length = strlen(buffer) - uio->uio_offset; - if (length > uio->uio_resid) - length = uio->uio_resid; - - return(uiomove((caddr_t)buffer, length, uio)); -} - - -static int -twodigits(buffer, pos) - char *buffer; - int pos; -{ - int result = 0; - - if (buffer[pos] >= '0' && buffer[pos] <= '9') - result = (buffer[pos] - '0') * 10; - if (buffer[pos+1] >= '0' && buffer[pos+1] <= '9') - result += (buffer[pos+1] - '0'); - return(result); -} - -int -rtcwrite(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - rtc_t rtc; - int s; - char buffer[25]; - int length; - int error; - - /* - * We require atomic updates! - */ - length = uio->uio_resid; - if (uio->uio_offset || (length != sizeof(buffer) - && length != sizeof(buffer - 1))) - return(EINVAL); - - if ((error = uiomove((caddr_t)buffer, sizeof(buffer), uio))) - return(error); - - if (length == sizeof(buffer) && buffer[sizeof(buffer) - 1] != '\n') - return(EINVAL); - - printf("rtcwrite: %s\n", buffer); - - rtc.rtc_micro = 0; - rtc.rtc_centi = twodigits(buffer, 9); - rtc.rtc_sec = twodigits(buffer, 6); - rtc.rtc_min = twodigits(buffer, 3); - rtc.rtc_hour = twodigits(buffer, 0); - rtc.rtc_day = twodigits(buffer, 14); - rtc.rtc_mon = twodigits(buffer, 17); - rtc.rtc_year = twodigits(buffer, 22); - rtc.rtc_cen = twodigits(buffer, 20); - - s = splclock(); - rtc_write(NULL, &rtc); - (void)splx(s); - - return(0); -} - -/* End of rtc.c */ diff --git a/sys/arch/arm/iomd/todclock.c b/sys/arch/arm/iomd/todclock.c deleted file mode 100644 index 8a4141782145..000000000000 --- a/sys/arch/arm/iomd/todclock.c +++ /dev/null @@ -1,333 +0,0 @@ -/* $NetBSD: todclock.c,v 1.7 2002/10/02 15:45:13 thorpej Exp $ */ - -/* - * Copyright (c) 1994-1997 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RiscBSD kernel project - * - * clock.c - * - * Timer related machine specific code - * - * Created : 29/09/94 - */ - -/* Include header files */ - -#include - -__KERNEL_RCSID(0, "$NetBSD: todclock.c,v 1.7 2002/10/02 15:45:13 thorpej Exp $"); - -#include -#include -#include -#include - -#include -#include - -#include "todclock.h" - -#if NTODCLOCK > 1 -#error "Can only have 1 todclock device" -#endif - -/* - * softc structure for the todclock device - */ - -struct todclock_softc { - struct device sc_dev; /* device node */ - void *sc_rtc_arg; /* arg to read/write */ - int (*sc_rtc_write) __P((void *, rtc_t *)); /* rtc write function */ - int (*sc_rtc_read) __P((void *, rtc_t *)); /* rtc read function */ -}; - -/* prototypes for functions */ - -static void todclockattach __P((struct device *parent, struct device *self, - void *aux)); -static int todclockmatch __P((struct device *parent, struct cfdata *cf, - void *aux)); -static __inline int yeartoday __P((int)); - -/* - * We need to remember our softc for functions like inittodr() - * and resettodr() - * since we only ever have one time-of-day device we can just store - * the direct pointer to softc. - */ - -static struct todclock_softc *todclock_sc = NULL; - -/* driver and attach structures */ - -CFATTACH_DECL(todclock, sizeof(struct todclock_softc), - todclockmatch, todclockattach, NULL, NULL); - -/* - * int todclockmatch(struct device *parent, struct cfdata *cf, void *aux) - * - * todclock device probe function. - * just validate the attach args - */ - -int -todclockmatch(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct todclock_attach_args *ta = aux; - - if (todclock_sc != NULL) - return(0); - if (strcmp(ta->ta_name, "todclock") != 0) - return(0); - - if (ta->ta_flags & TODCLOCK_FLAG_FAKE) - return(1); - return(2); -} - -/* - * void todclockattach(struct device *parent, struct device *self, void *aux) - * - * todclock device attach function. - * Initialise the softc structure and do a search for children - */ - -void -todclockattach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; -{ - struct todclock_softc *sc = (void *)self; - struct todclock_attach_args *ta = aux; - - /* set up our softc */ - todclock_sc = sc; - todclock_sc->sc_rtc_arg = ta->ta_rtc_arg; - todclock_sc->sc_rtc_write = ta->ta_rtc_write; - todclock_sc->sc_rtc_read = ta->ta_rtc_read; - - printf("\n"); - - /* - * Initialise the time of day register. - * This is normally left to the filing system to do but not all - * filing systems call it e.g. cd9660 - */ - - inittodr(0); -} - -static __inline int -yeartoday(year) - int year; -{ - return((year % 4) ? 365 : 366); -} - - -static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static int timeset = 0; - -#define SECPERDAY (24*60*60) -#define SECPERNYEAR (365*SECPERDAY) -#define SECPER4YEARS (4*SECPERNYEAR+SECPERDAY) -#define EPOCHYEAR 1970 - -/* - * Globally visable functions - * - * These functions are used from other parts of the kernel. - * These functions use the functions defined in the tod_sc - * to actually read and write the rtc. - * - * The first todclock to be attached will be used for handling - * the time of day. - */ - -/* - * Write back the time of day to the rtc - */ - -void -resettodr() -{ - int s; - time_t year, mon, day, hour, min, sec; - rtc_t rtc; - - /* Have we set the system time in inittodr() */ - if (!timeset) - return; - - /* We need a todclock device and should always have one */ - if (!todclock_sc) - return; - - /* Abort early if there is not actually an RTC write routine */ - if (todclock_sc->sc_rtc_write == NULL) - return; - - sec = time.tv_sec; - sec -= rtc_offset * 60; - year = (sec / SECPER4YEARS) * 4; - sec %= SECPER4YEARS; - - /* year now hold the number of years rounded down 4 */ - - while (sec > (yeartoday(EPOCHYEAR+year) * SECPERDAY)) { - sec -= yeartoday(EPOCHYEAR+year)*SECPERDAY; - year++; - } - - /* year is now a correct offset from the EPOCHYEAR */ - - year+=EPOCHYEAR; - mon=0; - if (yeartoday(year) == 366) - month[1]=29; - else - month[1]=28; - while (sec >= month[mon]*SECPERDAY) { - sec -= month[mon]*SECPERDAY; - mon++; - } - - day = sec / SECPERDAY; - sec %= SECPERDAY; - hour = sec / 3600; - sec %= 3600; - min = sec / 60; - sec %= 60; - rtc.rtc_cen = year / 100; - rtc.rtc_year = year % 100; - rtc.rtc_mon = mon+1; - rtc.rtc_day = day+1; - rtc.rtc_hour = hour; - rtc.rtc_min = min; - rtc.rtc_sec = sec; - rtc.rtc_centi = - rtc.rtc_micro = 0; - - s = splclock(); - todclock_sc->sc_rtc_write(todclock_sc->sc_rtc_arg, &rtc); - (void)splx(s); -} - -/* - * Initialise the time of day register, based on the time base which is, e.g. - * from a filesystem. - */ - -void -inittodr(base) - time_t base; -{ - time_t n; - int i, days = 0; - int s; - int year; - rtc_t rtc; - - /* - * Default to the suggested time but replace that we one from an - * RTC is we can. - */ - - /* Use the suggested time as a fall back */ - time.tv_sec = base; - time.tv_usec = 0; - - /* Can we read an RTC ? */ - if (todclock_sc != NULL && todclock_sc->sc_rtc_read) { - s = splclock(); - if (todclock_sc->sc_rtc_read(todclock_sc->sc_rtc_arg, &rtc) == 0) { - (void)splx(s); - return; - } - (void)splx(s); - } else - return; - - /* Convert the rtc time into seconds */ - - n = rtc.rtc_sec + 60 * rtc.rtc_min + 3600 * rtc.rtc_hour; - n += (rtc.rtc_day - 1) * 3600 * 24; - year = (rtc.rtc_year + rtc.rtc_cen * 100) - 1900; - - if (yeartoday(year) == 366) - month[1] = 29; - for (i = rtc.rtc_mon - 2; i >= 0; i--) - days += month[i]; - month[1] = 28; - - for (i = 70; i < year; i++) - days += yeartoday(i); - - n += days * 3600 * 24; - - n += rtc_offset * 60; - - time.tv_sec = n; - time.tv_usec = 0; - - /* timeset is used to ensure the time is valid before a resettodr() */ - - timeset = 1; - - /* If the base was 0 then keep quiet */ - - if (base) { - printf("inittodr: %02d:%02d:%02d.%02d%02d %02d/%02d/%02d%02d\n", - rtc.rtc_hour, rtc.rtc_min, rtc.rtc_sec, rtc.rtc_centi, - rtc.rtc_micro, rtc.rtc_day, rtc.rtc_mon, rtc.rtc_cen, - rtc.rtc_year); - - if (n > base + 60) { - days = (n - base) / SECPERDAY; - printf("Clock has gained %d day%c %ld hours %ld minutes %ld secs\n", - days, ((days == 1) ? 0 : 's'), - (long)((n - base) / 3600) % 24, - (long)((n - base) / 60) % 60, - (long) (n - base) % 60); - } - } -} - -/* End of todclock.c */ diff --git a/sys/arch/arm/iomd/todclockvar.h b/sys/arch/arm/iomd/todclockvar.h deleted file mode 100644 index 09a1833de610..000000000000 --- a/sys/arch/arm/iomd/todclockvar.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $NetBSD: todclockvar.h,v 1.1 2001/10/05 22:27:42 reinoud Exp $ */ - -/* - * Copyright (c) 1997 Mark Brinicombe. - * Copyright (c) 1997 Causality Limited - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * todclockvar.h - * - * structures and variables for the todclock device - * - * Created : 12/02/97 - */ - -/* - * Attach args for todclock device - */ - -struct todclock_attach_args { - const char *ta_name; /* device name */ - void *ta_rtc_arg; /* arg to read/write */ - int (*ta_rtc_write) __P((void *, rtc_t *)); /* function to write rtc */ - int (*ta_rtc_read) __P((void *, rtc_t *)); /* function to read rtc */ - int ta_flags; /* flags */ -#define TODCLOCK_FLAG_FAKE 0x01 /* tod service is faked */ -}; - -/* End of todclockvar.h */