static int initialize_i2c_bus_info ( int bus_num, struct i2c_board_info *board_info, int info_size, struct i2c_board_info *master_board_info, int master_info_size ) { int dev_cnt = 0; #ifdef CONFIG_ARM_OF struct device_node *bus_node; const void *feat_prop; char *device_names; char dev_name[I2C_MAX_DEV_NAME_LEN]; int device_name_len, i, j; struct i2c_board_info *master_entry; char prop_name[I2C_BUS_PROP_NAME_LEN]; j = 0; bus_node = of_find_node_by_path(DT_PATH_I2C); if (bus_node == NULL || board_info == NULL) return dev_cnt; snprintf(prop_name, I2C_BUS_PROP_NAME_LEN, "bus%1ddevices", bus_num); feat_prop = of_get_property(bus_node, prop_name, NULL); if (NULL != feat_prop) { device_names = (char *)feat_prop; printk(KERN_INFO "I2C-%d devices: %s\n", bus_num, device_names); device_name_len = strlen(device_names); memset(dev_name, 0x0, I2C_MAX_DEV_NAME_LEN); for (i = 0; i < device_name_len; i++) { if (device_names[i] != '\0' && device_names[i] != ',') dev_name[j++] = device_names[i]; /* parse for ',' in string */ if (device_names[i] == ',' || (i == device_name_len-1)) { if (dev_cnt < info_size) { master_entry = get_board_info(dev_name, bus_num, master_board_info, master_info_size); if (master_entry != NULL) { memcpy( &board_info[dev_cnt++], master_entry, sizeof( struct i2c_board_info)); printk(KERN_INFO "%s -> I2C bus-%d\n", master_entry->type, bus_num); } j = 0; memset( dev_name, 0x0, I2C_MAX_DEV_NAME_LEN); } } } } #endif return dev_cnt; }
/******************************************************************************* * SN layout * * 32 30 25 20 15 10 5 0 * ----------------------------------------------------------------------- * | | Vendor ID| Board ID | Vendor ID| Board ID | Vendor ID| Board ID | * ----------------------------------------------------------------------- * | EK | DM | CPU | * * Rev layout * * 32 24 21 18 15 10 5 0 * ----------------------------------------------------------------------- * | | EK | DM | CPU | EK | DM | CPU | * ----------------------------------------------------------------------- * | Revision id | Revision Code | * ******************************************************************************* */ void load_1wire_info() { int i; unsigned int cnt; unsigned int size = LEN_ONE_WIRE_INFO; struct board_info board_info; struct board_info *bd_info; memset(&board_info, 0, sizeof(board_info)); bd_info= &board_info; dbg_log(1, "1-Wire: Loading 1-Wire information ...\n\r"); sn = rev = 0; cnt = enumerate_all_rom(); if (!cnt) { dbg_log(1, "WARNING: 1-Wire: No 1-Wire chip found\n\r "); goto err; } dbg_log(1, "1-Wire: BoardName | [Revid] | VendorName\n\r"); for (i = 0; i < cnt; i++) { if (ds24xx_read_memory(i, 0, 0, size, buf) < 0) { dbg_log(1, "WARNING: 1-Wire: Failed to read from 1-Wire chip!\n\r"); goto err; } if (get_board_info(buf, i, bd_info)) { dbg_log(1, "WARNING: 1-Wire: Failed to get board information\n\r"); goto err; } switch (bd_info->board_type) { case BOARD_TYPE_CPU: sn |= (bd_info->board_id & SN_MASK); sn |= ((bd_info->vendor_id & VENDOR_MASK) << CM_VENDOR_OFFSET); rev |= ((bd_info->revision_code - 'A') & REV_MASK); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << CM_REV_ID_OFFSET); break; case BOARD_TYPE_DM: sn |= ((bd_info->board_id & SN_MASK) << DM_SN_OFFSET); sn |= ((bd_info->vendor_id & VENDOR_MASK) << DM_VENDOR_OFFSET); rev |= (((bd_info->revision_code - 'A') & REV_MASK) << DM_REV_OFFSET); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << DM_REV_ID_OFFSET); break; case BOARD_TYPE_EK: sn |= ((bd_info->board_id & SN_MASK) << EK_SN_OFFSET); sn |= ((bd_info->vendor_id & VENDOR_MASK) << EK_VENDOR_OFFSET); rev |= (((bd_info->revision_code - 'A') & REV_MASK) << EK_REV_OFFSET); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << EK_REV_ID_OFFSET); break; default: dbg_log(1, "WARNING: 1-Wire: Unknown board type\n\r"); goto err; } } /* save to GPBR #2 and #3 */ dbg_log(1, "\n\r1-Wire: SYS_GPBR2: %d, SYS_GPBR3: %d\n\r\n\r", sn, rev); writel(sn, AT91C_BASE_GPBR + 4 * 2); writel(rev, AT91C_BASE_GPBR + 4 * 3); return; err: sn = set_default_sn(); rev = set_default_rev(); dbg_log(1, "\n\r1-Wire: Using defalt value SYS_GPBR2: %d, SYS_GPBR3: %d\n\r\n\r", sn, rev); writel(sn, AT91C_BASE_GPBR + 4 * 2); writel(rev, AT91C_BASE_GPBR + 4 * 3); return; }
/******************************************************************************* * SN layout * * 31 30 25 20 15 10 5 0 * ----------------------------------------------------------------------- * | | Vendor ID| Board ID | Vendor ID| Board ID | Vendor ID| Board ID | * ----------------------------------------------------------------------- * | EK | DM | CPU | * * Rev layout * * 31 24 21 18 15 10 5 0 * ----------------------------------------------------------------------- * | | EK | DM | CPU | EK | DM | CPU | * ----------------------------------------------------------------------- * | Revision id | Revision Code | * ******************************************************************************* */ void load_1wire_info(void) { int i, j; unsigned int cnt; unsigned int size = LEN_ONE_WIRE_INFO; struct board_info board_info; struct board_info *bd_info; #if defined(CONFIG_SAMA5D4EK) int missing = BOARD_TYPE_EK_MASK | BOARD_TYPE_DM_MASK; #else int missing = BOARD_TYPE_MASK; #endif unsigned char *tmp = buf; memset(&board_info, 0, sizeof(board_info)); bd_info= &board_info; dbg_info("1-Wire: Loading 1-Wire information ...\n"); sn = rev = 0; cnt = enumerate_all_rom(); if (!cnt) { dbg_info("WARNING: 1-Wire: No 1-Wire chip found\n "); goto err; } dbg_info("1-Wire: BoardName | [Revid] | VendorName\n"); for (i = 0; i < cnt; i++) { if (ds24xx_read_memory(i, 0, 0, size, buf) < 0) { dbg_info("WARNING: 1-Wire: Failed to read from 1-Wire chip!\n"); goto err; } dbg_loud("board: #%d: ", i); for (j = 0; j < size; j++) dbg_loud("%d ", *tmp++); dbg_loud("\n"); if (get_board_info(buf, i, bd_info)) { continue; } switch (bd_info->board_type) { case BOARD_TYPE_CPU: missing &= (BOARD_TYPE_MASK & ~BOARD_TYPE_CPU_MASK); sn |= (bd_info->board_id & SN_MASK); sn |= ((bd_info->vendor_id & VENDOR_MASK) << CM_VENDOR_OFFSET); rev |= ((bd_info->revision_code - 'A') & REV_MASK); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << CM_REV_ID_OFFSET); break; case BOARD_TYPE_DM: missing &= (BOARD_TYPE_MASK & ~BOARD_TYPE_DM_MASK); sn |= ((bd_info->board_id & SN_MASK) << DM_SN_OFFSET); sn |= ((bd_info->vendor_id & VENDOR_MASK) << DM_VENDOR_OFFSET); rev |= (((bd_info->revision_code - 'A') & REV_MASK) << DM_REV_OFFSET); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << DM_REV_ID_OFFSET); break; case BOARD_TYPE_EK: missing &= (BOARD_TYPE_MASK & ~BOARD_TYPE_EK_MASK); sn |= ((bd_info->board_id & SN_MASK) << EK_SN_OFFSET); sn |= ((bd_info->vendor_id & VENDOR_MASK) << EK_VENDOR_OFFSET); rev |= (((bd_info->revision_code - 'A') & REV_MASK) << EK_REV_OFFSET); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << EK_REV_ID_OFFSET); break; default: dbg_info("WARNING: 1-Wire: Unknown board type\n"); goto err; } } if (missing & BOARD_TYPE_CPU_MASK) dbg_info("1-Wire: Failed to read CM board information\n"); if (missing & BOARD_TYPE_DM_MASK) dbg_info("1-Wire: Failed to read DM board information\n"); if (missing & BOARD_TYPE_EK_MASK) dbg_info("1-Wire: Failed to read EK board information\n"); goto save_info; err: dbg_info("\n1-Wire: Using defalt information\n"); sn = set_default_sn(); rev = set_default_rev(); save_info: #ifdef AT91C_BASE_GPBR /* save to GPBR #2 and #3 */ dbg_info("\n1-Wire: SYS_GPBR2: %d, SYS_GPBR3: %d\n\n", sn, rev); writel(sn, AT91C_BASE_GPBR + 4 * 2); writel(rev, AT91C_BASE_GPBR + 4 * 3); #else dbg_info("\n1-Wire: Board sn: %d, revsion: %d\n\n", sn, rev); #endif return; }
void * load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, void *ign1, void *ign2) { #ifdef CONFIG_40x openbios_bd_t *openbios_bd = NULL; openbios_bd_t *(*get_board_info)(void) = (openbios_bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); /* * On 40x platforms we not only need the MAC-addresses, but also the * clocks and memsize. Now try to get all values using the OpenBIOS * "get_board_info()" callback. */ if ((openbios_bd = get_board_info()) != NULL) { /* * Copy bd_info from OpenBIOS struct into U-Boot struct * used by kernel */ hold_residual->bi_memsize = openbios_bd->bi_memsize; hold_residual->bi_intfreq = openbios_bd->bi_intfreq; hold_residual->bi_busfreq = openbios_bd->bi_busfreq; hold_residual->bi_pci_busfreq = openbios_bd->bi_pci_busfreq; memcpy(hold_residual->bi_pci_enetaddr, openbios_bd->bi_pci_enetaddr, 6); #ifdef CONFIG_405EP memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr[0], 6); memcpy(hold_residual->bi_enet1addr, openbios_bd->bi_enetaddr[1], 6); hold_residual->bi_opbfreq = openbios_bd->bi_opb_busfreq; hold_residual->bi_procfreq = openbios_bd->bi_pllouta_freq; #else /* CONFIG_405EP */ memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr, 6); #endif /* CONFIG_405EP */ } else { /* Hmmm...better try to stuff some defaults. */ hold_residual->bi_memsize = 16 * 1024 * 1024; hold_residual->bi_intfreq = 200000000; hold_residual->bi_busfreq = 100000000; hold_residual->bi_pci_busfreq = 66666666; /* * Only supply one mac-address in this fallback */ memcpy(hold_residual->bi_enetaddr, (void *)def_enet_addr, 6); #ifdef CONFIG_405EP hold_residual->bi_opbfreq = 50000000; hold_residual->bi_procfreq = 200000000; #endif /* CONFIG_405EP */ } timebase_period_ns = 1000000000 / hold_residual->bi_intfreq; #endif /* CONFIG_40x */ #ifdef CONFIG_440GP /* simply copy the MAC addresses */ memcpy(hold_residual->bi_enetaddr, (char *)OPENBIOS_MAC_BASE, 6); memcpy(hold_residual->bi_enet1addr, (char *)(OPENBIOS_MAC_BASE+OPENBIOS_MAC_OFFSET), 6); #endif /* CONFIG_440GP */ decompress_kernel(load_addr, num_words, cksum); return (void *)hold_residual; }