brintos

brintos / linux-shallow public Read only

0
0
Text · 12.5 KiB · 4cdb108 Raw
482 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * A driver for the Integrated Circuits ICS932S4014 * Copyright (C) 2008 IBM5 *6 * Author: Darrick J. Wong <darrick.wong@oracle.com>7 */8 9#include <linux/module.h>10#include <linux/jiffies.h>11#include <linux/i2c.h>12#include <linux/err.h>13#include <linux/mutex.h>14#include <linux/delay.h>15#include <linux/log2.h>16#include <linux/slab.h>17 18/* Addresses to scan */19static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };20 21/* ICS932S401 registers */22#define ICS932S401_REG_CFG2			0x0123#define		ICS932S401_CFG1_SPREAD		0x0124#define ICS932S401_REG_CFG7			0x0625#define		ICS932S401_FS_MASK		0x0726#define	ICS932S401_REG_VENDOR_REV		0x0727#define		ICS932S401_VENDOR		128#define		ICS932S401_VENDOR_MASK		0x0F29#define		ICS932S401_REV			430#define		ICS932S401_REV_SHIFT		431#define ICS932S401_REG_DEVICE			0x0932#define		ICS932S401_DEVICE		1133#define	ICS932S401_REG_CTRL			0x0A34#define		ICS932S401_MN_ENABLED		0x8035#define		ICS932S401_CPU_ALT		0x0436#define		ICS932S401_SRC_ALT		0x0837#define ICS932S401_REG_CPU_M_CTRL		0x0B38#define		ICS932S401_M_MASK		0x3F39#define	ICS932S401_REG_CPU_N_CTRL		0x0C40#define	ICS932S401_REG_CPU_SPREAD1		0x0D41#define ICS932S401_REG_CPU_SPREAD2		0x0E42#define		ICS932S401_SPREAD_MASK		0x7FFF43#define ICS932S401_REG_SRC_M_CTRL		0x0F44#define ICS932S401_REG_SRC_N_CTRL		0x1045#define	ICS932S401_REG_SRC_SPREAD1		0x1146#define ICS932S401_REG_SRC_SPREAD2		0x1247#define ICS932S401_REG_CPU_DIVISOR		0x1348#define		ICS932S401_CPU_DIVISOR_SHIFT	449#define ICS932S401_REG_PCISRC_DIVISOR		0x1450#define		ICS932S401_SRC_DIVISOR_MASK	0x0F51#define		ICS932S401_PCI_DIVISOR_SHIFT	452 53/* Base clock is 14.318MHz */54#define BASE_CLOCK				1431855 56#define NUM_REGS				2157#define NUM_MIRRORED_REGS			1558 59static int regs_to_copy[NUM_MIRRORED_REGS] = {60	ICS932S401_REG_CFG2,61	ICS932S401_REG_CFG7,62	ICS932S401_REG_VENDOR_REV,63	ICS932S401_REG_DEVICE,64	ICS932S401_REG_CTRL,65	ICS932S401_REG_CPU_M_CTRL,66	ICS932S401_REG_CPU_N_CTRL,67	ICS932S401_REG_CPU_SPREAD1,68	ICS932S401_REG_CPU_SPREAD2,69	ICS932S401_REG_SRC_M_CTRL,70	ICS932S401_REG_SRC_N_CTRL,71	ICS932S401_REG_SRC_SPREAD1,72	ICS932S401_REG_SRC_SPREAD2,73	ICS932S401_REG_CPU_DIVISOR,74	ICS932S401_REG_PCISRC_DIVISOR,75};76 77/* How often do we reread sensors values? (In jiffies) */78#define SENSOR_REFRESH_INTERVAL	(2 * HZ)79 80/* How often do we reread sensor limit values? (In jiffies) */81#define LIMIT_REFRESH_INTERVAL	(60 * HZ)82 83struct ics932s401_data {84	struct attribute_group	attrs;85	struct mutex		lock;86	char			sensors_valid;87	unsigned long		sensors_last_updated;	/* In jiffies */88 89	u8			regs[NUM_REGS];90};91 92static int ics932s401_probe(struct i2c_client *client);93static int ics932s401_detect(struct i2c_client *client,94			  struct i2c_board_info *info);95static void ics932s401_remove(struct i2c_client *client);96 97static const struct i2c_device_id ics932s401_id[] = {98	{ "ics932s401" },99	{ }100};101MODULE_DEVICE_TABLE(i2c, ics932s401_id);102 103static struct i2c_driver ics932s401_driver = {104	.class		= I2C_CLASS_HWMON,105	.driver = {106		.name	= "ics932s401",107	},108	.probe		= ics932s401_probe,109	.remove		= ics932s401_remove,110	.id_table	= ics932s401_id,111	.detect		= ics932s401_detect,112	.address_list	= normal_i2c,113};114 115static struct ics932s401_data *ics932s401_update_device(struct device *dev)116{117	struct i2c_client *client = to_i2c_client(dev);118	struct ics932s401_data *data = i2c_get_clientdata(client);119	unsigned long local_jiffies = jiffies;120	int i, temp;121 122	mutex_lock(&data->lock);123	if (time_before(local_jiffies, data->sensors_last_updated +124		SENSOR_REFRESH_INTERVAL)125		&& data->sensors_valid)126		goto out;127 128	/*129	 * Each register must be read as a word and then right shifted 8 bits.130	 * Not really sure why this is; setting the "byte count programming"131	 * register to 1 does not fix this problem.132	 */133	for (i = 0; i < NUM_MIRRORED_REGS; i++) {134		temp = i2c_smbus_read_word_data(client, regs_to_copy[i]);135		if (temp < 0)136			temp = 0;137		data->regs[regs_to_copy[i]] = temp >> 8;138	}139 140	data->sensors_last_updated = local_jiffies;141	data->sensors_valid = 1;142 143out:144	mutex_unlock(&data->lock);145	return data;146}147 148static ssize_t show_spread_enabled(struct device *dev,149				   struct device_attribute *devattr,150				   char *buf)151{152	struct ics932s401_data *data = ics932s401_update_device(dev);153 154	if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)155		return sprintf(buf, "1\n");156 157	return sprintf(buf, "0\n");158}159 160/* bit to cpu khz map */161static const int fs_speeds[] = {162	266666,163	133333,164	200000,165	166666,166	333333,167	100000,168	400000,169	0,170};171 172/* clock divisor map */173static const int divisors[] = {2, 3, 5, 15, 4, 6, 10, 30, 8, 12, 20, 60, 16,174			       24, 40, 120};175 176/* Calculate CPU frequency from the M/N registers. */177static int calculate_cpu_freq(struct ics932s401_data *data)178{179	int m, n, freq;180 181	m = data->regs[ICS932S401_REG_CPU_M_CTRL] & ICS932S401_M_MASK;182	n = data->regs[ICS932S401_REG_CPU_N_CTRL];183 184	/* Pull in bits 8 & 9 from the M register */185	n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x80) << 1;186	n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x40) << 3;187 188	freq = BASE_CLOCK * (n + 8) / (m + 2);189	freq /= divisors[data->regs[ICS932S401_REG_CPU_DIVISOR] >>190			 ICS932S401_CPU_DIVISOR_SHIFT];191 192	return freq;193}194 195static ssize_t show_cpu_clock(struct device *dev,196			      struct device_attribute *devattr,197			      char *buf)198{199	struct ics932s401_data *data = ics932s401_update_device(dev);200 201	return sprintf(buf, "%d\n", calculate_cpu_freq(data));202}203 204static ssize_t show_cpu_clock_sel(struct device *dev,205				  struct device_attribute *devattr,206				  char *buf)207{208	struct ics932s401_data *data = ics932s401_update_device(dev);209	int freq;210 211	if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)212		freq = calculate_cpu_freq(data);213	else {214		/* Freq is neatly wrapped up for us */215		int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK;216 217		freq = fs_speeds[fid];218		if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) {219			switch (freq) {220			case 166666:221				freq = 160000;222				break;223			case 333333:224				freq = 320000;225				break;226			}227		}228	}229 230	return sprintf(buf, "%d\n", freq);231}232 233/* Calculate SRC frequency from the M/N registers. */234static int calculate_src_freq(struct ics932s401_data *data)235{236	int m, n, freq;237 238	m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;239	n = data->regs[ICS932S401_REG_SRC_N_CTRL];240 241	/* Pull in bits 8 & 9 from the M register */242	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;243	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;244 245	freq = BASE_CLOCK * (n + 8) / (m + 2);246	freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] &247			 ICS932S401_SRC_DIVISOR_MASK];248 249	return freq;250}251 252static ssize_t show_src_clock(struct device *dev,253			      struct device_attribute *devattr,254			      char *buf)255{256	struct ics932s401_data *data = ics932s401_update_device(dev);257 258	return sprintf(buf, "%d\n", calculate_src_freq(data));259}260 261static ssize_t show_src_clock_sel(struct device *dev,262				  struct device_attribute *devattr,263				  char *buf)264{265	struct ics932s401_data *data = ics932s401_update_device(dev);266	int freq;267 268	if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)269		freq = calculate_src_freq(data);270	else271		/* Freq is neatly wrapped up for us */272		if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT &&273		    data->regs[ICS932S401_REG_CTRL] & ICS932S401_SRC_ALT)274			freq = 96000;275		else276			freq = 100000;277 278	return sprintf(buf, "%d\n", freq);279}280 281/* Calculate PCI frequency from the SRC M/N registers. */282static int calculate_pci_freq(struct ics932s401_data *data)283{284	int m, n, freq;285 286	m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;287	n = data->regs[ICS932S401_REG_SRC_N_CTRL];288 289	/* Pull in bits 8 & 9 from the M register */290	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;291	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;292 293	freq = BASE_CLOCK * (n + 8) / (m + 2);294	freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] >>295			 ICS932S401_PCI_DIVISOR_SHIFT];296 297	return freq;298}299 300static ssize_t show_pci_clock(struct device *dev,301			      struct device_attribute *devattr,302			      char *buf)303{304	struct ics932s401_data *data = ics932s401_update_device(dev);305 306	return sprintf(buf, "%d\n", calculate_pci_freq(data));307}308 309static ssize_t show_pci_clock_sel(struct device *dev,310				  struct device_attribute *devattr,311				  char *buf)312{313	struct ics932s401_data *data = ics932s401_update_device(dev);314	int freq;315 316	if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)317		freq = calculate_pci_freq(data);318	else319		freq = 33333;320 321	return sprintf(buf, "%d\n", freq);322}323 324static ssize_t show_value(struct device *dev,325			  struct device_attribute *devattr,326			  char *buf);327 328static ssize_t show_spread(struct device *dev,329			   struct device_attribute *devattr,330			   char *buf);331 332static DEVICE_ATTR(spread_enabled, S_IRUGO, show_spread_enabled, NULL);333static DEVICE_ATTR(cpu_clock_selection, S_IRUGO, show_cpu_clock_sel, NULL);334static DEVICE_ATTR(cpu_clock, S_IRUGO, show_cpu_clock, NULL);335static DEVICE_ATTR(src_clock_selection, S_IRUGO, show_src_clock_sel, NULL);336static DEVICE_ATTR(src_clock, S_IRUGO, show_src_clock, NULL);337static DEVICE_ATTR(pci_clock_selection, S_IRUGO, show_pci_clock_sel, NULL);338static DEVICE_ATTR(pci_clock, S_IRUGO, show_pci_clock, NULL);339static DEVICE_ATTR(usb_clock, S_IRUGO, show_value, NULL);340static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL);341static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL);342static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL);343 344static struct attribute *ics932s401_attr[] = {345	&dev_attr_spread_enabled.attr,346	&dev_attr_cpu_clock_selection.attr,347	&dev_attr_cpu_clock.attr,348	&dev_attr_src_clock_selection.attr,349	&dev_attr_src_clock.attr,350	&dev_attr_pci_clock_selection.attr,351	&dev_attr_pci_clock.attr,352	&dev_attr_usb_clock.attr,353	&dev_attr_ref_clock.attr,354	&dev_attr_cpu_spread.attr,355	&dev_attr_src_spread.attr,356	NULL357};358 359static ssize_t show_value(struct device *dev,360			  struct device_attribute *devattr,361			  char *buf)362{363	int x;364 365	if (devattr == &dev_attr_usb_clock)366		x = 48000;367	else if (devattr == &dev_attr_ref_clock)368		x = BASE_CLOCK;369	else370		BUG();371 372	return sprintf(buf, "%d\n", x);373}374 375static ssize_t show_spread(struct device *dev,376			   struct device_attribute *devattr,377			   char *buf)378{379	struct ics932s401_data *data = ics932s401_update_device(dev);380	int reg;381	unsigned long val;382 383	if (!(data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD))384		return sprintf(buf, "0%%\n");385 386	if (devattr == &dev_attr_src_spread)387		reg = ICS932S401_REG_SRC_SPREAD1;388	else if (devattr == &dev_attr_cpu_spread)389		reg = ICS932S401_REG_CPU_SPREAD1;390	else391		BUG();392 393	val = data->regs[reg] | (data->regs[reg + 1] << 8);394	val &= ICS932S401_SPREAD_MASK;395 396	/* Scale 0..2^14 to -0.5. */397	val = 500000 * val / 16384;398	return sprintf(buf, "-0.%lu%%\n", val);399}400 401/* Return 0 if detection is successful, -ENODEV otherwise */402static int ics932s401_detect(struct i2c_client *client,403			  struct i2c_board_info *info)404{405	struct i2c_adapter *adapter = client->adapter;406	int vendor, device, revision;407 408	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))409		return -ENODEV;410 411	vendor = i2c_smbus_read_word_data(client, ICS932S401_REG_VENDOR_REV);412	vendor >>= 8;413	revision = vendor >> ICS932S401_REV_SHIFT;414	vendor &= ICS932S401_VENDOR_MASK;415	if (vendor != ICS932S401_VENDOR)416		return -ENODEV;417 418	device = i2c_smbus_read_word_data(client, ICS932S401_REG_DEVICE);419	device >>= 8;420	if (device != ICS932S401_DEVICE)421		return -ENODEV;422 423	if (revision != ICS932S401_REV)424		dev_info(&adapter->dev, "Unknown revision %d\n", revision);425 426	strscpy(info->type, "ics932s401", I2C_NAME_SIZE);427 428	return 0;429}430 431static int ics932s401_probe(struct i2c_client *client)432{433	struct ics932s401_data *data;434	int err;435 436	data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL);437	if (!data) {438		err = -ENOMEM;439		goto exit;440	}441 442	i2c_set_clientdata(client, data);443	mutex_init(&data->lock);444 445	dev_info(&client->dev, "%s chip found\n", client->name);446 447	/* Register sysfs hooks */448	data->attrs.attrs = ics932s401_attr;449	err = sysfs_create_group(&client->dev.kobj, &data->attrs);450	if (err)451		goto exit_free;452 453	return 0;454 455exit_free:456	kfree(data);457exit:458	return err;459}460 461static void ics932s401_remove(struct i2c_client *client)462{463	struct ics932s401_data *data = i2c_get_clientdata(client);464 465	sysfs_remove_group(&client->dev.kobj, &data->attrs);466	kfree(data);467}468 469module_i2c_driver(ics932s401_driver);470 471MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");472MODULE_DESCRIPTION("ICS932S401 driver");473MODULE_LICENSE("GPL");474 475/* IBM IntelliStation Z30 */476MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*");477MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*");478 479/* IBM x3650/x3550 */480MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650*");481MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550*");482