208 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * ads7871 - driver for TI ADS7871 A/D converter4 *5 * Copyright (c) 2010 Paul Thomas <pthomas8589@gmail.com>6 *7 * You need to have something like this in struct spi_board_info8 * {9 * .modalias = "ads7871",10 * .max_speed_hz = 2*1000*1000,11 * .chip_select = 0,12 * .bus_num = 1,13 * },14 */15 16/*From figure 18 in the datasheet*/17/*Register addresses*/18#define REG_LS_BYTE 0 /*A/D Output Data, LS Byte*/19#define REG_MS_BYTE 1 /*A/D Output Data, MS Byte*/20#define REG_PGA_VALID 2 /*PGA Valid Register*/21#define REG_AD_CONTROL 3 /*A/D Control Register*/22#define REG_GAIN_MUX 4 /*Gain/Mux Register*/23#define REG_IO_STATE 5 /*Digital I/O State Register*/24#define REG_IO_CONTROL 6 /*Digital I/O Control Register*/25#define REG_OSC_CONTROL 7 /*Rev/Oscillator Control Register*/26#define REG_SER_CONTROL 24 /*Serial Interface Control Register*/27#define REG_ID 31 /*ID Register*/28 29/*30 * From figure 17 in the datasheet31 * These bits get ORed with the address to form32 * the instruction byte33 */34/*Instruction Bit masks*/35#define INST_MODE_BM (1 << 7)36#define INST_READ_BM (1 << 6)37#define INST_16BIT_BM (1 << 5)38 39/*From figure 18 in the datasheet*/40/*bit masks for Rev/Oscillator Control Register*/41#define MUX_CNV_BV 742#define MUX_CNV_BM (1 << MUX_CNV_BV)43#define MUX_M3_BM (1 << 3) /*M3 selects single ended*/44#define MUX_G_BV 4 /*allows for reg = (gain << MUX_G_BV) | ...*/45 46/*From figure 18 in the datasheet*/47/*bit masks for Rev/Oscillator Control Register*/48#define OSC_OSCR_BM (1 << 5)49#define OSC_OSCE_BM (1 << 4)50#define OSC_REFE_BM (1 << 3)51#define OSC_BUFE_BM (1 << 2)52#define OSC_R2V_BM (1 << 1)53#define OSC_RBG_BM (1 << 0)54 55#include <linux/module.h>56#include <linux/init.h>57#include <linux/spi/spi.h>58#include <linux/hwmon.h>59#include <linux/hwmon-sysfs.h>60#include <linux/err.h>61#include <linux/delay.h>62 63#define DEVICE_NAME "ads7871"64 65struct ads7871_data {66 struct spi_device *spi;67};68 69static int ads7871_read_reg8(struct spi_device *spi, int reg)70{71 int ret;72 reg = reg | INST_READ_BM;73 ret = spi_w8r8(spi, reg);74 return ret;75}76 77static int ads7871_read_reg16(struct spi_device *spi, int reg)78{79 int ret;80 reg = reg | INST_READ_BM | INST_16BIT_BM;81 ret = spi_w8r16(spi, reg);82 return ret;83}84 85static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val)86{87 u8 tmp[2] = {reg, val};88 return spi_write(spi, tmp, sizeof(tmp));89}90 91static ssize_t voltage_show(struct device *dev, struct device_attribute *da,92 char *buf)93{94 struct ads7871_data *pdata = dev_get_drvdata(dev);95 struct spi_device *spi = pdata->spi;96 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);97 int ret, val, i = 0;98 uint8_t channel, mux_cnv;99 100 channel = attr->index;101 /*102 * TODO: add support for conversions103 * other than single ended with a gain of 1104 */105 /*MUX_M3_BM forces single ended*/106 /*This is also where the gain of the PGA would be set*/107 ads7871_write_reg8(spi, REG_GAIN_MUX,108 (MUX_CNV_BM | MUX_M3_BM | channel));109 110 ret = ads7871_read_reg8(spi, REG_GAIN_MUX);111 mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV);112 /*113 * on 400MHz arm9 platform the conversion114 * is already done when we do this test115 */116 while ((i < 2) && mux_cnv) {117 i++;118 ret = ads7871_read_reg8(spi, REG_GAIN_MUX);119 mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV);120 msleep_interruptible(1);121 }122 123 if (mux_cnv == 0) {124 val = ads7871_read_reg16(spi, REG_LS_BYTE);125 /*result in volts*10000 = (val/8192)*2.5*10000*/126 val = ((val >> 2) * 25000) / 8192;127 return sprintf(buf, "%d\n", val);128 } else {129 return -1;130 }131}132 133static SENSOR_DEVICE_ATTR_RO(in0_input, voltage, 0);134static SENSOR_DEVICE_ATTR_RO(in1_input, voltage, 1);135static SENSOR_DEVICE_ATTR_RO(in2_input, voltage, 2);136static SENSOR_DEVICE_ATTR_RO(in3_input, voltage, 3);137static SENSOR_DEVICE_ATTR_RO(in4_input, voltage, 4);138static SENSOR_DEVICE_ATTR_RO(in5_input, voltage, 5);139static SENSOR_DEVICE_ATTR_RO(in6_input, voltage, 6);140static SENSOR_DEVICE_ATTR_RO(in7_input, voltage, 7);141 142static struct attribute *ads7871_attrs[] = {143 &sensor_dev_attr_in0_input.dev_attr.attr,144 &sensor_dev_attr_in1_input.dev_attr.attr,145 &sensor_dev_attr_in2_input.dev_attr.attr,146 &sensor_dev_attr_in3_input.dev_attr.attr,147 &sensor_dev_attr_in4_input.dev_attr.attr,148 &sensor_dev_attr_in5_input.dev_attr.attr,149 &sensor_dev_attr_in6_input.dev_attr.attr,150 &sensor_dev_attr_in7_input.dev_attr.attr,151 NULL152};153 154ATTRIBUTE_GROUPS(ads7871);155 156static int ads7871_probe(struct spi_device *spi)157{158 struct device *dev = &spi->dev;159 int ret;160 uint8_t val;161 struct ads7871_data *pdata;162 struct device *hwmon_dev;163 164 /* Configure the SPI bus */165 spi->mode = (SPI_MODE_0);166 spi->bits_per_word = 8;167 spi_setup(spi);168 169 ads7871_write_reg8(spi, REG_SER_CONTROL, 0);170 ads7871_write_reg8(spi, REG_AD_CONTROL, 0);171 172 val = (OSC_OSCR_BM | OSC_OSCE_BM | OSC_REFE_BM | OSC_BUFE_BM);173 ads7871_write_reg8(spi, REG_OSC_CONTROL, val);174 ret = ads7871_read_reg8(spi, REG_OSC_CONTROL);175 176 dev_dbg(dev, "REG_OSC_CONTROL write:%x, read:%x\n", val, ret);177 /*178 * because there is no other error checking on an SPI bus179 * we need to make sure we really have a chip180 */181 if (val != ret)182 return -ENODEV;183 184 pdata = devm_kzalloc(dev, sizeof(struct ads7871_data), GFP_KERNEL);185 if (!pdata)186 return -ENOMEM;187 188 pdata->spi = spi;189 190 hwmon_dev = devm_hwmon_device_register_with_groups(dev, spi->modalias,191 pdata,192 ads7871_groups);193 return PTR_ERR_OR_ZERO(hwmon_dev);194}195 196static struct spi_driver ads7871_driver = {197 .driver = {198 .name = DEVICE_NAME,199 },200 .probe = ads7871_probe,201};202 203module_spi_driver(ads7871_driver);204 205MODULE_AUTHOR("Paul Thomas <pthomas8589@gmail.com>");206MODULE_DESCRIPTION("TI ADS7871 A/D driver");207MODULE_LICENSE("GPL");208