linux/drivers/hwmon/atxp1.c
<<
>>
Prefs
   1/*
   2 * atxp1.c - kernel module for setting CPU VID and general purpose
   3 *           I/Os using the Attansic ATXP1 chip.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * The ATXP1 can reside on I2C addresses 0x37 or 0x4e. The chip is
  16 * not auto-detected by the driver and must be instantiated explicitly.
  17 * See Documentation/i2c/instantiating-devices for more information.
  18 */
  19
  20#include <linux/kernel.h>
  21#include <linux/init.h>
  22#include <linux/module.h>
  23#include <linux/jiffies.h>
  24#include <linux/i2c.h>
  25#include <linux/hwmon.h>
  26#include <linux/hwmon-vid.h>
  27#include <linux/err.h>
  28#include <linux/mutex.h>
  29#include <linux/sysfs.h>
  30#include <linux/slab.h>
  31
  32MODULE_LICENSE("GPL");
  33MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
  34MODULE_VERSION("0.6.3");
  35MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
  36
  37#define ATXP1_VID       0x00
  38#define ATXP1_CVID      0x01
  39#define ATXP1_GPIO1     0x06
  40#define ATXP1_GPIO2     0x0a
  41#define ATXP1_VIDENA    0x20
  42#define ATXP1_VIDMASK   0x1f
  43#define ATXP1_GPIO1MASK 0x0f
  44
  45struct atxp1_data {
  46        struct i2c_client *client;
  47        struct mutex update_lock;
  48        unsigned long last_updated;
  49        u8 valid;
  50        struct {
  51                u8 vid;         /* VID output register */
  52                u8 cpu_vid; /* VID input from CPU */
  53                u8 gpio1;   /* General purpose I/O register 1 */
  54                u8 gpio2;   /* General purpose I/O register 2 */
  55        } reg;
  56        u8 vrm;                 /* Detected CPU VRM */
  57};
  58
  59static struct atxp1_data *atxp1_update_device(struct device *dev)
  60{
  61        struct atxp1_data *data = dev_get_drvdata(dev);
  62        struct i2c_client *client = data->client;
  63
  64        mutex_lock(&data->update_lock);
  65
  66        if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
  67
  68                /* Update local register data */
  69                data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID);
  70                data->reg.cpu_vid = i2c_smbus_read_byte_data(client,
  71                                                             ATXP1_CVID);
  72                data->reg.gpio1 = i2c_smbus_read_byte_data(client, ATXP1_GPIO1);
  73                data->reg.gpio2 = i2c_smbus_read_byte_data(client, ATXP1_GPIO2);
  74
  75                data->valid = 1;
  76        }
  77
  78        mutex_unlock(&data->update_lock);
  79
  80        return data;
  81}
  82
  83/* sys file functions for cpu0_vid */
  84static ssize_t cpu0_vid_show(struct device *dev,
  85                             struct device_attribute *attr, char *buf)
  86{
  87        int size;
  88        struct atxp1_data *data;
  89
  90        data = atxp1_update_device(dev);
  91
  92        size = sprintf(buf, "%d\n", vid_from_reg(data->reg.vid & ATXP1_VIDMASK,
  93                                                 data->vrm));
  94
  95        return size;
  96}
  97
  98static ssize_t cpu0_vid_store(struct device *dev,
  99                              struct device_attribute *attr, const char *buf,
 100                              size_t count)
 101{
 102        struct atxp1_data *data = atxp1_update_device(dev);
 103        struct i2c_client *client = data->client;
 104        int vid, cvid;
 105        unsigned long vcore;
 106        int err;
 107
 108        err = kstrtoul(buf, 10, &vcore);
 109        if (err)
 110                return err;
 111
 112        vcore /= 25;
 113        vcore *= 25;
 114
 115        /* Calculate VID */
 116        vid = vid_to_reg(vcore, data->vrm);
 117        if (vid < 0) {
 118                dev_err(dev, "VID calculation failed.\n");
 119                return vid;
 120        }
 121
 122        /*
 123         * If output enabled, use control register value.
 124         * Otherwise original CPU VID
 125         */
 126        if (data->reg.vid & ATXP1_VIDENA)
 127                cvid = data->reg.vid & ATXP1_VIDMASK;
 128        else
 129                cvid = data->reg.cpu_vid;
 130
 131        /* Nothing changed, aborting */
 132        if (vid == cvid)
 133                return count;
 134
 135        dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", (int)vcore, vid);
 136
 137        /* Write every 25 mV step to increase stability */
 138        if (cvid > vid) {
 139                for (; cvid >= vid; cvid--)
 140                        i2c_smbus_write_byte_data(client,
 141                                                ATXP1_VID, cvid | ATXP1_VIDENA);
 142        } else {
 143                for (; cvid <= vid; cvid++)
 144                        i2c_smbus_write_byte_data(client,
 145                                                ATXP1_VID, cvid | ATXP1_VIDENA);
 146        }
 147
 148        data->valid = 0;
 149
 150        return count;
 151}
 152
 153/*
 154 * CPU core reference voltage
 155 * unit: millivolt
 156 */
 157static DEVICE_ATTR_RW(cpu0_vid);
 158
 159/* sys file functions for GPIO1 */
 160static ssize_t gpio1_show(struct device *dev, struct device_attribute *attr,
 161                          char *buf)
 162{
 163        int size;
 164        struct atxp1_data *data;
 165
 166        data = atxp1_update_device(dev);
 167
 168        size = sprintf(buf, "0x%02x\n", data->reg.gpio1 & ATXP1_GPIO1MASK);
 169
 170        return size;
 171}
 172
 173static ssize_t gpio1_store(struct device *dev, struct device_attribute *attr,
 174                           const char *buf, size_t count)
 175{
 176        struct atxp1_data *data = atxp1_update_device(dev);
 177        struct i2c_client *client = data->client;
 178        unsigned long value;
 179        int err;
 180
 181        err = kstrtoul(buf, 16, &value);
 182        if (err)
 183                return err;
 184
 185        value &= ATXP1_GPIO1MASK;
 186
 187        if (value != (data->reg.gpio1 & ATXP1_GPIO1MASK)) {
 188                dev_info(dev, "Writing 0x%x to GPIO1.\n", (unsigned int)value);
 189
 190                i2c_smbus_write_byte_data(client, ATXP1_GPIO1, value);
 191
 192                data->valid = 0;
 193        }
 194
 195        return count;
 196}
 197
 198/*
 199 * GPIO1 data register
 200 * unit: Four bit as hex (e.g. 0x0f)
 201 */
 202static DEVICE_ATTR_RW(gpio1);
 203
 204/* sys file functions for GPIO2 */
 205static ssize_t gpio2_show(struct device *dev, struct device_attribute *attr,
 206                          char *buf)
 207{
 208        int size;
 209        struct atxp1_data *data;
 210
 211        data = atxp1_update_device(dev);
 212
 213        size = sprintf(buf, "0x%02x\n", data->reg.gpio2);
 214
 215        return size;
 216}
 217
 218static ssize_t gpio2_store(struct device *dev, struct device_attribute *attr,
 219                           const char *buf, size_t count)
 220{
 221        struct atxp1_data *data = atxp1_update_device(dev);
 222        struct i2c_client *client = data->client;
 223        unsigned long value;
 224        int err;
 225
 226        err = kstrtoul(buf, 16, &value);
 227        if (err)
 228                return err;
 229        value &= 0xff;
 230
 231        if (value != data->reg.gpio2) {
 232                dev_info(dev, "Writing 0x%x to GPIO1.\n", (unsigned int)value);
 233
 234                i2c_smbus_write_byte_data(client, ATXP1_GPIO2, value);
 235
 236                data->valid = 0;
 237        }
 238
 239        return count;
 240}
 241
 242/*
 243 * GPIO2 data register
 244 * unit: Eight bit as hex (e.g. 0xff)
 245 */
 246static DEVICE_ATTR_RW(gpio2);
 247
 248static struct attribute *atxp1_attrs[] = {
 249        &dev_attr_gpio1.attr,
 250        &dev_attr_gpio2.attr,
 251        &dev_attr_cpu0_vid.attr,
 252        NULL
 253};
 254ATTRIBUTE_GROUPS(atxp1);
 255
 256static int atxp1_probe(struct i2c_client *client,
 257                       const struct i2c_device_id *id)
 258{
 259        struct device *dev = &client->dev;
 260        struct atxp1_data *data;
 261        struct device *hwmon_dev;
 262
 263        data = devm_kzalloc(dev, sizeof(struct atxp1_data), GFP_KERNEL);
 264        if (!data)
 265                return -ENOMEM;
 266
 267        /* Get VRM */
 268        data->vrm = vid_which_vrm();
 269        if (data->vrm != 90 && data->vrm != 91) {
 270                dev_err(dev, "atxp1: Not supporting VRM %d.%d\n",
 271                        data->vrm / 10, data->vrm % 10);
 272                return -ENODEV;
 273        }
 274
 275        data->client = client;
 276        mutex_init(&data->update_lock);
 277
 278        hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 279                                                           data,
 280                                                           atxp1_groups);
 281        if (IS_ERR(hwmon_dev))
 282                return PTR_ERR(hwmon_dev);
 283
 284        dev_info(dev, "Using VRM: %d.%d\n", data->vrm / 10, data->vrm % 10);
 285
 286        return 0;
 287};
 288
 289static const struct i2c_device_id atxp1_id[] = {
 290        { "atxp1", 0 },
 291        { }
 292};
 293MODULE_DEVICE_TABLE(i2c, atxp1_id);
 294
 295static struct i2c_driver atxp1_driver = {
 296        .class          = I2C_CLASS_HWMON,
 297        .driver = {
 298                .name   = "atxp1",
 299        },
 300        .probe          = atxp1_probe,
 301        .id_table       = atxp1_id,
 302};
 303
 304module_i2c_driver(atxp1_driver);
 305