root/drivers/macintosh/windfarm_max6690_sensor.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wf_max6690_get
  2. wf_max6690_release
  3. wf_max6690_probe
  4. wf_max6690_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   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 #include <asm/prom.h>
  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   0
  25 #define MAX6690_EXTERNAL_TEMP   1
  26 
  27 struct 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 
  34 static 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 
  50 static 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 
  57 static 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 
  63 static int wf_max6690_probe(struct i2c_client *client,
  64                             const struct i2c_device_id *id)
  65 {
  66         const char *name, *loc;
  67         struct wf_6690_sensor *max;
  68         int rc;
  69 
  70         loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL);
  71         if (!loc) {
  72                 dev_warn(&client->dev, "Missing hwsensor-location property!\n");
  73                 return -ENXIO;
  74         }
  75 
  76         /*
  77          * We only expose the external temperature register for
  78          * now as this is all we need for our control loops
  79          */
  80         if (!strcmp(loc, "BACKSIDE") || !strcmp(loc, "SYS CTRLR AMBIENT"))
  81                 name = "backside-temp";
  82         else if (!strcmp(loc, "NB Ambient"))
  83                 name = "north-bridge-temp";
  84         else if (!strcmp(loc, "GPU Ambient"))
  85                 name = "gpu-temp";
  86         else
  87                 return -ENXIO;
  88 
  89         max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
  90         if (max == NULL) {
  91                 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
  92                        "no memory\n");
  93                 return -ENOMEM;
  94         }
  95 
  96         max->i2c = client;
  97         max->sens.name = name;
  98         max->sens.ops = &wf_max6690_ops;
  99         i2c_set_clientdata(client, max);
 100 
 101         rc = wf_register_sensor(&max->sens);
 102         if (rc)
 103                 kfree(max);
 104         return rc;
 105 }
 106 
 107 static int wf_max6690_remove(struct i2c_client *client)
 108 {
 109         struct wf_6690_sensor *max = i2c_get_clientdata(client);
 110 
 111         max->i2c = NULL;
 112         wf_unregister_sensor(&max->sens);
 113 
 114         return 0;
 115 }
 116 
 117 static const struct i2c_device_id wf_max6690_id[] = {
 118         { "MAC,max6690", 0 },
 119         { }
 120 };
 121 MODULE_DEVICE_TABLE(i2c, wf_max6690_id);
 122 
 123 static const struct of_device_id wf_max6690_of_id[] = {
 124         { .compatible = "max6690", },
 125         { }
 126 };
 127 MODULE_DEVICE_TABLE(of, wf_max6690_of_id);
 128 
 129 static struct i2c_driver wf_max6690_driver = {
 130         .driver = {
 131                 .name           = "wf_max6690",
 132                 .of_match_table = wf_max6690_of_id,
 133         },
 134         .probe          = wf_max6690_probe,
 135         .remove         = wf_max6690_remove,
 136         .id_table       = wf_max6690_id,
 137 };
 138 
 139 module_i2c_driver(wf_max6690_driver);
 140 
 141 MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
 142 MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");
 143 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */