/*
 * Internal simplified write function:
 *   i2c_regs:	Pointer to I2C registers for current bus
 *   chip:	I2C chip address, range 0..127
 *   addr:	Memory (register) address within the chip
 *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
 *		memories, 0 for register type devices with only one register)
 *   data:	Where to read the data
 *   len:	How many bytes to write
 *
 *   Returns:	0 on success, not 0 on failure
 */
static int __i2c_write(struct u5500_i2c_regs *i2c_regs, u8 chip, uint addr,
		int alen, u8 *data, int len)
{
	int i;
	u32 mcr = 0;

	/* Set the address mode to 7 bit */
	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);

	/* Store the slave address in the master control register */
	WRITE_FIELD(mcr, I2C_MCR_A7, I2C_MCR_SHIFT_A7, chip);

	/* Write operation */
	CLR_BIT(mcr, I2C_MCR_OP);

	/* Current transaction is terminated by STOP condition */
	SET_BIT(mcr, I2C_MCR_STOP);

	/* Frame length: addr byte + len */
	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, (alen + len));

	/* Write MCR register */
	writel(mcr, &i2c_regs->mcr);

	if (i2c_write_addr(i2c_regs, addr, alen) != 0)
		return -1;

	for (i = 0; i < len; i++) {
		/* Wait until the Tx FIFO is not full */
		if (loop_till_bit_clear((void *)&i2c_regs->risr,
					I2C_INT_TXFF, I2C_ENDAD_COUNTER))
			return -1;

		/* it is a 32 bit register with upper 24 reserved R/O */
		writeb(data[i], &i2c_regs->tfr);
	}

	/* Check for Master Transaction Done */
	if (loop_till_bit_set((void *)&i2c_regs->risr, I2C_INT_MTD,
				I2C_ENDAD_COUNTER)) {
		printf("i2c_write_byte error2: risr %08x\n",
				i2c_regs->risr);
		return -1;
	}

	/* Acknowledge Master Transaction Done */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);

	/* Acknowledge Master Transaction Done Without Stop */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);

	return 0;
}
/*
 * Probe the given I2C chip address. Returns 0 if a chip responded,
 * not 0 on failure.
 */
int i2c_probe(uchar chip)
{
	u32 mcr = 0;
	struct u5500_i2c_regs *i2c_regs;

	if (chip == CONFIG_SYS_I2C_SLAVE)
		return 1;

	i2c_regs = i2c_dev[i2c_bus_num];

	/* Set the address mode to 7 bit */
	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);

	/* Store the slave address in the master control register */
	WRITE_FIELD(mcr, I2C_MCR_A10, I2C_MCR_SHIFT_A7, chip);

	/* Read operation */
	SET_BIT(mcr, I2C_MCR_OP);

	/* Set the frame length to one byte */
	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);

	/* Current transaction is terminated by STOP condition */
	SET_BIT(mcr, I2C_MCR_STOP);

	/* Write MCR register */
	writel(mcr, &i2c_regs->mcr);

	/* Wait until the Rx Fifo is not empty */
	if (loop_till_bit_clear((void *)&i2c_regs->risr, I2C_INT_RXFE,
			I2C_ENDAD_COUNTER)) {
		i2c_abort(i2c_regs);
		return -1;
	}

	flush_fifo(i2c_regs);

	/* Acknowledge the Master Transaction Done */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);

	/* Acknowledge the Master Transaction Done Without Stop */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);

	return 0;
}
/*
 * Internal simplified read function:
 *   i2c_regs:	Pointer to I2C registers for current bus
 *   chip:	I2C chip address, range 0..127
 *   addr:	Memory (register) address within the chip
 *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
 *		memories, 0 for register type devices with only one register)
 *   value:	Where to put the data
 *
 *   Returns:	0 on success, not 0 on failure
 */
static int i2c_read_byte(struct u5500_i2c_regs *i2c_regs, uchar chip,
		uint addr, int alen, uchar *value)
{
	u32   mcr = 0;

	/* Set the address mode to 7 bit */
	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);

	/* Store the slave address in the master control register */
	WRITE_FIELD(mcr, I2C_MCR_A7, I2C_MCR_SHIFT_A7, chip);

	if (alen != 0) {
		/* Master write operation */
		CLR_BIT(mcr, I2C_MCR_OP);

		/* Configure the Frame length to one byte */
		WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);

		/* Repeated start, no stop */
		CLR_BIT(mcr, I2C_MCR_STOP);

		/* Write Master Control Register */
		writel(mcr, &i2c_regs->mcr);

		/* send addr/index */
		if (i2c_write_addr(i2c_regs, addr, alen) != 0)
			return -1;

		/* Check for the Master Transaction Done Without Stop */
		if (loop_till_bit_set((void *)&i2c_regs->risr,
					I2C_INT_MTDWS, I2C_ENDAD_COUNTER)) {
			return -1;
		}

		/* Acknowledge the Master Transaction Done Without Stop */
		i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
	}

	/* Master control configuration for read operation  */
	SET_BIT(mcr, I2C_MCR_OP);

	/* Configure the STOP condition, we read only one byte */
	SET_BIT(mcr, I2C_MCR_STOP);

	/* Set the frame length to one byte, we support only 1 byte reads */
	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);

	i2c_write_field(&i2c_regs->mcr, I2C_MCR_LENGTH_STOP_OP,
			I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);

	/*
	 * receive_data_polling
	 */

	/* Wait until the Rx FIFO is not empty */
	if (loop_till_bit_clear((void *)&i2c_regs->risr, I2C_INT_RXFE,
			I2C_ENDAD_COUNTER))
		return -1;

	/* Read the data byte from Rx FIFO */
	*value = readb(&i2c_regs->rfr);

	/* Wait until the work is done */
	if (loop_till_bit_set((void *)&i2c_regs->risr, I2C_INT_MTD,
				I2C_ENDAD_COUNTER))
		return -1;

	/* Acknowledge the Master Transaction Done */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);

	/* If MTD is set, Master Transaction Done Without Stop is set too */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);

	return 0;
}
示例#4
0
static void print_record(FILE *fout, const char *field, IP2LocationRecord *record, const char *format, const char *ip)
{
    const char *start = field;
    const char *end = strchr(start, ',');
    int first = 1;

    if (strcmp(format, "XML") == 0) {
        fprintf(fout, "<row>");
    }

#define WRITE_FIELD(field_name, field)  \
        if (strncmp(start, field_name, end - start) == 0) { \
            const char *value = field; \
            if (strcmp(value, NOT_SUPPORTED) == 0) { \
                value = "N/A"; \
            } \
            if (strcmp(format, "XML") == 0) { \
                fprintf(fout, "<%s>%s</%s>", field_name, value, field_name); \
            } else if (strcmp(format, "CSV") == 0) { \
                if (!first) { \
                    fprintf(fout, ","); \
                } \
                fprintf(fout, "\"%s\"", value); \
            } else if (strcmp(format, "TAB") == 0) { \
                if (!first) { \
                    fprintf(fout, "\t"); \
                } \
                fprintf(fout, "%s", value); \
            } \
            first = 0; \
        }
#define WRITE_FIELDF(field_name, field)  \
        if (strncmp(start, field_name, end - start) == 0) { \
            if (strcmp(format, "XML") == 0) { \
                fprintf(fout, "<%s>%f</%s>", field_name, field, field_name); \
            } else if (strcmp(format, "CSV") == 0) { \
                if (!first) { \
                    fprintf(fout, ","); \
                } \
                fprintf(fout, "\"%f\"", field); \
            } else if (strcmp(format, "TAB") == 0) { \
                if (!first) { \
                    fprintf(fout, "\t"); \
                } \
                fprintf(fout, "%f", field); \
            } \
            first = 0; \
        }


    for (;;) {
        if (end == NULL) {
            end = start + strlen(start);
        }

        WRITE_FIELD("ip", ip);
        WRITE_FIELD("countryshort", record->country_short);
        WRITE_FIELD("countrylong", record->country_long);
        WRITE_FIELD("region", record->region);
        WRITE_FIELD("city", record->city);
        WRITE_FIELD("isp", record->isp);
        WRITE_FIELDF("latitude", record->latitude);
        WRITE_FIELDF("longitude", record->longitude);
        WRITE_FIELD("domain", record->domain);
        WRITE_FIELD("zipcode", record->zipcode);
        WRITE_FIELD("timezone", record->timezone);
        WRITE_FIELD("netspeed", record->netspeed);
        WRITE_FIELD("iddcode", record->iddcode);
        WRITE_FIELD("areacode", record->areacode);
        WRITE_FIELD("weatherstationcode", record->weatherstationcode);
        WRITE_FIELD("weatherstationname", record->weatherstationname);
        WRITE_FIELD("mcc", record->mcc);
        WRITE_FIELD("mnc", record->mnc);
        WRITE_FIELD("mobilebrand", record->mobilebrand);
        WRITE_FIELDF("elevation", record->elevation);
        WRITE_FIELD("usagetype", record->usagetype);

        if (*end == ',') {
            start = end + 1;
            end = strchr(start, ',');
        } else {
            break;
        }
    }
    if (strcmp(format, "XML") == 0) {
        fprintf(fout, "</row>");
    }
    fprintf(fout, "\n");
}