mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
Third IIO new drivers and cleanups series for 3.15.
New driver * Xilinx XADC driver - This has been ready for a while but was awaiting a device tree ack (or as it turns out 3+ weeks). Cleanup * Drop some unreachable code from mag3110 highlighted by smatch. Fix * vf610 - introduced this cycle - put a possible negative error code into an unsigned long. Another smatch find - this one promoted by guilt that Dan was busy fixing all our messups. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJTGMrfAAoJEFSFNJnE9BaILFsP/iW3NlfWdk1JvdERTpvh4eRW zhhvje+ekn5zR5fwyOlpf7PgDW485sCQ6smVmkjiGvHVGK428Bg19NE2qGAEkaCu dlj0NhKDUWEy7yTixcuP9rPGOd7NFc5qsKfbHlMo9bHNdoKlo0KXOaY9vU8APNAC 0fKyioOqQkcRqejO/4E5GH4uquoDF3e+kPk2vlMBGuxlBeQf3t1Va7j7bP601ln2 YAd+P19s2H33Ujxvholyxad6wyM88W+sglJvM3rLvluGWXsQrnJWQPgD+RMjfvOT QOiyoA+dGuZogT7R3g22Ai6OmaxlXxKBXhutgfZ08VvOaJA0ZVyONvOYjdqQ+F/a UTg6WzkcVJSQdpbErHUEpR4p0n0Q/Whq7KAb1KGNkoe9cIiYGNcmHIg7+MsMtbZi GOGmEry4325ghBUULBfVNzUpQfGNHejw4f9gmngilU2lA7JHeyDUFNKWOKShUWMt nUUm41YsvI3Tj34+740UtldvZrpcvQ9lz6AFDh/xe3MnyLr68xwzc975x9PRr6L8 ZGCAbYeGBzVWDKM2Gri1uF0hVobEB58BsRmViPM4Bwqr8Y3bThSpl68wLYaLw9+d xXu/c+VqyPeubtMKHqSEWJH2NraKo1GFkfQCe2MsnKHTnKfykMQeOKlne21/UCpA mZ/daW65ZngKkI1I1552 =OSqU -----END PGP SIGNATURE----- Merge tag 'iio-for-3.15c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next Jonathan writes: Third IIO new drivers and cleanups series for 3.15. New driver * Xilinx XADC driver - This has been ready for a while but was awaiting a device tree ack (or as it turns out 3+ weeks). Cleanup * Drop some unreachable code from mag3110 highlighted by smatch. Fix * vf610 - introduced this cycle - put a possible negative error code into an unsigned long. Another smatch find - this one promoted by guilt that Dan was busy fixing all our messups.
This commit is contained in:
commit
d62994701b
113
Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt
Normal file
113
Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt
Normal file
@ -0,0 +1,113 @@
|
||||
Xilinx XADC device driver
|
||||
|
||||
This binding document describes the bindings for both of them since the
|
||||
bindings are very similar. The Xilinx XADC is a ADC that can be found in the
|
||||
series 7 FPGAs from Xilinx. The XADC has a DRP interface for communication.
|
||||
Currently two different frontends for the DRP interface exist. One that is only
|
||||
available on the ZYNQ family as a hardmacro in the SoC portion of the ZYNQ. The
|
||||
other one is available on all series 7 platforms and is a softmacro with a AXI
|
||||
interface. This binding document describes the bindings for both of them since
|
||||
the bindings are very similar.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be one of
|
||||
* "xlnx,zynq-xadc-1.00.a": When using the ZYNQ device
|
||||
configuration interface to interface to the XADC hardmacro.
|
||||
* "xlnx,axi-xadc-1.00.a": When using the axi-xadc pcore to
|
||||
interface to the XADC hardmacro.
|
||||
- reg: Address and length of the register set for the device
|
||||
- interrupts: Interrupt for the XADC control interface.
|
||||
- clocks: When using the ZYNQ this must be the ZYNQ PCAP clock,
|
||||
when using the AXI-XADC pcore this must be the clock that provides the
|
||||
clock to the AXI bus interface of the core.
|
||||
|
||||
Optional properties:
|
||||
- interrupt-parent: phandle to the parent interrupt controller
|
||||
- xlnx,external-mux:
|
||||
* "none": No external multiplexer is used, this is the default
|
||||
if the property is omitted.
|
||||
* "single": External multiplexer mode is used with one
|
||||
multiplexer.
|
||||
* "dual": External multiplexer mode is used with two
|
||||
multiplexers for simultaneous sampling.
|
||||
- xlnx,external-mux-channel: Configures which pair of pins is used to
|
||||
sample data in external mux mode.
|
||||
Valid values for single external multiplexer mode are:
|
||||
0: VP/VN
|
||||
1: VAUXP[0]/VAUXN[0]
|
||||
2: VAUXP[1]/VAUXN[1]
|
||||
...
|
||||
16: VAUXP[15]/VAUXN[15]
|
||||
Valid values for dual external multiplexer mode are:
|
||||
1: VAUXP[0]/VAUXN[0] - VAUXP[8]/VAUXN[8]
|
||||
2: VAUXP[1]/VAUXN[1] - VAUXP[9]/VAUXN[9]
|
||||
...
|
||||
8: VAUXP[7]/VAUXN[7] - VAUXP[15]/VAUXN[15]
|
||||
|
||||
This property needs to be present if the device is configured for
|
||||
external multiplexer mode (either single or dual). If the device is
|
||||
not using external multiplexer mode the property is ignored.
|
||||
- xnlx,channels: List of external channels that are connected to the ADC
|
||||
Required properties:
|
||||
* #address-cells: Should be 1.
|
||||
* #size-cells: Should be 0.
|
||||
|
||||
The child nodes of this node represent the external channels which are
|
||||
connected to the ADC. If the property is no present no external
|
||||
channels will be assumed to be connected.
|
||||
|
||||
Each child node represents one channel and has the following
|
||||
properties:
|
||||
Required properties:
|
||||
* reg: Pair of pins the the channel is connected to.
|
||||
0: VP/VN
|
||||
1: VAUXP[0]/VAUXN[0]
|
||||
2: VAUXP[1]/VAUXN[1]
|
||||
...
|
||||
16: VAUXP[15]/VAUXN[15]
|
||||
Note each channel number should only be used at most
|
||||
once.
|
||||
Optional properties:
|
||||
* xlnx,bipolar: If set the channel is used in bipolar
|
||||
mode.
|
||||
|
||||
|
||||
Examples:
|
||||
xadc@f8007100 {
|
||||
compatible = "xlnx,zynq-xadc-1.00.a";
|
||||
reg = <0xf8007100 0x20>;
|
||||
interrupts = <0 7 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
clocks = <&pcap_clk>;
|
||||
|
||||
xlnx,channels {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
channel@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
channel@8 {
|
||||
reg = <8>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
xadc@43200000 {
|
||||
compatible = "xlnx,axi-xadc-1.00.a";
|
||||
reg = <0x43200000 0x1000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
clocks = <&fpga1_clk>;
|
||||
|
||||
xlnx,channels {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
xlnx,bipolar;
|
||||
};
|
||||
};
|
||||
};
|
@ -214,4 +214,17 @@ config VIPERBOARD_ADC
|
||||
Say yes here to access the ADC part of the Nano River
|
||||
Technologies Viperboard.
|
||||
|
||||
config XILINX_XADC
|
||||
tristate "Xilinx XADC driver"
|
||||
depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
Say yes here to have support for the Xilinx XADC. The driver does support
|
||||
both the ZYNQ interface to the XADC as well as the AXI-XADC interface.
|
||||
|
||||
The driver can also be build as a module. If so, the module will be called
|
||||
xilinx-xadc.
|
||||
|
||||
endmenu
|
||||
|
@ -23,3 +23,5 @@ obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
|
||||
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
|
||||
obj-$(CONFIG_VF610_ADC) += vf610_adc.o
|
||||
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
|
||||
xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o
|
||||
obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o
|
||||
|
@ -447,7 +447,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
|
||||
{
|
||||
struct vf610_adc *info = iio_priv(indio_dev);
|
||||
unsigned int hc_cfg;
|
||||
unsigned long ret;
|
||||
long ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
|
1333
drivers/iio/adc/xilinx-xadc-core.c
Normal file
1333
drivers/iio/adc/xilinx-xadc-core.c
Normal file
File diff suppressed because it is too large
Load Diff
254
drivers/iio/adc/xilinx-xadc-events.c
Normal file
254
drivers/iio/adc/xilinx-xadc-events.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Xilinx XADC driver
|
||||
*
|
||||
* Copyright 2013 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clauen <lars@metafoo.de>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#include <linux/iio/events.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "xilinx-xadc.h"
|
||||
|
||||
static const struct iio_chan_spec *xadc_event_to_channel(
|
||||
struct iio_dev *indio_dev, unsigned int event)
|
||||
{
|
||||
switch (event) {
|
||||
case XADC_THRESHOLD_OT_MAX:
|
||||
case XADC_THRESHOLD_TEMP_MAX:
|
||||
return &indio_dev->channels[0];
|
||||
case XADC_THRESHOLD_VCCINT_MAX:
|
||||
case XADC_THRESHOLD_VCCAUX_MAX:
|
||||
return &indio_dev->channels[event];
|
||||
default:
|
||||
return &indio_dev->channels[event-1];
|
||||
}
|
||||
}
|
||||
|
||||
static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event)
|
||||
{
|
||||
const struct iio_chan_spec *chan;
|
||||
unsigned int offset;
|
||||
|
||||
/* Temperature threshold error, we don't handle this yet */
|
||||
if (event == 0)
|
||||
return;
|
||||
|
||||
if (event < 4)
|
||||
offset = event;
|
||||
else
|
||||
offset = event + 4;
|
||||
|
||||
chan = xadc_event_to_channel(indio_dev, event);
|
||||
|
||||
if (chan->type == IIO_TEMP) {
|
||||
/*
|
||||
* The temperature channel only supports over-temperature
|
||||
* events.
|
||||
*/
|
||||
iio_push_event(indio_dev,
|
||||
IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
|
||||
IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
|
||||
iio_get_time_ns());
|
||||
} else {
|
||||
/*
|
||||
* For other channels we don't know whether it is a upper or
|
||||
* lower threshold event. Userspace will have to check the
|
||||
* channel value if it wants to know.
|
||||
*/
|
||||
iio_push_event(indio_dev,
|
||||
IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
|
||||
IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER),
|
||||
iio_get_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for_each_set_bit(i, &events, 8)
|
||||
xadc_handle_event(indio_dev, i);
|
||||
}
|
||||
|
||||
static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan,
|
||||
enum iio_event_direction dir)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
if (chan->type == IIO_TEMP) {
|
||||
offset = XADC_THRESHOLD_OT_MAX;
|
||||
} else {
|
||||
if (chan->channel < 2)
|
||||
offset = chan->channel + 1;
|
||||
else
|
||||
offset = chan->channel + 6;
|
||||
}
|
||||
|
||||
if (dir == IIO_EV_DIR_FALLING)
|
||||
offset += 4;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan)
|
||||
{
|
||||
if (chan->type == IIO_TEMP) {
|
||||
return XADC_ALARM_OT_MASK;
|
||||
} else {
|
||||
switch (chan->channel) {
|
||||
case 0:
|
||||
return XADC_ALARM_VCCINT_MASK;
|
||||
case 1:
|
||||
return XADC_ALARM_VCCAUX_MASK;
|
||||
case 2:
|
||||
return XADC_ALARM_VCCBRAM_MASK;
|
||||
case 3:
|
||||
return XADC_ALARM_VCCPINT_MASK;
|
||||
case 4:
|
||||
return XADC_ALARM_VCCPAUX_MASK;
|
||||
case 5:
|
||||
return XADC_ALARM_VCCODDR_MASK;
|
||||
default:
|
||||
/* We will never get here */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int xadc_read_event_config(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir)
|
||||
{
|
||||
struct xadc *xadc = iio_priv(indio_dev);
|
||||
|
||||
return (bool)(xadc->alarm_mask & xadc_get_alarm_mask(chan));
|
||||
}
|
||||
|
||||
int xadc_write_event_config(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir, int state)
|
||||
{
|
||||
unsigned int alarm = xadc_get_alarm_mask(chan);
|
||||
struct xadc *xadc = iio_priv(indio_dev);
|
||||
uint16_t cfg, old_cfg;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&xadc->mutex);
|
||||
|
||||
if (state)
|
||||
xadc->alarm_mask |= alarm;
|
||||
else
|
||||
xadc->alarm_mask &= ~alarm;
|
||||
|
||||
xadc->ops->update_alarm(xadc, xadc->alarm_mask);
|
||||
|
||||
ret = _xadc_read_adc_reg(xadc, XADC_REG_CONF1, &cfg);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
|
||||
old_cfg = cfg;
|
||||
cfg |= XADC_CONF1_ALARM_MASK;
|
||||
cfg &= ~((xadc->alarm_mask & 0xf0) << 4); /* bram, pint, paux, ddr */
|
||||
cfg &= ~((xadc->alarm_mask & 0x08) >> 3); /* ot */
|
||||
cfg &= ~((xadc->alarm_mask & 0x07) << 1); /* temp, vccint, vccaux */
|
||||
if (old_cfg != cfg)
|
||||
ret = _xadc_write_adc_reg(xadc, XADC_REG_CONF1, cfg);
|
||||
|
||||
err_out:
|
||||
mutex_unlock(&xadc->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Register value is msb aligned, the lower 4 bits are ignored */
|
||||
#define XADC_THRESHOLD_VALUE_SHIFT 4
|
||||
|
||||
int xadc_read_event_value(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir, enum iio_event_info info,
|
||||
int *val, int *val2)
|
||||
{
|
||||
unsigned int offset = xadc_get_threshold_offset(chan, dir);
|
||||
struct xadc *xadc = iio_priv(indio_dev);
|
||||
|
||||
switch (info) {
|
||||
case IIO_EV_INFO_VALUE:
|
||||
*val = xadc->threshold[offset];
|
||||
break;
|
||||
case IIO_EV_INFO_HYSTERESIS:
|
||||
*val = xadc->temp_hysteresis;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*val >>= XADC_THRESHOLD_VALUE_SHIFT;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
|
||||
int xadc_write_event_value(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir, enum iio_event_info info,
|
||||
int val, int val2)
|
||||
{
|
||||
unsigned int offset = xadc_get_threshold_offset(chan, dir);
|
||||
struct xadc *xadc = iio_priv(indio_dev);
|
||||
int ret = 0;
|
||||
|
||||
val <<= XADC_THRESHOLD_VALUE_SHIFT;
|
||||
|
||||
if (val < 0 || val > 0xffff)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&xadc->mutex);
|
||||
|
||||
switch (info) {
|
||||
case IIO_EV_INFO_VALUE:
|
||||
xadc->threshold[offset] = val;
|
||||
break;
|
||||
case IIO_EV_INFO_HYSTERESIS:
|
||||
xadc->temp_hysteresis = val;
|
||||
break;
|
||||
default:
|
||||
mutex_unlock(&xadc->mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chan->type == IIO_TEMP) {
|
||||
/*
|
||||
* According to the datasheet we need to set the lower 4 bits to
|
||||
* 0x3, otherwise 125 degree celsius will be used as the
|
||||
* threshold.
|
||||
*/
|
||||
val |= 0x3;
|
||||
|
||||
/*
|
||||
* Since we store the hysteresis as relative (to the threshold)
|
||||
* value, but the hardware expects an absolute value we need to
|
||||
* recalcualte this value whenever the hysteresis or the
|
||||
* threshold changes.
|
||||
*/
|
||||
if (xadc->threshold[offset] < xadc->temp_hysteresis)
|
||||
xadc->threshold[offset + 4] = 0;
|
||||
else
|
||||
xadc->threshold[offset + 4] = xadc->threshold[offset] -
|
||||
xadc->temp_hysteresis;
|
||||
ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset + 4),
|
||||
xadc->threshold[offset + 4]);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (info == IIO_EV_INFO_VALUE)
|
||||
ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset), val);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&xadc->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
209
drivers/iio/adc/xilinx-xadc.h
Normal file
209
drivers/iio/adc/xilinx-xadc.h
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Xilinx XADC driver
|
||||
*
|
||||
* Copyright 2013 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clauen <lars@metafoo.de>
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#ifndef __IIO_XILINX_XADC__
|
||||
#define __IIO_XILINX_XADC__
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct iio_dev;
|
||||
struct clk;
|
||||
struct xadc_ops;
|
||||
struct platform_device;
|
||||
|
||||
void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events);
|
||||
|
||||
int xadc_read_event_config(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir);
|
||||
int xadc_write_event_config(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir, int state);
|
||||
int xadc_read_event_value(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir, enum iio_event_info info,
|
||||
int *val, int *val2);
|
||||
int xadc_write_event_value(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan, enum iio_event_type type,
|
||||
enum iio_event_direction dir, enum iio_event_info info,
|
||||
int val, int val2);
|
||||
|
||||
enum xadc_external_mux_mode {
|
||||
XADC_EXTERNAL_MUX_NONE,
|
||||
XADC_EXTERNAL_MUX_SINGLE,
|
||||
XADC_EXTERNAL_MUX_DUAL,
|
||||
};
|
||||
|
||||
struct xadc {
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
|
||||
const struct xadc_ops *ops;
|
||||
|
||||
uint16_t threshold[16];
|
||||
uint16_t temp_hysteresis;
|
||||
unsigned int alarm_mask;
|
||||
|
||||
uint16_t *data;
|
||||
|
||||
struct iio_trigger *trigger;
|
||||
struct iio_trigger *convst_trigger;
|
||||
struct iio_trigger *samplerate_trigger;
|
||||
|
||||
enum xadc_external_mux_mode external_mux_mode;
|
||||
|
||||
unsigned int zynq_alarm;
|
||||
unsigned int zynq_masked_alarm;
|
||||
unsigned int zynq_intmask;
|
||||
struct delayed_work zynq_unmask_work;
|
||||
|
||||
struct mutex mutex;
|
||||
spinlock_t lock;
|
||||
|
||||
struct completion completion;
|
||||
};
|
||||
|
||||
struct xadc_ops {
|
||||
int (*read)(struct xadc *, unsigned int, uint16_t *);
|
||||
int (*write)(struct xadc *, unsigned int, uint16_t);
|
||||
int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev,
|
||||
int irq);
|
||||
void (*update_alarm)(struct xadc *, unsigned int);
|
||||
unsigned long (*get_dclk_rate)(struct xadc *);
|
||||
irqreturn_t (*interrupt_handler)(int, void *);
|
||||
irqreturn_t (*threaded_interrupt_handler)(int, void *);
|
||||
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
static inline int _xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
|
||||
uint16_t *val)
|
||||
{
|
||||
lockdep_assert_held(&xadc->mutex);
|
||||
return xadc->ops->read(xadc, reg, val);
|
||||
}
|
||||
|
||||
static inline int _xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
|
||||
uint16_t val)
|
||||
{
|
||||
lockdep_assert_held(&xadc->mutex);
|
||||
return xadc->ops->write(xadc, reg, val);
|
||||
}
|
||||
|
||||
static inline int xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
|
||||
uint16_t *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&xadc->mutex);
|
||||
ret = _xadc_read_adc_reg(xadc, reg, val);
|
||||
mutex_unlock(&xadc->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
|
||||
uint16_t val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&xadc->mutex);
|
||||
ret = _xadc_write_adc_reg(xadc, reg, val);
|
||||
mutex_unlock(&xadc->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* XADC hardmacro register definitions */
|
||||
#define XADC_REG_TEMP 0x00
|
||||
#define XADC_REG_VCCINT 0x01
|
||||
#define XADC_REG_VCCAUX 0x02
|
||||
#define XADC_REG_VPVN 0x03
|
||||
#define XADC_REG_VREFP 0x04
|
||||
#define XADC_REG_VREFN 0x05
|
||||
#define XADC_REG_VCCBRAM 0x06
|
||||
|
||||
#define XADC_REG_VCCPINT 0x0d
|
||||
#define XADC_REG_VCCPAUX 0x0e
|
||||
#define XADC_REG_VCCO_DDR 0x0f
|
||||
#define XADC_REG_VAUX(x) (0x10 + (x))
|
||||
|
||||
#define XADC_REG_MAX_TEMP 0x20
|
||||
#define XADC_REG_MAX_VCCINT 0x21
|
||||
#define XADC_REG_MAX_VCCAUX 0x22
|
||||
#define XADC_REG_MAX_VCCBRAM 0x23
|
||||
#define XADC_REG_MIN_TEMP 0x24
|
||||
#define XADC_REG_MIN_VCCINT 0x25
|
||||
#define XADC_REG_MIN_VCCAUX 0x26
|
||||
#define XADC_REG_MIN_VCCBRAM 0x27
|
||||
#define XADC_REG_MAX_VCCPINT 0x28
|
||||
#define XADC_REG_MAX_VCCPAUX 0x29
|
||||
#define XADC_REG_MAX_VCCO_DDR 0x2a
|
||||
#define XADC_REG_MIN_VCCPINT 0x2b
|
||||
#define XADC_REG_MIN_VCCPAUX 0x2c
|
||||
#define XADC_REG_MIN_VCCO_DDR 0x2d
|
||||
|
||||
#define XADC_REG_CONF0 0x40
|
||||
#define XADC_REG_CONF1 0x41
|
||||
#define XADC_REG_CONF2 0x42
|
||||
#define XADC_REG_SEQ(x) (0x48 + (x))
|
||||
#define XADC_REG_INPUT_MODE(x) (0x4c + (x))
|
||||
#define XADC_REG_THRESHOLD(x) (0x50 + (x))
|
||||
|
||||
#define XADC_REG_FLAG 0x3f
|
||||
|
||||
#define XADC_CONF0_EC BIT(9)
|
||||
#define XADC_CONF0_ACQ BIT(8)
|
||||
#define XADC_CONF0_MUX BIT(11)
|
||||
#define XADC_CONF0_CHAN(x) (x)
|
||||
|
||||
#define XADC_CONF1_SEQ_MASK (0xf << 12)
|
||||
#define XADC_CONF1_SEQ_DEFAULT (0 << 12)
|
||||
#define XADC_CONF1_SEQ_SINGLE_PASS (1 << 12)
|
||||
#define XADC_CONF1_SEQ_CONTINUOUS (2 << 12)
|
||||
#define XADC_CONF1_SEQ_SINGLE_CHANNEL (3 << 12)
|
||||
#define XADC_CONF1_SEQ_SIMULTANEOUS (4 << 12)
|
||||
#define XADC_CONF1_SEQ_INDEPENDENT (8 << 12)
|
||||
#define XADC_CONF1_ALARM_MASK 0x0f0f
|
||||
|
||||
#define XADC_CONF2_DIV_MASK 0xff00
|
||||
#define XADC_CONF2_DIV_OFFSET 8
|
||||
|
||||
#define XADC_CONF2_PD_MASK (0x3 << 4)
|
||||
#define XADC_CONF2_PD_NONE (0x0 << 4)
|
||||
#define XADC_CONF2_PD_ADC_B (0x2 << 4)
|
||||
#define XADC_CONF2_PD_BOTH (0x3 << 4)
|
||||
|
||||
#define XADC_ALARM_TEMP_MASK BIT(0)
|
||||
#define XADC_ALARM_VCCINT_MASK BIT(1)
|
||||
#define XADC_ALARM_VCCAUX_MASK BIT(2)
|
||||
#define XADC_ALARM_OT_MASK BIT(3)
|
||||
#define XADC_ALARM_VCCBRAM_MASK BIT(4)
|
||||
#define XADC_ALARM_VCCPINT_MASK BIT(5)
|
||||
#define XADC_ALARM_VCCPAUX_MASK BIT(6)
|
||||
#define XADC_ALARM_VCCODDR_MASK BIT(7)
|
||||
|
||||
#define XADC_THRESHOLD_TEMP_MAX 0x0
|
||||
#define XADC_THRESHOLD_VCCINT_MAX 0x1
|
||||
#define XADC_THRESHOLD_VCCAUX_MAX 0x2
|
||||
#define XADC_THRESHOLD_OT_MAX 0x3
|
||||
#define XADC_THRESHOLD_TEMP_MIN 0x4
|
||||
#define XADC_THRESHOLD_VCCINT_MIN 0x5
|
||||
#define XADC_THRESHOLD_VCCAUX_MIN 0x6
|
||||
#define XADC_THRESHOLD_OT_MIN 0x7
|
||||
#define XADC_THRESHOLD_VCCBRAM_MAX 0x8
|
||||
#define XADC_THRESHOLD_VCCPINT_MAX 0x9
|
||||
#define XADC_THRESHOLD_VCCPAUX_MAX 0xa
|
||||
#define XADC_THRESHOLD_VCCODDR_MAX 0xb
|
||||
#define XADC_THRESHOLD_VCCBRAM_MIN 0xc
|
||||
#define XADC_THRESHOLD_VCCPINT_MIN 0xd
|
||||
#define XADC_THRESHOLD_VCCPAUX_MIN 0xe
|
||||
#define XADC_THRESHOLD_VCCODDR_MIN 0xf
|
||||
|
||||
#endif
|
@ -194,7 +194,6 @@ static int mag3110_read_raw(struct iio_dev *indio_dev,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT;
|
||||
*val = mag3110_samp_freq[i][0];
|
||||
|
Loading…
Reference in New Issue
Block a user