static int adt7475_probe()

in adt7475.c [1542:1723]


static int adt7475_probe(struct i2c_client *client)
{
	enum chips chip;
	static const char * const names[] = {
		[adt7473] = "ADT7473",
		[adt7475] = "ADT7475",
		[adt7476] = "ADT7476",
		[adt7490] = "ADT7490",
	};

	struct adt7475_data *data;
	struct device *hwmon_dev;
	int i, ret = 0, revision, group_num = 0;
	u8 config3;
	const struct i2c_device_id *id = i2c_match_id(adt7475_id, client);

	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	mutex_init(&data->lock);
	data->client = client;
	i2c_set_clientdata(client, data);

	if (client->dev.of_node)
		chip = (enum chips)of_device_get_match_data(&client->dev);
	else
		chip = id->driver_data;

	/* Initialize device-specific values */
	switch (chip) {
	case adt7476:
		data->has_voltage = 0x0e;	/* in1 to in3 */
		revision = adt7475_read(REG_DEVID2) & 0x07;
		break;
	case adt7490:
		data->has_voltage = 0x3e;	/* in1 to in5 */
		revision = adt7475_read(REG_DEVID2) & 0x03;
		if (revision == 0x03)
			revision += adt7475_read(REG_DEVREV2);
		break;
	default:
		data->has_voltage = 0x06;	/* in1, in2 */
		revision = adt7475_read(REG_DEVID2) & 0x07;
	}

	config3 = adt7475_read(REG_CONFIG3);
	/* Pin PWM2 may alternatively be used for ALERT output */
	if (!(config3 & CONFIG3_SMBALERT))
		data->has_pwm2 = 1;
	/* Meaning of this bit is inverted for the ADT7473-1 */
	if (id->driver_data == adt7473 && revision >= 1)
		data->has_pwm2 = !data->has_pwm2;

	data->config4 = adt7475_read(REG_CONFIG4);
	/* Pin TACH4 may alternatively be used for THERM */
	if ((data->config4 & CONFIG4_PINFUNC) == 0x0)
		data->has_fan4 = 1;

	/*
	 * THERM configuration is more complex on the ADT7476 and ADT7490,
	 * because 2 different pins (TACH4 and +2.5 Vin) can be used for
	 * this function
	 */
	if (id->driver_data == adt7490) {
		if ((data->config4 & CONFIG4_PINFUNC) == 0x1 &&
		    !(config3 & CONFIG3_THERM))
			data->has_fan4 = 1;
	}
	if (id->driver_data == adt7476 || id->driver_data == adt7490) {
		if (!(config3 & CONFIG3_THERM) ||
		    (data->config4 & CONFIG4_PINFUNC) == 0x1)
			data->has_voltage |= (1 << 0);		/* in0 */
	}

	/*
	 * On the ADT7476, the +12V input pin may instead be used as VID5,
	 * and VID pins may alternatively be used as GPIO
	 */
	if (id->driver_data == adt7476) {
		u8 vid = adt7475_read(REG_VID);
		if (!(vid & VID_VIDSEL))
			data->has_voltage |= (1 << 4);		/* in4 */

		data->has_vid = !(adt7475_read(REG_CONFIG5) & CONFIG5_VIDGPIO);
	}

	/* Voltage attenuators can be bypassed, globally or individually */
	data->config2 = adt7475_read(REG_CONFIG2);
	ret = load_attenuators(client, chip, data);
	if (ret)
		dev_warn(&client->dev, "Error configuring attenuator bypass\n");

	if (data->config2 & CONFIG2_ATTN) {
		data->bypass_attn = (0x3 << 3) | 0x3;
	} else {
		data->bypass_attn = ((data->config4 & CONFIG4_ATTN_IN10) >> 4) |
				    ((data->config4 & CONFIG4_ATTN_IN43) >> 3);
	}
	data->bypass_attn &= data->has_voltage;

	/*
	 * Call adt7475_read_pwm for all pwm's as this will reprogram any
	 * pwm's which are disabled to manual mode with 0% duty cycle
	 */
	for (i = 0; i < ADT7475_PWM_COUNT; i++)
		adt7475_read_pwm(client, i);

	ret = adt7475_set_pwm_polarity(client);
	if (ret && ret != -EINVAL)
		dev_warn(&client->dev, "Error configuring pwm polarity\n");

	/* Start monitoring */
	switch (chip) {
	case adt7475:
	case adt7476:
		i2c_smbus_write_byte_data(client, REG_CONFIG1,
					  adt7475_read(REG_CONFIG1) | 0x01);
		break;
	default:
		break;
	}

	data->groups[group_num++] = &adt7475_attr_group;

	/* Features that can be disabled individually */
	if (data->has_fan4) {
		data->groups[group_num++] = &fan4_attr_group;
	}
	if (data->has_pwm2) {
		data->groups[group_num++] = &pwm2_attr_group;
	}
	if (data->has_voltage & (1 << 0)) {
		data->groups[group_num++] = &in0_attr_group;
	}
	if (data->has_voltage & (1 << 3)) {
		data->groups[group_num++] = &in3_attr_group;
	}
	if (data->has_voltage & (1 << 4)) {
		data->groups[group_num++] = &in4_attr_group;
	}
	if (data->has_voltage & (1 << 5)) {
		data->groups[group_num++] = &in5_attr_group;
	}
	if (data->has_vid) {
		data->vrm = vid_which_vrm();
		data->groups[group_num] = &vid_attr_group;
	}

	/* register device with all the acquired attributes */
	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
							   client->name, data,
							   data->groups);

	if (IS_ERR(hwmon_dev)) {
		ret = PTR_ERR(hwmon_dev);
		return ret;
	}

	dev_info(&client->dev, "%s device, revision %d\n",
		 names[id->driver_data], revision);
	if ((data->has_voltage & 0x11) || data->has_fan4 || data->has_pwm2)
		dev_info(&client->dev, "Optional features:%s%s%s%s%s\n",
			 (data->has_voltage & (1 << 0)) ? " in0" : "",
			 (data->has_voltage & (1 << 4)) ? " in4" : "",
			 data->has_fan4 ? " fan4" : "",
			 data->has_pwm2 ? " pwm2" : "",
			 data->has_vid ? " vid" : "");
	if (data->bypass_attn)
		dev_info(&client->dev, "Bypassing attenuators on:%s%s%s%s\n",
			 (data->bypass_attn & (1 << 0)) ? " in0" : "",
			 (data->bypass_attn & (1 << 1)) ? " in1" : "",
			 (data->bypass_attn & (1 << 3)) ? " in3" : "",
			 (data->bypass_attn & (1 << 4)) ? " in4" : "");

	/* Limits and settings, should never change update more than once */
	ret = adt7475_update_limits(client);
	if (ret)
		return ret;

	return 0;
}