int i2c_write(int address, const unsigned char* buf, int count ) { int i,x=0; i2c_start(); i2c_outb(address & 0xfe); if (i2c_getack()) { for (i=0; i<count; i++) { i2c_outb(buf[i]); if (!i2c_getack()) { x=-2; break; } } } else { debugf("i2c_write() - no ack\n"); x=-1; } i2c_stop(); return x; }
/* * Writes bytes to a I2C device. * * Returns number of bytes successfully sent or a negative value on error. */ int i2c_write(volatile unsigned char *iface, unsigned char addr, const unsigned char *buf, int count) { int i, rc; if (count <= 0) return 0; rc = i2c_start(iface); if (rc < 0) return rc; rc = i2c_outb(iface, addr & 0xfe); if (rc < 0) return rc; for (i = 0; i < count; i++) { rc = i2c_outb(iface, *buf++); if (rc < 0) return rc; } i2c_stop(iface); return count; }
/* * This should perform the 'PCF8584 initialization sequence' as described * in the Philips IC12 data book (1995, Aug 29). * There should be a 30 clock cycle wait after reset, I assume this * has been fulfilled. * There should be a delay at the end equal to the longest I2C message * to synchronize the BB-bit (in multimaster systems). How long is * this? I assume 1 second is always long enough. * * vdovikin: added detect code for PCF8584 */ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) { unsigned char temp; // DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", ; /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); /* * check to see S1 now used as R/W ctrl - * PCF8584 does that when ESO is zero */ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { ; return -ENXIO; /* definitely not PCF8584 */ } /* load own address in S0, effective address is (own << 1) */ i2c_outb(adap, get_own(adap)); /* check it's really written */ if ((temp = i2c_inb(adap)) != get_own(adap)) { ; return -ENXIO; } /* S1=0xA0, next byte in S2 */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { ; return -ENXIO; } /* load clock register S2 */ i2c_outb(adap, get_clock(adap)); /* check it's really written, the only 5 lowest bits does matter */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { ; return -ENXIO; } /* Enable serial interface, idle, S0 selected */ set_pcf(adap, 1, I2C_PCF_IDLE); /* check to see PCF is really idled and we can access status register */ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { ; return -ENXIO; } ; return 0; }
static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) { unsigned char temp; DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); /* */ set_pcf(adap, 1, I2C_PCF_PIN); /* */ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* */ } /* */ i2c_outb(adap, get_own(adap)); /* */ if ((temp = i2c_inb(adap)) != get_own(adap)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); return -ENXIO; } /* */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* */ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); return -ENXIO; } /* */ i2c_outb(adap, get_clock(adap)); /* */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); return -ENXIO; } /* */ set_pcf(adap, 1, I2C_PCF_IDLE); /* */ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); return 0; }
static void set_rtc_time(struct rtc_time *rtc_tm) { rtc_tm->tm_sec = to_bcd(rtc_tm->tm_sec); rtc_tm->tm_min = to_bcd(rtc_tm->tm_min); rtc_tm->tm_hour = to_bcd(rtc_tm->tm_hour); rtc_tm->tm_mday = to_bcd(rtc_tm->tm_mday); rtc_tm->tm_mon = to_bcd(rtc_tm->tm_mon + 1); rtc_tm->tm_year = to_bcd(rtc_tm->tm_year); if (rtc_tm->tm_year >= 0x100) { rtc_tm->tm_year -= 0x100; rtc_tm->tm_mon |= RTC_Y2K_MASK; } spin_lock_irq(&rtc_lock); i2c_start(); i2c_outb(RTC_I2C_ADDRESS | I2C_WRITE_MASK); i2c_outb(0x00); /* set starting register to 0 (=seconds) */ i2c_outb(rtc_tm->tm_sec); i2c_outb(rtc_tm->tm_min); i2c_outb(rtc_tm->tm_hour); i2c_outb(rtc_tm->tm_wday); i2c_outb(rtc_tm->tm_mday); i2c_outb(rtc_tm->tm_mon); i2c_outb(rtc_tm->tm_year); i2c_stop(); spin_unlock_irq(&rtc_lock); }
static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, int count, int last) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wrcount, status, timeout; for (wrcount=0; wrcount<count; ++wrcount) { DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", buf[wrcount] & 0xff)); i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { if (timeout == -EINTR) return -EINTR; /* arbitration lost */ i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); return -EREMOTEIO; /* got a better one ?? */ } if (status & I2C_PCF_LRB) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); return -EREMOTEIO; /* got a better one ?? */ } } if (last) i2c_stop(adap); else i2c_repstart(adap); return wrcount; }
int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes) { int ret = 0; unsigned char obuf[1]; int i; i2c_begin(); obuf[0] = address; /* send read command */ if (i2c_write(RTC_DEV_READ, obuf, 1) >= 0) { i2c_start(); i2c_outb(RTC_DEV_READ); if (i2c_getack()) { for(i = 0; i < numbytes-1; i++) buf[i] = i2c_inb(0); buf[i] = i2c_inb(1); } else { ret = -1; } } i2c_stop(); i2c_end(); return ret; }
int rtc_read(unsigned char address) { int value = -1; unsigned char buf[1]; i2c_begin(); buf[0] = address; /* send read command */ if (i2c_write(RTC_DEV_READ,buf,1) >= 0) { i2c_start(); i2c_outb(RTC_DEV_READ); if (i2c_getack()) { value = i2c_inb(1); } } i2c_stop(); i2c_end(); return value; }
static int __init rtc_init(void) { int cr1; platform_detect(); if (sda_index == scl_index) { printk(KERN_ERR "RTC-RV5C386A: unrecognized platform!\n"); return -ENODEV; } i2c_init(); /* * Switch RTC to 24h mode */ spin_lock_irq(&rtc_lock); i2c_start(); i2c_outb(RTC_I2C_ADDRESS | I2C_WRITE_MASK); i2c_outb(0xE4); /* start at address 0xE, transmission mode 4 */ cr1 = i2c_inb(I2C_NAK); i2c_stop(); spin_unlock_irq(&rtc_lock); if ((cr1 & RTC_24HOUR_MODE_MASK) == 0) { /* RTC is running in 12h mode */ printk(KERN_INFO "rtc.o: switching to 24h mode\n"); spin_lock_irq(&rtc_lock); i2c_start(); i2c_outb(RTC_I2C_ADDRESS | I2C_WRITE_MASK); i2c_outb(0xE0); i2c_outb(cr1 | RTC_24HOUR_MODE_MASK); i2c_stop(); spin_unlock_irq(&rtc_lock); } misc_register(&rtc_dev); printk(KERN_INFO "RV5C386A Real Time Clock Driver loaded\n"); return 0; }
static int pcf_doAddress(struct i2c_algo_pcf_data *adap, struct i2c_msg *msg) { unsigned short flags = msg->flags; unsigned char addr; addr = msg->addr << 1; if (flags & I2C_M_RD) addr |= 1; if (flags & I2C_M_REV_DIR_ADDR) addr ^= 1; i2c_outb(adap, addr); return 0; }
int i2c_read(int address, unsigned char* buf, int count ) { int i,x=0; i2c_start(); i2c_outb(address | 1); if (i2c_getack()) { for (i=0; i<count; i++) { buf[i] = i2c_inb(0); } } else x=-1; i2c_stop(); return x; }
/* * Reads bytes from a I2C device. * * Returns number of bytes successfully received or a negative value on error. */ int i2c_read(volatile unsigned char *iface, unsigned char addr, unsigned char *buf, int count) { int i, rc; if (count <= 0) return 0; rc = i2c_start(iface); if (rc < 0) return rc; rc = i2c_outb(iface, addr | 1); if (rc < 0) return rc; /* Switch to Rx mode */ iface[O_MBCR] &= ~MTX; /* Turn on ACK generation if reading multiple bytes */ if (count > 1) iface[O_MBCR] &= ~TXAK; /* Dummy read */ rc = (int) iface[O_MBDR]; for (i = count; i > 0; i--) { rc = i2c_wait_for_slave(iface); if (rc < 0) return rc; if (i == 2) /* Don't ACK the last byte to be read from the slave */ iface[O_MBCR] |= TXAK; else if (i == 1) /* Generate STOP before reading last byte received */ i2c_stop(iface); *buf++ = iface[O_MBDR]; } return count; }
static void get_rtc_time(struct rtc_time *rtc_tm) { int cr2; /* * Read date and time from the RTC. We use read method (3). */ spin_lock_irq(&rtc_lock); i2c_start(); i2c_outb(RTC_I2C_ADDRESS | I2C_READ_MASK); cr2 = i2c_inb(I2C_ACK); rtc_tm->tm_sec = i2c_inb(I2C_ACK); rtc_tm->tm_min = i2c_inb(I2C_ACK); rtc_tm->tm_hour = i2c_inb(I2C_ACK); rtc_tm->tm_wday = i2c_inb(I2C_ACK); rtc_tm->tm_mday = i2c_inb(I2C_ACK); rtc_tm->tm_mon = i2c_inb(I2C_ACK); rtc_tm->tm_year = i2c_inb(I2C_NAK); i2c_stop(); spin_unlock_irq(&rtc_lock); if (cr2 & RTC_VDET_MASK) { printk(KERN_WARNING "***RTC BATTERY FAILURE***\n"); } /* Handle century bit */ if (rtc_tm->tm_mon & RTC_Y2K_MASK) { rtc_tm->tm_mon &= ~RTC_Y2K_MASK; rtc_tm->tm_year += 0x100; } rtc_tm->tm_sec = from_bcd(rtc_tm->tm_sec); rtc_tm->tm_min = from_bcd(rtc_tm->tm_min); rtc_tm->tm_hour = from_bcd(rtc_tm->tm_hour); rtc_tm->tm_mday = from_bcd(rtc_tm->tm_mday); rtc_tm->tm_mon = from_bcd(rtc_tm->tm_mon) - 1; rtc_tm->tm_year = from_bcd(rtc_tm->tm_year); rtc_tm->tm_isdst = -1; /* DST not known */ }