linux/drivers/hwmon/ads7871.c
<<
>>
Prefs
   1/*
   2 *  ads7871 - driver for TI ADS7871 A/D converter
   3 *
   4 *  Copyright (c) 2010 Paul Thomas <pthomas8589@gmail.com>
   5 *
   6 *  This program is distributed in the hope that it will be useful,
   7 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   8 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   9 *  GNU General Public License for more details.
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License version 2 or
  13 *  later as publishhed by the Free Software Foundation.
  14 *
  15 *      You need to have something like this in struct spi_board_info
  16 *      {
  17 *              .modalias       = "ads7871",
  18 *              .max_speed_hz   = 2*1000*1000,
  19 *              .chip_select    = 0,
  20 *              .bus_num        = 1,
  21 *      },
  22 */
  23
  24/*From figure 18 in the datasheet*/
  25/*Register addresses*/
  26#define REG_LS_BYTE     0 /*A/D Output Data, LS Byte*/
  27#define REG_MS_BYTE     1 /*A/D Output Data, MS Byte*/
  28#define REG_PGA_VALID   2 /*PGA Valid Register*/
  29#define REG_AD_CONTROL  3 /*A/D Control Register*/
  30#define REG_GAIN_MUX    4 /*Gain/Mux Register*/
  31#define REG_IO_STATE    5 /*Digital I/O State Register*/
  32#define REG_IO_CONTROL  6 /*Digital I/O Control Register*/
  33#define REG_OSC_CONTROL 7 /*Rev/Oscillator Control Register*/
  34#define REG_SER_CONTROL 24 /*Serial Interface Control Register*/
  35#define REG_ID          31 /*ID Register*/
  36
  37/*
  38 * From figure 17 in the datasheet
  39 * These bits get ORed with the address to form
  40 * the instruction byte
  41 */
  42/*Instruction Bit masks*/
  43#define INST_MODE_bm    (1<<7)
  44#define INST_READ_bm    (1<<6)
  45#define INST_16BIT_bm   (1<<5)
  46
  47/*From figure 18 in the datasheet*/
  48/*bit masks for Rev/Oscillator Control Register*/
  49#define MUX_CNV_bv      7
  50#define MUX_CNV_bm      (1<<MUX_CNV_bv)
  51#define MUX_M3_bm       (1<<3) /*M3 selects single ended*/
  52#define MUX_G_bv        4 /*allows for reg = (gain << MUX_G_bv) | ...*/
  53
  54/*From figure 18 in the datasheet*/
  55/*bit masks for Rev/Oscillator Control Register*/
  56#define OSC_OSCR_bm     (1<<5)
  57#define OSC_OSCE_bm     (1<<4)
  58#define OSC_REFE_bm     (1<<3)
  59#define OSC_BUFE_bm     (1<<2)
  60#define OSC_R2V_bm      (1<<1)
  61#define OSC_RBG_bm      (1<<0)
  62
  63#include <linux/module.h>
  64#include <linux/init.h>
  65#include <linux/spi/spi.h>
  66#include <linux/hwmon.h>
  67#include <linux/hwmon-sysfs.h>
  68#include <linux/err.h>
  69#include <linux/mutex.h>
  70#include <linux/delay.h>
  71
  72#define DEVICE_NAME     "ads7871"
  73
  74struct ads7871_data {
  75        struct device   *hwmon_dev;
  76        struct mutex    update_lock;
  77};
  78
  79static int ads7871_read_reg8(struct spi_device *spi, int reg)
  80{
  81        int ret;
  82        reg = reg | INST_READ_bm;
  83        ret = spi_w8r8(spi, reg);
  84        return ret;
  85}
  86
  87static int ads7871_read_reg16(struct spi_device *spi, int reg)
  88{
  89        int ret;
  90        reg = reg | INST_READ_bm | INST_16BIT_bm;
  91        ret = spi_w8r16(spi, reg);
  92        return ret;
  93}
  94
  95static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val)
  96{
  97        u8 tmp[2] = {reg, val};
  98        return spi_write(spi, tmp, sizeof(tmp));
  99}
 100
 101static ssize_t show_voltage(struct device *dev,
 102                struct device_attribute *da, char *buf)
 103{
 104        struct spi_device *spi = to_spi_device(dev);
 105        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 106        int ret, val, i = 0;
 107        uint8_t channel, mux_cnv;
 108
 109        channel = attr->index;
 110        /*
 111         * TODO: add support for conversions
 112         * other than single ended with a gain of 1
 113         */
 114        /*MUX_M3_bm forces single ended*/
 115        /*This is also where the gain of the PGA would be set*/
 116        ads7871_write_reg8(spi, REG_GAIN_MUX,
 117                (MUX_CNV_bm | MUX_M3_bm | channel));
 118
 119        ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
 120        mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv);
 121        /*
 122         * on 400MHz arm9 platform the conversion
 123         * is already done when we do this test
 124         */
 125        while ((i < 2) && mux_cnv) {
 126                i++;
 127                ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
 128                mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv);
 129                msleep_interruptible(1);
 130        }
 131
 132        if (mux_cnv == 0) {
 133                val = ads7871_read_reg16(spi, REG_LS_BYTE);
 134                /*result in volts*10000 = (val/8192)*2.5*10000*/
 135                val = ((val>>2) * 25000) / 8192;
 136                return sprintf(buf, "%d\n", val);
 137        } else {
 138                return -1;
 139        }
 140}
 141
 142static ssize_t ads7871_show_name(struct device *dev,
 143                                 struct device_attribute *devattr, char *buf)
 144{
 145        return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
 146}
 147
 148static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0);
 149static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1);
 150static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2);
 151static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 3);
 152static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 4);
 153static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5);
 154static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6);
 155static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7);
 156
 157static DEVICE_ATTR(name, S_IRUGO, ads7871_show_name, NULL);
 158
 159static struct attribute *ads7871_attributes[] = {
 160        &sensor_dev_attr_in0_input.dev_attr.attr,
 161        &sensor_dev_attr_in1_input.dev_attr.attr,
 162        &sensor_dev_attr_in2_input.dev_attr.attr,
 163        &sensor_dev_attr_in3_input.dev_attr.attr,
 164        &sensor_dev_attr_in4_input.dev_attr.attr,
 165        &sensor_dev_attr_in5_input.dev_attr.attr,
 166        &sensor_dev_attr_in6_input.dev_attr.attr,
 167        &sensor_dev_attr_in7_input.dev_attr.attr,
 168        &dev_attr_name.attr,
 169        NULL
 170};
 171
 172static const struct attribute_group ads7871_group = {
 173        .attrs = ads7871_attributes,
 174};
 175
 176static int __devinit ads7871_probe(struct spi_device *spi)
 177{
 178        int ret, err;
 179        uint8_t val;
 180        struct ads7871_data *pdata;
 181
 182        dev_dbg(&spi->dev, "probe\n");
 183
 184        /* Configure the SPI bus */
 185        spi->mode = (SPI_MODE_0);
 186        spi->bits_per_word = 8;
 187        spi_setup(spi);
 188
 189        ads7871_write_reg8(spi, REG_SER_CONTROL, 0);
 190        ads7871_write_reg8(spi, REG_AD_CONTROL, 0);
 191
 192        val = (OSC_OSCR_bm | OSC_OSCE_bm | OSC_REFE_bm | OSC_BUFE_bm);
 193        ads7871_write_reg8(spi, REG_OSC_CONTROL, val);
 194        ret = ads7871_read_reg8(spi, REG_OSC_CONTROL);
 195
 196        dev_dbg(&spi->dev, "REG_OSC_CONTROL write:%x, read:%x\n", val, ret);
 197        /*
 198         * because there is no other error checking on an SPI bus
 199         * we need to make sure we really have a chip
 200         */
 201        if (val != ret)
 202                return -ENODEV;
 203
 204        pdata = devm_kzalloc(&spi->dev, sizeof(struct ads7871_data),
 205                             GFP_KERNEL);
 206        if (!pdata)
 207                return -ENOMEM;
 208
 209        err = sysfs_create_group(&spi->dev.kobj, &ads7871_group);
 210        if (err < 0)
 211                return err;
 212
 213        spi_set_drvdata(spi, pdata);
 214
 215        pdata->hwmon_dev = hwmon_device_register(&spi->dev);
 216        if (IS_ERR(pdata->hwmon_dev)) {
 217                err = PTR_ERR(pdata->hwmon_dev);
 218                goto error_remove;
 219        }
 220
 221        return 0;
 222
 223error_remove:
 224        sysfs_remove_group(&spi->dev.kobj, &ads7871_group);
 225        return err;
 226}
 227
 228static int __devexit ads7871_remove(struct spi_device *spi)
 229{
 230        struct ads7871_data *pdata = spi_get_drvdata(spi);
 231
 232        hwmon_device_unregister(pdata->hwmon_dev);
 233        sysfs_remove_group(&spi->dev.kobj, &ads7871_group);
 234        return 0;
 235}
 236
 237static struct spi_driver ads7871_driver = {
 238        .driver = {
 239                .name = DEVICE_NAME,
 240                .owner = THIS_MODULE,
 241        },
 242
 243        .probe = ads7871_probe,
 244        .remove = __devexit_p(ads7871_remove),
 245};
 246
 247module_spi_driver(ads7871_driver);
 248
 249MODULE_AUTHOR("Paul Thomas <pthomas8589@gmail.com>");
 250MODULE_DESCRIPTION("TI ADS7871 A/D driver");
 251MODULE_LICENSE("GPL");
 252
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.