/* * 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; }
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"); }