예제 #1
0
파일: i2c-archos.c 프로젝트: IlVerz/rockbox
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;
}
예제 #2
0
/*
 * 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;
}
예제 #3
0
/*
 * 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;
}
예제 #5
0
파일: rtc.c 프로젝트: 7LK/McWRT
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);
}
예제 #6
0
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;
}
예제 #9
0
파일: rtc.c 프로젝트: 7LK/McWRT
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;
}
예제 #10
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;
}
예제 #11
0
파일: i2c-archos.c 프로젝트: IlVerz/rockbox
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;
}
예제 #12
0
/*
 * 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;
}
예제 #13
0
파일: rtc.c 프로젝트: 7LK/McWRT
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 */
}