brintos

brintos / linux-shallow public Read only

0
0
Text · 3.2 KiB · d734b31 Raw
141 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Windfarm PowerMac thermal control.  MAX6690 sensor.4 *5 * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>6 */7#include <linux/types.h>8#include <linux/errno.h>9#include <linux/kernel.h>10#include <linux/init.h>11#include <linux/slab.h>12#include <linux/i2c.h>13 14#include <asm/pmac_low_i2c.h>15 16#include "windfarm.h"17 18#define VERSION "1.0"19 20/* This currently only exports the external temperature sensor,21   since that's all the control loops need. */22 23/* Some MAX6690 register numbers */24#define MAX6690_INTERNAL_TEMP	025#define MAX6690_EXTERNAL_TEMP	126 27struct wf_6690_sensor {28	struct i2c_client	*i2c;29	struct wf_sensor	sens;30};31 32#define wf_to_6690(x)	container_of((x), struct wf_6690_sensor, sens)33 34static int wf_max6690_get(struct wf_sensor *sr, s32 *value)35{36	struct wf_6690_sensor *max = wf_to_6690(sr);37	s32 data;38 39	if (max->i2c == NULL)40		return -ENODEV;41 42	/* chip gets initialized by firmware */43	data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP);44	if (data < 0)45		return data;46	*value = data << 16;47	return 0;48}49 50static void wf_max6690_release(struct wf_sensor *sr)51{52	struct wf_6690_sensor *max = wf_to_6690(sr);53 54	kfree(max);55}56 57static const struct wf_sensor_ops wf_max6690_ops = {58	.get_value	= wf_max6690_get,59	.release	= wf_max6690_release,60	.owner		= THIS_MODULE,61};62 63static int wf_max6690_probe(struct i2c_client *client)64{65	const char *name, *loc;66	struct wf_6690_sensor *max;67	int rc;68 69	loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL);70	if (!loc) {71		dev_warn(&client->dev, "Missing hwsensor-location property!\n");72		return -ENXIO;73	}74 75	/*76	 * We only expose the external temperature register for77	 * now as this is all we need for our control loops78	 */79	if (!strcmp(loc, "BACKSIDE") || !strcmp(loc, "SYS CTRLR AMBIENT"))80		name = "backside-temp";81	else if (!strcmp(loc, "NB Ambient"))82		name = "north-bridge-temp";83	else if (!strcmp(loc, "GPU Ambient"))84		name = "gpu-temp";85	else86		return -ENXIO;87 88	max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);89	if (max == NULL) {90		printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "91		       "no memory\n");92		return -ENOMEM;93	}94 95	max->i2c = client;96	max->sens.name = name;97	max->sens.ops = &wf_max6690_ops;98	i2c_set_clientdata(client, max);99 100	rc = wf_register_sensor(&max->sens);101	if (rc)102		kfree(max);103	return rc;104}105 106static void wf_max6690_remove(struct i2c_client *client)107{108	struct wf_6690_sensor *max = i2c_get_clientdata(client);109 110	max->i2c = NULL;111	wf_unregister_sensor(&max->sens);112}113 114static const struct i2c_device_id wf_max6690_id[] = {115	{ "MAC,max6690" },116	{ }117};118MODULE_DEVICE_TABLE(i2c, wf_max6690_id);119 120static const struct of_device_id wf_max6690_of_id[] = {121	{ .compatible = "max6690", },122	{ }123};124MODULE_DEVICE_TABLE(of, wf_max6690_of_id);125 126static struct i2c_driver wf_max6690_driver = {127	.driver = {128		.name		= "wf_max6690",129		.of_match_table = wf_max6690_of_id,130	},131	.probe		= wf_max6690_probe,132	.remove		= wf_max6690_remove,133	.id_table	= wf_max6690_id,134};135 136module_i2c_driver(wf_max6690_driver);137 138MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");139MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");140MODULE_LICENSE("GPL");141