static int probe_thermostat()

in therm_adt746x.c [468:565]


static int probe_thermostat(struct i2c_client *client,
			    const struct i2c_device_id *id)
{
	struct device_node *np = client->dev.of_node;
	struct thermostat* th;
	const __be32 *prop;
	int i, rc, vers, offset = 0;

	if (!np)
		return -ENXIO;
	prop = of_get_property(np, "hwsensor-params-version", NULL);
	if (!prop)
		return -ENXIO;
	vers = be32_to_cpup(prop);
	printk(KERN_INFO "adt746x: version %d (%ssupported)\n",
	       vers, vers == 1 ? "" : "un");
	if (vers != 1)
		return -ENXIO;

	if (of_get_property(np, "hwsensor-location", NULL)) {
		for (i = 0; i < 3; i++) {
			sensor_location[i] = of_get_property(np,
					"hwsensor-location", NULL) + offset;

			if (sensor_location[i] == NULL)
				sensor_location[i] = "";

			printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]);
			offset += strlen(sensor_location[i]) + 1;
		}
	}

	th = kzalloc(sizeof(struct thermostat), GFP_KERNEL);
	if (!th)
		return -ENOMEM;

	i2c_set_clientdata(client, th);
	th->clt = client;
	th->type = id->driver_data;

	rc = read_reg(th, CONFIG_REG);
	if (rc < 0) {
		dev_err(&client->dev, "Thermostat failed to read config!\n");
		kfree(th);
		return -ENODEV;
	}

	/* force manual control to start the fan quieter */
	if (fan_speed == -1)
		fan_speed = 64;
	
	if (th->type == ADT7460) {
		printk(KERN_INFO "adt746x: ADT7460 initializing\n");
		/* The 7460 needs to be started explicitly */
		write_reg(th, CONFIG_REG, 1);
	} else
		printk(KERN_INFO "adt746x: ADT7467 initializing\n");

	for (i = 0; i < 3; i++) {
		th->initial_limits[i] = read_reg(th, LIMIT_REG[i]);
		set_limit(th, i);
	}

	printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d"
			 " to %d, %d, %d\n",
			 th->initial_limits[0], th->initial_limits[1],
			 th->initial_limits[2], th->limits[0], th->limits[1],
			 th->limits[2]);

	/* record invert bit status because fw can corrupt it after suspend */
	th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
	th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;

	/* be sure to really write fan speed the first time */
	th->last_speed[0] = -2;
	th->last_speed[1] = -2;
	th->last_var[0] = -80;
	th->last_var[1] = -80;

	if (fan_speed != -1) {
		/* manual mode, stop fans */
		write_both_fan_speed(th, 0);
	} else {
		/* automatic mode */
		write_both_fan_speed(th, -1);
	}
	
	th->thread = kthread_run(monitor_task, th, "kfand");
	if (th->thread == ERR_PTR(-ENOMEM)) {
		printk(KERN_INFO "adt746x: Kthread creation failed\n");
		th->thread = NULL;
		return -ENOMEM;
	}

	thermostat_create_files(th);

	return 0;
}