/* Function Description: Initialize i2c child device. * Return: None. */ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, struct i2c_child_t *pchild) { int node, len, i, tbls_size = 0; node = edev_child->prom_node; /* Get device address. */ len = prom_getproperty(node, "reg", (char *) &(pchild->addr), sizeof(pchild->addr)); /* Get tables property. Read firmware temperature tables. */ len = prom_getproperty(node, "translation", (char *) pchild->tblprop_array, (PCF8584_MAX_CHANNELS * sizeof(struct pcf8584_tblprop))); if (len > 0) { pchild->total_tbls = len / sizeof(struct pcf8584_tblprop); for (i = 0; i < pchild->total_tbls; i++) { if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) { tbls_size = pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset; } } pchild->tables = kmalloc(tbls_size, GFP_KERNEL); len = prom_getproperty(node, "tables", (char *) pchild->tables, tbls_size); if (len <= 0) { printk("envctrl: Failed to get table.\n"); return; } } /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04) * sections 2.5, 3.5, 4.5 state node 0x70 for CP1400/1500 is * "For Factory Use Only." * * We ignore the node on these platforms by assigning the * 'NULL' monitor type. */ if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) { int len; char prop[56]; len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop)); if (0 < len && (0 == strncmp(prop, "SUNW,UltraSPARC-IIi-cEngine", len))) { for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { pchild->mon_type[len] = ENVCTRL_NOMON; } return; } } /* Get the monitor channels. */ len = prom_getproperty(node, "channels-in-use", (char *) pchild->chnl_array, (PCF8584_MAX_CHANNELS * sizeof(struct pcf8584_channel))); pchild->total_chnls = len / sizeof(struct pcf8584_channel); for (i = 0; i < pchild->total_chnls; i++) { switch (pchild->chnl_array[i].type) { case PCF8584_TEMP_TYPE: envctrl_init_adc(pchild, node); break; case PCF8584_GLOBALADDR_TYPE: envctrl_init_globaladdr(pchild); i = pchild->total_chnls; break; case PCF8584_FANSTAT_TYPE: envctrl_init_fanstat(pchild); i = pchild->total_chnls; break; case PCF8584_VOLTAGE_TYPE: if (pchild->i2ctype == I2C_ADC) { envctrl_init_adc(pchild,node); } else { envctrl_init_voltage_status(pchild); } i = pchild->total_chnls; break; default: break; }; } }
/* Function Description: Initialize i2c child device. * Return: None. */ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, struct i2c_child_t *pchild) { int len, i, tbls_size = 0; struct device_node *dp = edev_child->prom_node; const void *pval; /* Get device address. */ pval = of_get_property(dp, "reg", &len); memcpy(&pchild->addr, pval, len); /* Get tables property. Read firmware temperature tables. */ pval = of_get_property(dp, "translation", &len); if (pval && len > 0) { memcpy(pchild->tblprop_array, pval, len); pchild->total_tbls = len / sizeof(struct pcf8584_tblprop); for (i = 0; i < pchild->total_tbls; i++) { if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) { tbls_size = pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset; } } pchild->tables = kmalloc(tbls_size, GFP_KERNEL); if (pchild->tables == NULL){ printk("envctrl: Failed to allocate table.\n"); return; } pval = of_get_property(dp, "tables", &len); if (!pval || len <= 0) { printk("envctrl: Failed to get table.\n"); return; } memcpy(pchild->tables, pval, len); } /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04) * sections 2.5, 3.5, 4.5 state node 0x70 for CP1400/1500 is * "For Factory Use Only." * * We ignore the node on these platforms by assigning the * 'NULL' monitor type. */ if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) { struct device_node *root_node; int len; root_node = of_find_node_by_path("/"); if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) { for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { pchild->mon_type[len] = ENVCTRL_NOMON; } return; } } /* Get the monitor channels. */ pval = of_get_property(dp, "channels-in-use", &len); memcpy(pchild->chnl_array, pval, len); pchild->total_chnls = len / sizeof(struct pcf8584_channel); for (i = 0; i < pchild->total_chnls; i++) { switch (pchild->chnl_array[i].type) { case PCF8584_TEMP_TYPE: envctrl_init_adc(pchild, dp); break; case PCF8584_GLOBALADDR_TYPE: envctrl_init_globaladdr(pchild); i = pchild->total_chnls; break; case PCF8584_FANSTAT_TYPE: envctrl_init_fanstat(pchild); i = pchild->total_chnls; break; case PCF8584_VOLTAGE_TYPE: if (pchild->i2ctype == I2C_ADC) { envctrl_init_adc(pchild,dp); } else { envctrl_init_voltage_status(pchild); } i = pchild->total_chnls; break; default: break; }; } }