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 = devm_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; }
static int rockchip_thermal_register_sensor(struct platform_device *pdev, struct rockchip_thermal_data *thermal, struct rockchip_thermal_sensor *sensor, int id) { const struct rockchip_tsadc_chip *tsadc = thermal->chip; int error; tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs, thermal->tshut_temp); if (error) dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n", __func__, thermal->tshut_temp, error); sensor->thermal = thermal; sensor->id = id; sensor->tzd = devm_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; }
static int tsens_register(struct tsens_priv *priv) { int i; struct thermal_zone_device *tzd; for (i = 0; i < priv->num_sensors; i++) { priv->sensor[i].priv = priv; priv->sensor[i].id = i; tzd = devm_thermal_zone_of_sensor_register(priv->dev, i, &priv->sensor[i], &tsens_of_ops); if (IS_ERR(tzd)) continue; priv->sensor[i].tzd = tzd; if (priv->ops->enable) priv->ops->enable(priv, i); } return 0; }
static int tango_thermal_probe(struct platform_device *pdev) { struct resource *res; struct tango_thermal_priv *priv; struct thermal_zone_device *tzdev; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); priv->thresh_idx = IDX_MIN; writel(0, priv->base + TEMPSI_CFG); writel(CMD_ON, priv->base + TEMPSI_CMD); tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &ops); return PTR_ERR_OR_ZERO(tzdev); }
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 = devm_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 = devm_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); return ret; } return 0; }
static int max8973_thermal_init(struct max8973_chip *mchip) { struct thermal_zone_device *tzd; struct irq_data *irq_data; unsigned long irq_flags = 0; int ret; if (mchip->id != MAX77621) return 0; tzd = devm_thermal_zone_of_sensor_register(mchip->dev, 0, mchip, &max77621_tz_ops); if (IS_ERR(tzd)) { ret = PTR_ERR(tzd); dev_err(mchip->dev, "Failed to register thermal sensor: %d\n", ret); return ret; } if (mchip->irq <= 0) return 0; irq_data = irq_get_irq_data(mchip->irq); if (irq_data) irq_flags = irqd_get_trigger_type(irq_data); ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL, max8973_thermal_irq, IRQF_ONESHOT | IRQF_SHARED | irq_flags, dev_name(mchip->dev), mchip); if (ret < 0) { dev_err(mchip->dev, "Failed to request irq %d, %d\n", mchip->irq, ret); return ret; } return 0; }
static int sun4i_ts_probe(struct platform_device *pdev) { struct sun4i_ts_data *ts; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device *hwmon; int error; u32 reg; bool ts_attached; u32 tp_sensitive_adjust = 15; u32 filter_type = 1; ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); if (!ts) return -ENOMEM; ts->dev = dev; ts->ignore_fifo_data = true; ts->temp_data = -1; if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) { /* Allwinner SDK has temperature (C) = (value / 6) - 271 */ ts->temp_offset = 271000; ts->temp_step = 167; } else if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) { /* * The A10 temperature sensor has quite a wide spread, these * parameters are based on the averaging of the calibration * results of 4 completely different boards, with a spread of * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331. */ ts->temp_offset = 257000; ts->temp_step = 133; } else { /* * The user manuals do not contain the formula for calculating * the temperature. The formula used here is from the AXP209, * which is designed by X-Powers, an affiliate of Allwinner: * * temperature (C) = (value * 0.1) - 144.7 * * Allwinner does not have any documentation whatsoever for * this hardware. Moreover, it is claimed that the sensor * is inaccurate and cannot work properly. */ ts->temp_offset = 144700; ts->temp_step = 100; } ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); if (ts_attached) { ts->input = devm_input_allocate_device(dev); if (!ts->input) return -ENOMEM; ts->input->name = pdev->name; ts->input->phys = "sun4i_ts/input0"; ts->input->open = sun4i_ts_open; ts->input->close = sun4i_ts_close; ts->input->id.bustype = BUS_HOST; ts->input->id.vendor = 0x0001; ts->input->id.product = 0x0001; ts->input->id.version = 0x0100; ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); __set_bit(BTN_TOUCH, ts->input->keybit); input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); input_set_drvdata(ts->input, ts); } ts->base = devm_ioremap_resource(dev, platform_get_resource(pdev, IORESOURCE_MEM, 0)); if (IS_ERR(ts->base)) return PTR_ERR(ts->base); ts->irq = platform_get_irq(pdev, 0); error = devm_request_irq(dev, ts->irq, sun4i_ts_irq, 0, "sun4i-ts", ts); if (error) return error; /* * Select HOSC clk, clkin = clk / 6, adc samplefreq = clkin / 8192, * t_acq = clkin / (16 * 64) */ writel(ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63), ts->base + TP_CTRL0); /* * tp_sensitive_adjust is an optional property * tp_mode = 0 : only x and y coordinates, as we don't use dual touch */ of_property_read_u32(np, "allwinner,tp-sensitive-adjust", &tp_sensitive_adjust); writel(TP_SENSITIVE_ADJUST(tp_sensitive_adjust) | TP_MODE_SELECT(0), ts->base + TP_CTRL2); /* * Enable median and averaging filter, optional property for * filter type. */ of_property_read_u32(np, "allwinner,filter-type", &filter_type); writel(FILTER_EN(1) | FILTER_TYPE(filter_type), ts->base + TP_CTRL3); /* Enable temperature measurement, period 1953 (2 seconds) */ writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR); /* * Set stylus up debounce to aprox 10 ms, enable debounce, and * finally enable tp mode. */ reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1); if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) reg |= SUN6I_TP_MODE_EN(1); else reg |= TP_MODE_EN(1); writel(reg, ts->base + TP_CTRL1); /* * The thermal core does not register hwmon devices for DT-based * thermal zone sensors, such as this one. */ hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", ts, sun4i_ts_groups); if (IS_ERR(hwmon)) return PTR_ERR(hwmon); devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, &sun4i_ts_tz_ops); writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); if (ts_attached) { error = input_register_device(ts->input); if (error) { writel(0, ts->base + TP_INT_FIFOC); return error; } } platform_set_drvdata(pdev, ts); return 0; }
static int uniphier_tm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct regmap *regmap; struct device_node *parent; struct uniphier_tm_dev *tdev; const struct thermal_trip *trips; int i, ret, irq, ntrips, crit_temp = INT_MAX; tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); if (!tdev) return -ENOMEM; tdev->dev = dev; tdev->data = of_device_get_match_data(dev); if (WARN_ON(!tdev->data)) return -EINVAL; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; /* get regmap from syscon node */ parent = of_get_parent(dev->of_node); /* parent should be syscon node */ regmap = syscon_node_to_regmap(parent); of_node_put(parent); if (IS_ERR(regmap)) { dev_err(dev, "failed to get regmap (error %ld)\n", PTR_ERR(regmap)); return PTR_ERR(regmap); } tdev->regmap = regmap; ret = uniphier_tm_initialize_sensor(tdev); if (ret) { dev_err(dev, "failed to initialize sensor\n"); return ret; } ret = devm_request_threaded_irq(dev, irq, uniphier_tm_alarm_irq, uniphier_tm_alarm_irq_thread, 0, "thermal", tdev); if (ret) return ret; platform_set_drvdata(pdev, tdev); tdev->tz_dev = devm_thermal_zone_of_sensor_register(dev, 0, tdev, &uniphier_of_thermal_ops); if (IS_ERR(tdev->tz_dev)) { dev_err(dev, "failed to register sensor device\n"); return PTR_ERR(tdev->tz_dev); } /* get trip points */ trips = of_thermal_get_trip_points(tdev->tz_dev); ntrips = of_thermal_get_ntrips(tdev->tz_dev); if (ntrips > ALERT_CH_NUM) { dev_err(dev, "thermal zone has too many trips\n"); return -E2BIG; } /* set alert temperatures */ for (i = 0; i < ntrips; i++) { if (trips[i].type == THERMAL_TRIP_CRITICAL && trips[i].temperature < crit_temp) crit_temp = trips[i].temperature; uniphier_tm_set_alert(tdev, i, trips[i].temperature); tdev->alert_en[i] = true; } if (crit_temp > CRITICAL_TEMP_LIMIT) { dev_err(dev, "critical trip is over limit(>%d), or not set\n", CRITICAL_TEMP_LIMIT); return -EINVAL; } uniphier_tm_enable_sensor(tdev); return 0; }
static int tmp102_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct device *hwmon_dev; struct tmp102 *tmp102; unsigned int regval; int err; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_err(dev, "adapter doesn't support SMBus word transactions\n"); return -ENODEV; } tmp102 = devm_kzalloc(dev, sizeof(*tmp102), GFP_KERNEL); if (!tmp102) return -ENOMEM; i2c_set_clientdata(client, tmp102); tmp102->regmap = devm_regmap_init_i2c(client, &tmp102_regmap_config); if (IS_ERR(tmp102->regmap)) return PTR_ERR(tmp102->regmap); err = regmap_read(tmp102->regmap, TMP102_CONF_REG, ®val); if (err < 0) { dev_err(dev, "error reading config register\n"); return err; } if ((regval & ~TMP102_CONFREG_MASK) != (TMP102_CONF_R0 | TMP102_CONF_R1)) { dev_err(dev, "unexpected config register value\n"); return -ENODEV; } tmp102->config_orig = regval; devm_add_action(dev, tmp102_restore_config, tmp102); regval &= ~TMP102_CONFIG_CLEAR; regval |= TMP102_CONFIG_SET; err = regmap_write(tmp102->regmap, TMP102_CONF_REG, regval); if (err < 0) { dev_err(dev, "error writing config register\n"); return err; } tmp102->ready_time = jiffies; if (tmp102->config_orig & TMP102_CONF_SD) { /* * Mark that we are not ready with data until the first * conversion is complete */ tmp102->ready_time += msecs_to_jiffies(CONVERSION_TIME_MS); } hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, tmp102, tmp102_groups); if (IS_ERR(hwmon_dev)) { dev_dbg(dev, "unable to register hwmon device\n"); return PTR_ERR(hwmon_dev); } devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, &tmp102_of_thermal_ops); dev_info(dev, "initialized\n"); return 0; }
static int rcar_gen3_thermal_probe(struct platform_device *pdev) { struct rcar_gen3_thermal_priv *priv; struct device *dev = &pdev->dev; struct resource *res; struct thermal_zone_device *zone; int ret, irq, i; char *irqname; /* default values if FUSEs are missing */ /* TODO: Read values from hardware on supported platforms */ int ptat[3] = { 2631, 1509, 435 }; int thcode[TSC_MAX_NUM][3] = { { 3397, 2800, 2221 }, { 3393, 2795, 2216 }, { 3389, 2805, 2237 }, }; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->thermal_init = rcar_gen3_thermal_init; if (soc_device_match(r8a7795es1)) priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1; spin_lock_init(&priv->lock); platform_set_drvdata(pdev, priv); /* * Request 2 (of the 3 possible) IRQs, the driver only needs to * to trigger on the low and high trip points of the current * temp window at this point. */ for (i = 0; i < 2; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) return irq; irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d", dev_name(dev), i); if (!irqname) return -ENOMEM; ret = devm_request_threaded_irq(dev, irq, rcar_gen3_thermal_irq, rcar_gen3_thermal_irq_thread, IRQF_SHARED, irqname, priv); if (ret) return ret; } pm_runtime_enable(dev); pm_runtime_get_sync(dev); for (i = 0; i < TSC_MAX_NUM; i++) { struct rcar_gen3_thermal_tsc *tsc; res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (!res) break; tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); if (!tsc) { ret = -ENOMEM; goto error_unregister; } tsc->base = devm_ioremap_resource(dev, res); if (IS_ERR(tsc->base)) { ret = PTR_ERR(tsc->base); goto error_unregister; } priv->tscs[i] = tsc; priv->thermal_init(tsc); rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, &rcar_gen3_tz_of_ops); if (IS_ERR(zone)) { dev_err(dev, "Can't register thermal zone\n"); ret = PTR_ERR(zone); goto error_unregister; } tsc->zone = zone; ret = of_thermal_get_ntrips(tsc->zone); if (ret < 0) goto error_unregister; dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret); } priv->num_tscs = i; if (!priv->num_tscs) { ret = -ENODEV; goto error_unregister; } rcar_thermal_irq_set(priv, true); return 0; error_unregister: rcar_gen3_thermal_remove(pdev); return ret; }
static int tegra_bpmp_thermal_probe(struct platform_device *pdev) { struct tegra_bpmp *bpmp = dev_get_drvdata(pdev->dev.parent); struct tegra_bpmp_thermal *tegra; struct thermal_zone_device *tzd; unsigned int i, max_num_zones; int err; tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); if (!tegra) return -ENOMEM; tegra->dev = &pdev->dev; tegra->bpmp = bpmp; err = tegra_bpmp_thermal_get_num_zones(bpmp, &max_num_zones); if (err) { dev_err(&pdev->dev, "failed to get the number of zones: %d\n", err); return err; } tegra->zones = devm_kcalloc(&pdev->dev, max_num_zones, sizeof(*tegra->zones), GFP_KERNEL); if (!tegra->zones) return -ENOMEM; for (i = 0; i < max_num_zones; ++i) { struct tegra_bpmp_thermal_zone *zone; int temp; zone = devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL); if (!zone) return -ENOMEM; zone->idx = i; zone->tegra = tegra; err = tegra_bpmp_thermal_get_temp(zone, &temp); if (err < 0) { devm_kfree(&pdev->dev, zone); continue; } tzd = devm_thermal_zone_of_sensor_register( &pdev->dev, i, zone, &tegra_bpmp_of_thermal_ops); if (IS_ERR(tzd)) { if (PTR_ERR(tzd) == -EPROBE_DEFER) return -EPROBE_DEFER; devm_kfree(&pdev->dev, zone); continue; } zone->tzd = tzd; INIT_WORK(&zone->tz_device_update_work, tz_device_update_work_fn); tegra->zones[tegra->num_zones++] = zone; } err = tegra_bpmp_request_mrq(bpmp, MRQ_THERMAL, bpmp_mrq_thermal, tegra); if (err) { dev_err(&pdev->dev, "failed to register mrq handler: %d\n", err); return err; } platform_set_drvdata(pdev, tegra); return 0; }