linux-stable/drivers/hwmon/i5500_temp.c

149 lines
3.5 KiB
C
Raw Normal View History

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157 Based on 3 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version [author] [kishon] [vijay] [abraham] [i] [kishon]@[ti] [com] this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version [author] [graeme] [gregory] [gg]@[slimlogic] [co] [uk] [author] [kishon] [vijay] [abraham] [i] [kishon]@[ti] [com] [based] [on] [twl6030]_[usb] [c] [author] [hema] [hk] [hemahk]@[ti] [com] this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 1105 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070033.202006027@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-27 06:55:06 +00:00
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor
*
* Copyright (C) 2012, 2014 Jean Delvare <jdelvare@suse.de>
*/
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Register definitions from datasheet */
#define REG_TSTHRCATA 0xE2
#define REG_TSCTRL 0xE8
#define REG_TSTHRRPEX 0xEB
#define REG_TSTHRLO 0xEC
#define REG_TSTHRHI 0xEE
#define REG_CTHINT 0xF0
#define REG_TSFSC 0xF3
#define REG_CTSTS 0xF4
#define REG_TSTHRRQPI 0xF5
#define REG_CTCTRL 0xF7
#define REG_TSTIMER 0xF8
static umode_t i5500_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
int channel)
{
return 0444;
}
static int i5500_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
long *val)
{
struct pci_dev *pdev = to_pci_dev(dev->parent);
u16 tsthr;
s8 tsfsc;
u8 ctsts;
switch (type) {
case hwmon_temp:
switch (attr) {
/* Sensor resolution : 0.5 degree C */
case hwmon_temp_input:
pci_read_config_word(pdev, REG_TSTHRHI, &tsthr);
pci_read_config_byte(pdev, REG_TSFSC, &tsfsc);
*val = (tsthr - tsfsc) * 500;
return 0;
case hwmon_temp_max:
pci_read_config_word(pdev, REG_TSTHRHI, &tsthr);
*val = tsthr * 500;
return 0;
case hwmon_temp_max_hyst:
pci_read_config_word(pdev, REG_TSTHRLO, &tsthr);
*val = tsthr * 500;
return 0;
case hwmon_temp_crit:
pci_read_config_word(pdev, REG_TSTHRCATA, &tsthr);
*val = tsthr * 500;
return 0;
case hwmon_temp_max_alarm:
pci_read_config_byte(pdev, REG_CTSTS, &ctsts);
*val = !!(ctsts & BIT(1));
return 0;
case hwmon_temp_crit_alarm:
pci_read_config_byte(pdev, REG_CTSTS, &ctsts);
*val = !!(ctsts & BIT(0));
return 0;
default:
break;
}
break;
default:
break;
}
return -EOPNOTSUPP;
}
static const struct hwmon_ops i5500_ops = {
.is_visible = i5500_is_visible,
.read = i5500_read,
};
static const struct hwmon_channel_info *i5500_info[] = {
HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
HWMON_CHANNEL_INFO(temp,
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | HWMON_T_CRIT |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM
),
NULL
};
static const struct hwmon_chip_info i5500_chip_info = {
.ops = &i5500_ops,
.info = i5500_info,
};
static const struct pci_device_id i5500_temp_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) },
{ 0 },
};
MODULE_DEVICE_TABLE(pci, i5500_temp_ids);
static int i5500_temp_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int err;
struct device *hwmon_dev;
u32 tstimer;
s8 tsfsc;
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "Failed to enable device\n");
return err;
}
pci_read_config_byte(pdev, REG_TSFSC, &tsfsc);
pci_read_config_dword(pdev, REG_TSTIMER, &tstimer);
if (tsfsc == 0x7F && tstimer == 0x07D30D40) {
dev_notice(&pdev->dev, "Sensor seems to be disabled\n");
return -ENODEV;
}
hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, "intel5500", NULL,
&i5500_chip_info, NULL);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static struct pci_driver i5500_temp_driver = {
.name = "i5500_temp",
.id_table = i5500_temp_ids,
.probe = i5500_temp_probe,
};
module_pci_driver(i5500_temp_driver);
MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver");
MODULE_LICENSE("GPL");