Пример #1
0
static int
rockchip_thermal_register_sensor(struct platform_device *pdev,
				 struct rockchip_thermal_data *thermal,
				 struct rockchip_thermal_sensor *sensor,
				 enum sensor_id id)
{
	const struct rockchip_tsadc_chip *tsadc = thermal->chip;
	int error;

	tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
	tsadc->set_tshut_temp(id, thermal->regs, thermal->tshut_temp);

	sensor->thermal = thermal;
	sensor->id = id;
	sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev, id, sensor,
						      &rockchip_of_thermal_ops);
	if (IS_ERR(sensor->tzd)) {
		error = PTR_ERR(sensor->tzd);
		dev_err(&pdev->dev, "failed to register sensor %d: %d\n",
			id, error);
		return error;
	}

	return 0;
}
Пример #2
0
static int hisi_thermal_register_sensor(struct platform_device *pdev,
					struct hisi_thermal_data *data,
					struct hisi_thermal_sensor *sensor,
					int index)
{
	int ret, i;
	const struct thermal_trip *trip;

	sensor->id = index;
	sensor->thermal = data;

	sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev, sensor->id,
				sensor, &hisi_of_thermal_ops);
	if (IS_ERR(sensor->tzd)) {
		ret = PTR_ERR(sensor->tzd);
		sensor->tzd = NULL;
		dev_err(&pdev->dev, "failed to register sensor id %d: %d\n",
			sensor->id, ret);
		return ret;
	}

	trip = of_thermal_get_trip_points(sensor->tzd);

	for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) {
		if (trip[i].type == THERMAL_TRIP_PASSIVE) {
			sensor->thres_temp = trip[i].temperature;
			break;
		}
	}

	return 0;
}
Пример #3
0
static int tsens_register(struct tsens_device *tmdev)
{
	int i, ret;
	struct thermal_zone_device *tzd;
	u32 *hw_id, n = tmdev->num_sensors;
	struct device_node *np = tmdev->dev->of_node;

	hw_id = devm_kcalloc(tmdev->dev, n, sizeof(u32), GFP_KERNEL);
	if (!hw_id)
		return -ENOMEM;

	ret = of_property_read_u32_array(np, "qcom,sensor-id", hw_id, n);
	for (i = 0;  i < tmdev->num_sensors; i++) {
		if (ret)
			tmdev->sensor[i].hw_id = i;
		else
			tmdev->sensor[i].hw_id = hw_id[i];
		tmdev->sensor[i].tmdev = tmdev;
		tmdev->sensor[i].id = i;
		tzd = thermal_zone_of_sensor_register(tmdev->dev, i,
						      &tmdev->sensor[i],
						      &tsens_of_ops);
		if (IS_ERR(tzd))
			continue;
		tmdev->sensor[i].tzd = tzd;
		if (tmdev->ops->enable)
			tmdev->ops->enable(tmdev, i);
	}
	return 0;
}
Пример #4
0
static int gadc_thermal_probe(struct platform_device *pdev)
{
	struct gadc_thermal_info *gti;
	int ret;

	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "Only DT based supported\n");
		return -ENODEV;
	}

	gti = devm_kzalloc(&pdev->dev, sizeof(*gti), GFP_KERNEL);
	if (!gti)
		return -ENOMEM;

	ret = gadc_thermal_read_linear_lookup_table(&pdev->dev, gti);
	if (ret < 0)
		return ret;

	gti->dev = &pdev->dev;
	platform_set_drvdata(pdev, gti);

	gti->channel = iio_channel_get(&pdev->dev, "sensor-channel");
	if (IS_ERR(gti->channel)) {
		ret = PTR_ERR(gti->channel);
		dev_err(&pdev->dev, "IIO channel not found: %d\n", ret);
		return ret;
	}

	gti->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, 0,
						      gti, &gadc_thermal_ops);
	if (IS_ERR(gti->tz_dev)) {
		ret = PTR_ERR(gti->tz_dev);
		dev_err(&pdev->dev, "Thermal zone sensor register failed: %d\n",
			ret);
		goto sensor_fail;
	}

	return 0;

sensor_fail:
	iio_channel_release(gti->channel);

	return ret;
}
Пример #5
0
/**
 * devm_thermal_zone_of_sensor_register - Resource managed version of
 *				thermal_zone_of_sensor_register()
 * @dev: a valid struct device pointer of a sensor device. Must contain
 *       a valid .of_node, for the sensor node.
 * @sensor_id: a sensor identifier, in case the sensor IP has more
 *	       than one sensors
 * @data: a private pointer (owned by the caller) that will be passed
 *	  back, when a temperature reading is needed.
 * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
 *
 * Refer thermal_zone_of_sensor_register() for more details.
 *
 * Return: On success returns a valid struct thermal_zone_device,
 * otherwise, it returns a corresponding ERR_PTR(). Caller must
 * check the return value with help of IS_ERR() helper.
 * Registered thermal_zone_device device will automatically be
 * released when device is unbounded.
 */
struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
	struct device *dev, int sensor_id,
	void *data, const struct thermal_zone_of_device_ops *ops)
{
	struct thermal_zone_device **ptr, *tzd;

	ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr),
			   GFP_KERNEL);
	if (!ptr)
		return ERR_PTR(-ENOMEM);

	tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops);
	if (IS_ERR(tzd)) {
		devres_free(ptr);
		return tzd;
	}

	*ptr = tzd;
	devres_add(dev, ptr);

	return tzd;
}
Пример #6
0
static int tmp102_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct tmp102 *tmp102;
	int status;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_WORD_DATA)) {
		dev_err(&client->dev,
			"adapter doesn't support SMBus word transactions\n");
		return -ENODEV;
	}

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

	i2c_set_clientdata(client, tmp102);

	status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
	if (status < 0) {
		dev_err(&client->dev, "error reading config register\n");
		return status;
	}
	tmp102->config_orig = status;
	status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
					      TMP102_CONFIG);
	if (status < 0) {
		dev_err(&client->dev, "error writing config register\n");
		goto fail_restore_config;
	}
	status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
	if (status < 0) {
		dev_err(&client->dev, "error reading config register\n");
		goto fail_restore_config;
	}
	status &= ~TMP102_CONFIG_RD_ONLY;
	if (status != TMP102_CONFIG) {
		dev_err(&client->dev, "config settings did not stick\n");
		status = -ENODEV;
		goto fail_restore_config;
	}
	tmp102->last_update = jiffies - HZ;
	mutex_init(&tmp102->lock);

	status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group);
	if (status) {
		dev_dbg(&client->dev, "could not create sysfs files\n");
		goto fail_restore_config;
	}
	tmp102->hwmon_dev = hwmon_device_register(&client->dev);
	if (IS_ERR(tmp102->hwmon_dev)) {
		dev_dbg(&client->dev, "unable to register hwmon device\n");
		status = PTR_ERR(tmp102->hwmon_dev);
		goto fail_remove_sysfs;
	}

	tmp102->tz = thermal_zone_of_sensor_register(&client->dev, 0,
						     &client->dev,
						     tmp102_read_temp, NULL);
	if (IS_ERR(tmp102->tz))
		tmp102->tz = NULL;

	dev_info(&client->dev, "initialized\n");

	return 0;

fail_remove_sysfs:
	sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group);
fail_restore_config:
	i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
				     tmp102->config_orig);
	return status;
}
Пример #7
0
static int bcm2835_thermal_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct thermal_zone_device *tz;
	struct bcm2835_thermal_data *data;
	struct resource *res;
	int err = 0;
	u32 val;
	unsigned long rate;

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

	match = of_match_device(bcm2835_thermal_of_match_table,
				&pdev->dev);
	if (!match)
		return -EINVAL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	data->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(data->regs)) {
		err = PTR_ERR(data->regs);
		dev_err(&pdev->dev, "Could not get registers: %d\n", err);
		return err;
	}

	data->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(data->clk)) {
		err = PTR_ERR(data->clk);
		if (err != -EPROBE_DEFER)
			dev_err(&pdev->dev, "Could not get clk: %d\n", err);
		return err;
	}

	err = clk_prepare_enable(data->clk);
	if (err)
		return err;

	rate = clk_get_rate(data->clk);
	if ((rate < 1920000) || (rate > 5000000))
		dev_warn(&pdev->dev,
			 "Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
			 data->clk, data->clk);

	/* register of thermal sensor and get info from DT */
	tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
					     &bcm2835_thermal_ops);
	if (IS_ERR(tz)) {
		err = PTR_ERR(tz);
		dev_err(&pdev->dev,
			"Failed to register the thermal device: %d\n",
			err);
		goto err_clk;
	}

	/*
	 * right now the FW does set up the HW-block, so we are not
	 * touching the configuration registers.
	 * But if the HW is not enabled, then set it up
	 * using "sane" values used by the firmware right now.
	 */
	val = readl(data->regs + BCM2835_TS_TSENSCTL);
	if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
		int trip_temp, offset, slope;

		slope = thermal_zone_get_slope(tz);
		offset = thermal_zone_get_offset(tz);
		/*
		 * For now we deal only with critical, otherwise
		 * would need to iterate
		 */
		err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
		if (err < 0) {
			dev_err(&pdev->dev,
				"Not able to read trip_temp: %d\n",
				err);
			goto err_tz;
		}

		/* set bandgap reference voltage and enable voltage regulator */
		val = (BCM2835_TS_TSENSCTL_CTRL_DEFAULT <<
		       BCM2835_TS_TSENSCTL_CTRL_SHIFT) |
		      BCM2835_TS_TSENSCTL_REGULEN;

		/* use the recommended reset duration */
		val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);

		/*  trip_adc value from info */
		val |= bcm2835_thermal_temp2adc(trip_temp,
						offset,
						slope)
			<< BCM2835_TS_TSENSCTL_THOLD_SHIFT;

		/* write the value back to the register as 2 steps */
		writel(val, data->regs + BCM2835_TS_TSENSCTL);
		val |= BCM2835_TS_TSENSCTL_RSTB;
		writel(val, data->regs + BCM2835_TS_TSENSCTL);
	}

	data->tz = tz;

	platform_set_drvdata(pdev, tz);

	bcm2835_thermal_debugfs(pdev);

	return 0;
err_tz:
	thermal_zone_of_sensor_unregister(&pdev->dev, tz);
err_clk:
	clk_disable_unprepare(data->clk);

	return err;
}