135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/9
335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang *
435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang *
535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Copyright 2010 Analog Devices Inc.
635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang *
735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Licensed under the GPL-2 or later.
835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
1035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/interrupt.h>
1135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/gpio.h>
1235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/workqueue.h>
1335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/device.h>
1435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/kernel.h>
1535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/slab.h>
1635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/sysfs.h>
1735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/list.h>
1835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/i2c.h>
1935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include <linux/rtc.h>
2099c978529a40132a6f7a5f136b4362b56fc88d8cPaul Gortmaker#include <linux/module.h>
2135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
2235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include "../iio.h"
23af5046af1c812839f085030f358a01814666fc80Jonathan Cameron#include "../events.h"
2435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include "../sysfs.h"
2535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include "adt7316.h"
2635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
2735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
2835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 registers definition
2935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
3035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_STAT1		0x0
3135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_STAT2		0x1
3235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_IN_TEMP_VDD		0x3
3335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_IN_TEMP_MASK	0x3
3435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_VDD_MASK		0xC
3535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_VDD_OFFSET		2
3635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_EX_TEMP_AIN		0x4
3735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_EX_TEMP_MASK	0x3
3835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_LSB_AIN_SHIFT		2
3935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_MSB_DATA_BASE        0x6
4035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_MSB_DATA_REGS        3
4135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_MSB_DATA_REGS        6
4235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_VDD			0x6
4335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_IN_TEMP		0x7
4435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_EX_TEMP		0x8
4535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN1		0x8
4635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN2		0x9
4735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN3		0xA
4835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN4		0xB
4935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_DATA_BASE		0x10
5035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_MSB_DATA_REGS	4
5135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_A		0x10
5235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_A		0x11
5335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_B		0x12
5435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_B		0x13
5535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_C		0x14
5635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_C		0x15
5735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_D		0x16
5835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_D		0x17
5935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_CONFIG1			0x18
6035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_CONFIG2			0x19
6135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_CONFIG3			0x1A
6235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LDAC_CONFIG		0x1B
6335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DAC_CONFIG		0x1C
6435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_MASK1		0x1D
6535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_MASK2		0x1E
6635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_OFFSET		0x1F
6735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_OFFSET		0x20
6835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_ANALOG_TEMP_OFFSET	0x21
6935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_ANALOG_TEMP_OFFSET	0x22
7035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VDD_HIGH		0x23
7135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VDD_LOW			0x24
7235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_HIGH		0x25
7335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_LOW		0x26
7435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_HIGH		0x27
7535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_LOW		0x28
7635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN2_HIGH		0x2B
7735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN2_LOW		0x2C
7835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN3_HIGH		0x2D
7935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN3_LOW		0x2E
8035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN4_HIGH		0x2F
8135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN4_LOW		0x30
8235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DEVICE_ID		0x4D
8335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MANUFACTURE_ID		0x4E
8435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DEVICE_REV		0x4F
8535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_SPI_LOCK_STAT		0x7F
8635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
8735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
8835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 config1
8935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
9035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN			0x1
9135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_SEL_EX_TEMP		0x4
9235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_SEL_AIN1_2_EX_TEMP_MASK	0x6
9335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_SEL_AIN3		0x8
9435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_EN			0x20
9535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_POLARITY		0x40
9635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_PD			0x80
9735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
9835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
9935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 config2
10035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
10135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_MASK	0x3
10235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_MASK	0x7
10335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_VDD	0
10435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_IN		1
10535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_EX		2
10635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN1	2
10735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN2	3
10835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN3	4
10935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN4	5
11035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_MODE	0x10
11135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DISABLE_AVERAGING	0x20
11235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN_SMBUS_TIMEOUT	0x40
11335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_RESET			0x80
11435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
11535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
11635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 config3
11735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
11835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_ADCLK_22_5		0x1
11935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_HIGH_RESOLUTION	0x2
12035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_VIA_DAC_LDCA	0x4
12135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN_IN_VREF		0x10
12235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN_IN_TEMP_PROP_DACA	0x20
12335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN_EX_TEMP_PROP_DACB	0x40
12435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
12535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
12635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 DAC config
12735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
12835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_2VREF_CH_MASK	0xF
12935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_MASK		0x30
13035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_SINGLE	0x00
13135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_AB_CD	0x10
13235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_ABCD		0x20
13335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_LDAC		0x30
13435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VREF_BYPASS_DAC_AB	0x40
13535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VREF_BYPASS_DAC_CD	0x80
13635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
13735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
13835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 LDAC config
13935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
14035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LDAC_EN_DA_MASK		0xF
14135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DAC_IN_VREF		0x10
14235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_AB_IN_VREF		0x10
14335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_CD_IN_VREF		0x20
14435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_IN_VREF_OFFSET	4
14535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_IN_VREF_MASK	0x30
14635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
14735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
14835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 INT_MASK2
14935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
15035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_MASK2_VDD		0x10
15135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
15235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
15335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 value masks
15435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
15535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VALUE_MASK		0xfff
15635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_T_VALUE_SIGN		0x400
15735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_T_VALUE_FLOAT_OFFSET	2
15835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_T_VALUE_FLOAT_MASK	0x2
15935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
16035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
16135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Chip ID
16235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
16335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7316		0x1
16435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7317		0x2
16535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7318		0x3
16635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7516		0x11
16735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7517		0x12
16835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7519		0x14
16935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
17035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_FAMILY_MASK		0xF0
17135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT73XX		0x0
17235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT75XX		0x10
17335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
17435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
17535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * struct adt7316_chip_info - chip specifc information
17635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
17735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
17835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstruct adt7316_chip_info {
17935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_bus	bus;
18035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16			ldac_pin;
18135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16			int_mask;	/* 0x2f */
18235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			config1;
18335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			config2;
18435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			config3;
18535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			dac_config;	/* DAC config */
18635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			ldac_config;	/* LDAC config */
18735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			dac_bits;	/* 8, 10, 12 */
18835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			id;		/* chip id */
18935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
19035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
19135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
19235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Logic interrupt mask for user application to enable
19335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * interrupts.
19435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
19535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_HIGH_INT_MASK	0x1
19635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_LOW_INT_MASK	0x2
19735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_HIGH_INT_MASK	0x4
19835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_LOW_INT_MASK	0x8
19935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_FAULT_INT_MASK	0x10
20035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN1_INT_MASK		0x4
20135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN2_INT_MASK		0x20
20235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN3_INT_MASK		0x40
20335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN4_INT_MASK		0x80
20435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VDD_INT_MASK		0x100
20535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_TEMP_INT_MASK		0x1F
20635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN_INT_MASK		0xE0
20735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_TEMP_AIN_INT_MASK	\
2088df322385a7e253672dc5077c11dc1a6219d25ccJonathan Cameron	(ADT7316_TEMP_INT_MASK)
20935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
21035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
21135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * struct adt7316_chip_info - chip specifc information
21235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
21335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
21435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstruct adt7316_limit_regs {
21535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16	data_high;
21635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16	data_low;
21735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
21835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
21935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enabled(struct device *dev,
22035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
22135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
22235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
22335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
22470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
22535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
22635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN));
22735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
22835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
22935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip,
23035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int enable)
23135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
23235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
23335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
23435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
23535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (enable)
23635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 = chip->config1 | ADT7316_EN;
23735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
23835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 = chip->config1 & ~ADT7316_EN;
23935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
24135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
24235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
24335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
24535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return ret;
24735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
24935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
25035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enabled(struct device *dev,
25135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
25235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
25335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
25435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
25535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
25670be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
25735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int enable;
25835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
25935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
26035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		enable = 1;
26135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
26235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		enable = 0;
26335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
26435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (_adt7316_store_enabled(chip, enable) < 0)
26535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
26635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
26735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return len;
26835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
26935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
27035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR,
27135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enabled,
27235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enabled,
27335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
27435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
27535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_select_ex_temp(struct device *dev,
27635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
27735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
27835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
27935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
28070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
28135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
28235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
28335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
28435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
28535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP));
28635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
28735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
28835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_select_ex_temp(struct device *dev,
28935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
29035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
29135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
29235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
29335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
29470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
29535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
29635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
29735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
29835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
29935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
30035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
30135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config1 = chip->config1 & (~ADT7516_SEL_EX_TEMP);
30235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
30335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 |= ADT7516_SEL_EX_TEMP;
30435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
30535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
30635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
30735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
30835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
30935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
31035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
31135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
31235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
31335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
31435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(select_ex_temp, S_IRUGO | S_IWUSR,
31535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_select_ex_temp,
31635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_select_ex_temp,
31735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
31835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
31935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_mode(struct device *dev,
32035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
32135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
32235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
32335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
32470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
32535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
32635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE)
32735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "single_channel\n");
32835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
32935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "round_robin\n");
33035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
33135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
33235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_mode(struct device *dev,
33335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
33435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
33535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
33635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
33735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
33870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
33935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
34035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
34135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
34235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MODE);
34335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "single_channel", 14))
34435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 |= ADT7316_AD_SINGLE_CH_MODE;
34535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
34635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
34735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
34835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
34935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
35035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
35135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
35235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
35335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
35435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
35535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
35635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_mode,
35735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_mode,
35835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
35935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
36035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_all_modes(struct device *dev,
36135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
36235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
36335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
36435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "single_channel\nround_robin\n");
36535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
36635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
36735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(all_modes, S_IRUGO, adt7316_show_all_modes, NULL, 0);
36835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
36935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ad_channel(struct device *dev,
37035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
37135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
37235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
37335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
37470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
37535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
37635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
37735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
37835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
37935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) {
38035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_VDD:
38135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - VDD\n");
38235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_IN:
38335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "1 - Internal Temperature\n");
38435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_EX:
38535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) &&
38635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
38735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "2 - AIN1\n");
38835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
38935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "2 - External Temperature\n");
39035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7516_AD_SINGLE_CH_AIN2:
39135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
39235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "3 - AIN2\n");
39335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
39435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "N/A\n");
39535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7516_AD_SINGLE_CH_AIN3:
39635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->config1 & ADT7516_SEL_AIN3)
39735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "4 - AIN3\n");
39835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
39935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "N/A\n");
40035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7516_AD_SINGLE_CH_AIN4:
40135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "5 - AIN4\n");
40235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	default:
40335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "N/A\n");
40495cd17c9f3734091a5811fabbd778e3f7b1f0789Joe Perches	}
40535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
40635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
40735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_ad_channel(struct device *dev,
40835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
40935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
41035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
41135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
41235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
41370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
41435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
41535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data = 0;
41635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
41735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
41835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
41935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
42035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
42135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 10, &data);
42235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
42335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
42435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
42535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
42635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 5)
42735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
42835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
42935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 = chip->config2 & (~ADT7516_AD_SINGLE_CH_MASK);
43035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
43135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 2)
43235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
43335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
43435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MASK);
43535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
43635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
43735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
43835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 |= data;
43935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
44135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
44235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
44335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
44535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
44735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
44835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ad_channel, S_IRUGO | S_IWUSR,
45035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ad_channel,
45135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_ad_channel,
45235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
45335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
45435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_all_ad_channels(struct device *dev,
45535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
45635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
45735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
45835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
45970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
46035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
46135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
46235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
46335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
46435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
46535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
466383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				"2 - External Temperature or AIN1\n"
46735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
46835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
46935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
47035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"2 - External Temperature\n");
47135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
47235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
47335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(all_ad_channels, S_IRUGO,
47435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_all_ad_channels, NULL, 0);
47535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
47635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_disable_averaging(struct device *dev,
47735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
47835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
47935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
48035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
48170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
48235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
48335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
48435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config2 & ADT7316_DISABLE_AVERAGING));
48535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
48635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
48735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_disable_averaging(struct device *dev,
48835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
48935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
49035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
49135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
49235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
49370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
49435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
49535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
49635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
49735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 & (~ADT7316_DISABLE_AVERAGING);
49835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
49935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 |= ADT7316_DISABLE_AVERAGING;
50035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
50135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
50235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
50335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
50435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
50535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
50635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
50735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
50835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
50935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
51035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(disable_averaging, S_IRUGO | S_IWUSR,
51135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_disable_averaging,
51235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_disable_averaging,
51335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
51435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
51535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enable_smbus_timeout(struct device *dev,
51635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
51735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
51835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
51935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
52070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
52135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
52235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
52335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT));
52435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
52535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
52635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enable_smbus_timeout(struct device *dev,
52735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
52835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
52935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
53035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
53135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
53270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
53335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
53435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
53535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
53635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 & (~ADT7316_EN_SMBUS_TIMEOUT);
53735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
53835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 |= ADT7316_EN_SMBUS_TIMEOUT;
53935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
54135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
54235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
54335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
54535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
54735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
54835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
55035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enable_smbus_timeout,
55135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enable_smbus_timeout,
55235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
55335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
55435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
55535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_reset(struct device *dev,
55635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
55735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
55835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
55935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
56035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
56170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
56235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
56335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
56435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
56535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 | ADT7316_RESET;
56635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
56735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
56835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
56935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
57035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
57135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
57235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
57335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
57435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(reset, S_IWUSR,
57535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		NULL,
57635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_reset,
57735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
57835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
57935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_powerdown(struct device *dev,
58035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
58135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
58235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
58335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
58470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
58535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
58635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD));
58735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
58835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
58935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_powerdown(struct device *dev,
59035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
59135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
59235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
59335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
59435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
59570be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
59635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
59735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
59835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
59935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config1 = chip->config1 & (~ADT7316_PD);
60035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
60135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 |= ADT7316_PD;
60235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
60335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
60435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
60535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
60635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
60735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
60835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
60935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
61035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
61135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
61235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(powerdown, S_IRUGO | S_IWUSR,
61335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_powerdown,
61435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_powerdown,
61535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
61635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
61735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_fast_ad_clock(struct device *dev,
61835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
61935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
62035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
62135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
62270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
62335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
62435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5));
62535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
62635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
62735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_fast_ad_clock(struct device *dev,
62835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
62935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
63035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
63135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
63235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
63370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
63435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
63535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
63635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
63735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config3 = chip->config3 & (~ADT7316_ADCLK_22_5);
63835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
63935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 |= ADT7316_ADCLK_22_5;
64035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
64135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
64235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
64335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
64435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
64535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
64635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
64735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
64835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
64935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
65035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(fast_ad_clock, S_IRUGO | S_IWUSR,
65135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_fast_ad_clock,
65235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_fast_ad_clock,
65335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
65435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
65535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_da_high_resolution(struct device *dev,
65635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
65735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
65835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
65935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
66070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
66135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
66235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) {
66335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
66435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "1 (12 bits)\n");
66535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
66635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "1 (10 bits)\n");
66735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
66835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
66935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "0 (8 bits)\n");
67035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
67135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
67235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_da_high_resolution(struct device *dev,
67335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
67435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
67535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
67635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
67735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
67870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
67935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
68035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
68135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
68235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_bits = 8;
68335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
68435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1)) {
68535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION;
68635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
68735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->dac_bits = 12;
68835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
68935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->dac_bits = 10;
69035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else
69135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION);
69235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
69335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
69435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
69535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
69635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
69735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
69835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
69935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
70035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
70135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
70235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(da_high_resolution, S_IRUGO | S_IWUSR,
70335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_da_high_resolution,
70435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_da_high_resolution,
70535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
70635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
70735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN_internal_Vref(struct device *dev,
70835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
70935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
71035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
71135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
71270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
71335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
71435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
71535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
71635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
71735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
71835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config3 & ADT7516_AIN_IN_VREF));
71935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
72035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
72135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_AIN_internal_Vref(struct device *dev,
72235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
72335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
72435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
72535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
72635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
72770be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
72835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
72935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
73035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
73135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
73235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
73335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
73435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (memcmp(buf, "1", 1))
73535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 & (~ADT7516_AIN_IN_VREF);
73635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
73735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 | ADT7516_AIN_IN_VREF;
73835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
73935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
74035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
74135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
74235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
74335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
74435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
74535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
74635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
74735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
74835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN_internal_Vref, S_IRUGO | S_IWUSR,
74935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_AIN_internal_Vref,
75035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_AIN_internal_Vref,
75135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
75235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
75335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
75435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enable_prop_DACA(struct device *dev,
75535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
75635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
75735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
75835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
75970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
76035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
76135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
76235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA));
76335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
76435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
76535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enable_prop_DACA(struct device *dev,
76635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
76735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
76835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
76935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
77035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
77170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
77235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
77335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
77435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
77535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config3 = chip->config3 & (~ADT7316_EN_IN_TEMP_PROP_DACA);
77635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
77735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 |= ADT7316_EN_IN_TEMP_PROP_DACA;
77835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
77935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
78035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
78135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
78235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
78335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
78435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
78535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
78635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
78735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
78835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enable_proportion_DACA, S_IRUGO | S_IWUSR,
78935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enable_prop_DACA,
79035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enable_prop_DACA,
79135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
79235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
79335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enable_prop_DACB(struct device *dev,
79435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
79535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
79635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
79735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
79870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
79935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
80035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
80135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB));
80235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
80335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
80435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enable_prop_DACB(struct device *dev,
80535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
80635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
80735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
80835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
80935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
81070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
81135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
81235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
81335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
81435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config3 = chip->config3 & (~ADT7316_EN_EX_TEMP_PROP_DACB);
81535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
81635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 |= ADT7316_EN_EX_TEMP_PROP_DACB;
81735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
81835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
81935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
82035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
82135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
82335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
82535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
82635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enable_proportion_DACB, S_IRUGO | S_IWUSR,
82835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enable_prop_DACB,
82935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enable_prop_DACB,
83035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
83135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
83235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev,
83335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
83435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
83535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
83635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
83770be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
83835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
83935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "0x%x\n",
84035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->dac_config & ADT7316_DA_2VREF_CH_MASK);
84135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
84235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
84335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
84435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
84535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
84635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
84735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
84835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
84970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
85035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
85135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data = 0;
85235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
85335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
85435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 16, &data);
85535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data > ADT7316_DA_2VREF_CH_MASK)
85635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
85735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
85835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_DA_2VREF_CH_MASK);
85935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config |= data;
86035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
86235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
86335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
86435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
86635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
86835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
86935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
87035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, S_IRUGO | S_IWUSR,
87135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DAC_2Vref_ch_mask,
87235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_2Vref_ch_mask,
87335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
87435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
87535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_update_mode(struct device *dev,
87635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
87735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
87835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
87935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
88070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
88135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
88235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
88335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "manual\n");
88435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else {
88535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) {
88635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		case ADT7316_DA_EN_MODE_SINGLE:
88735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "0 - auto at any MSB DAC writing\n");
88835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		case ADT7316_DA_EN_MODE_AB_CD:
88935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "1 - auto at MSB DAC AB and CD writing\n");
89035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		case ADT7316_DA_EN_MODE_ABCD:
89135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "2 - auto at MSB DAC ABCD writing\n");
89235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		default: /* ADT7316_DA_EN_MODE_LDAC */
89335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "3 - manual\n");
89495cd17c9f3734091a5811fabbd778e3f7b1f0789Joe Perches		}
89535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
89635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
89735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
89835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_update_mode(struct device *dev,
89935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
90035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
90135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
90235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
90335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
90470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
90535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
90635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
90735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
90835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
90935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
91035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
91135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
91235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 10, &data);
91335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data > ADT7316_DA_EN_MODE_MASK)
91435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
91535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
91635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_DA_EN_MODE_MASK);
91735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config |= data;
91835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
91935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
92035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
92135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
92235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
92335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
92435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
92535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
92635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
92735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
92835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_update_mode, S_IRUGO | S_IWUSR,
92935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DAC_update_mode,
93035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_update_mode,
93135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
93235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
93335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_all_DAC_update_modes(struct device *dev,
93435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
93535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
93635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
93735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
93870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
93935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
94035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)
94135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - auto at any MSB DAC writing\n"
94235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"1 - auto at MSB DAC AB and CD writing\n"
94335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"2 - auto at MSB DAC ABCD writing\n"
94435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"3 - manual\n");
94535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
94635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "manual\n");
94735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
94835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
94935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(all_DAC_update_modes, S_IRUGO,
95035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_all_DAC_update_modes, NULL, 0);
95135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
95235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
95335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_update_DAC(struct device *dev,
95435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
95535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
95635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
95735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
95835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
95970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
96035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 ldac_config;
96135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
96235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
96335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
96435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
96535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->dac_config & ADT7316_DA_EN_MODE_MASK) !=
96635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_DA_EN_MODE_LDAC)
96735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EPERM;
96835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
96935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = strict_strtoul(buf, 16, &data);
97035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret || data > ADT7316_LDAC_EN_DA_MASK)
97135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
97235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
97335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config = chip->ldac_config & (~ADT7316_LDAC_EN_DA_MASK);
97435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config |= data;
97535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
97635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG,
97735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config);
97835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
97935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
98035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
98135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		gpio_set_value(chip->ldac_pin, 0);
98235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		gpio_set_value(chip->ldac_pin, 1);
98335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
98435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
98535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
98635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
98735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
98835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(update_DAC, S_IRUGO | S_IWUSR,
98935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		NULL,
99035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_update_DAC,
99135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
99235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
99335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev,
99435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
99535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
99635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
99735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
99870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
99935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
100035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
100135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
100235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
100335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
100435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB));
100535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
100635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
100735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev,
100835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
100935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
101035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
101135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
101235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
101370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
101435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
101535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
101635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
101735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
101835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
101935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
102035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB);
102135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
102235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		dac_config |= ADT7316_VREF_BYPASS_DAC_AB;
102335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
102435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
102535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
102635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
102735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
102835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
102935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
103035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
103135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
103235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
103335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DA_AB_Vref_bypass, S_IRUGO | S_IWUSR,
103435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DA_AB_Vref_bypass,
103535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DA_AB_Vref_bypass,
103635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
103735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
103835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev,
103935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
104035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
104135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
104235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
104370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
104435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
104535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
104635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
104735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
104835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
104935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD));
105035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
105135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
105235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev,
105335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
105435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
105535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
105635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
105735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
105870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
105935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
106035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
106135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
106235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
106335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
106435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
106535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD);
106635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
106735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		dac_config |= ADT7316_VREF_BYPASS_DAC_CD;
106835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
106935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
107035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
107135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
107235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
107335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
107435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
107535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
107635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
107735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
107835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DA_CD_Vref_bypass, S_IRUGO | S_IWUSR,
107935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DA_CD_Vref_bypass,
108035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DA_CD_Vref_bypass,
108135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
108235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
108335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_internal_Vref(struct device *dev,
108435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
108535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
108635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
108735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
108870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
108935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
109035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
109135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0x%x\n",
109235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >>
109335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_DAC_IN_VREF_OFFSET);
109435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
109535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "%d\n",
109635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			!!(chip->dac_config & ADT7316_DAC_IN_VREF));
109735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
109835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
109935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
110035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
110135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
110235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
110335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
110435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
110570be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
110635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 ldac_config;
110735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
110835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
110935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
111035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
111135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = strict_strtoul(buf, 16, &data);
111235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret || data > 3)
111335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
111435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
111535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK);
111635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data & 0x1)
111735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config |= ADT7516_DAC_AB_IN_VREF;
111835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else if (data & 0x2)
111935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config |= ADT7516_DAC_CD_IN_VREF;
112035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
112135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = strict_strtoul(buf, 16, &data);
112235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
112335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
112435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
112535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config = chip->ldac_config & (~ADT7316_DAC_IN_VREF);
112635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data)
112735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config = chip->ldac_config | ADT7316_DAC_IN_VREF;
112835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
112935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, ldac_config);
113135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
113235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
113335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->ldac_config = ldac_config;
113535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
113735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
113835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_internal_Vref, S_IRUGO | S_IWUSR,
114035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DAC_internal_Vref,
114135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_internal_Vref,
114235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
114335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
114435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
114535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int channel, char *buf)
114635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
114735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16 data;
114835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 msb, lsb;
114935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	char sign = ' ';
115035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
115135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
115235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) &&
115335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK))
115435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
115535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
115635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	switch (channel) {
115735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_IN:
115835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
115935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_LSB_IN_TEMP_VDD, &lsb);
116035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
116135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
116235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
116335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
116435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
116535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
116635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
116735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
116835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
116935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data |= lsb & ADT7316_LSB_IN_TEMP_MASK;
117035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		break;
117135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_VDD:
117235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
117335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_LSB_IN_TEMP_VDD, &lsb);
117435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
117535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
117635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
117735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
117835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
117935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
118035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
118135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
118235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
118335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
118435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET;
118535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "%d\n", data);
118635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	default: /* ex_temp and ain */
118735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
118835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_LSB_EX_TEMP_AIN, &lsb);
118935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
119035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
119135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
119235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
119335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
119435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
119535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
119635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
119735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
119835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data |= lsb & (ADT7316_LSB_EX_TEMP_MASK <<
119935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(ADT7516_LSB_AIN_SHIFT * (channel -
120035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE))));
120135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
120235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
120335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "%d\n", data);
120435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
120535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			break;
120695cd17c9f3734091a5811fabbd778e3f7b1f0789Joe Perches	}
120735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
120835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data & ADT7316_T_VALUE_SIGN) {
120935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		/* convert supplement to positive value */
121035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = (ADT7316_T_VALUE_SIGN << 1) - data;
121135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		sign = '-';
121235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
121335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
121435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%c%d.%.2d\n", sign,
121535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(data >> ADT7316_T_VALUE_FLOAT_OFFSET),
121635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(data & ADT7316_T_VALUE_FLOAT_MASK) * 25);
121735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
121835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
121935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_VDD(struct device *dev,
122035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
122135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
122235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
122335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
122470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
122535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
122635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf);
122735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
122835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(VDD, S_IRUGO, adt7316_show_VDD, NULL, 0);
122935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
123035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_temp(struct device *dev,
123135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
123235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
123335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
123435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
123570be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
123635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
123735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf);
123835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
123935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
124035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(in_temp, S_IRUGO, adt7316_show_in_temp, NULL, 0);
124135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
124235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
124335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
124435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
124535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
124635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
124770be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
124835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
124935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf);
125035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
125135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
125235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
125335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
125435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
125535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN2(struct device *dev,
125635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
125735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
125835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
125935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
126070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
126135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
126235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf);
126335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
126435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN2, S_IRUGO, adt7316_show_AIN2, NULL, 0);
126535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
126635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN3(struct device *dev,
126735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
126835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
126935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
127035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
127170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
127235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
127335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf);
127435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
127535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN3, S_IRUGO, adt7316_show_AIN3, NULL, 0);
127635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
127735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN4(struct device *dev,
127835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
127935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
128035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
128135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
128270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
128335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
128435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf);
128535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
128635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN4, S_IRUGO, adt7316_show_AIN4, NULL, 0);
128735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
128835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
128935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int offset_addr, char *buf)
129035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
129135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int data;
129235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
129335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
129435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
129535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, offset_addr, &val);
129635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
129735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
129835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
129935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	data = (int)val;
130035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (val & 0x80)
130135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data -= 256;
130235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
130335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", data);
130435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
130535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
130635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
130735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int offset_addr, const char *buf, size_t len)
130835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
130935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	long data;
131035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
131135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
131235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
131335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtol(buf, 10, &data);
131435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data > 127 || data < -128)
131535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
131635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
131735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data < 0)
131835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data += 256;
131935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	val = (u8)data;
132135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, offset_addr, val);
132335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
132435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
132535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
132735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
132835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_temp_offset(struct device *dev,
133035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
133135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
133235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
133335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
133470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
133535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
133635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf);
133735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
133835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
133935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_in_temp_offset(struct device *dev,
134035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
134135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
134235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
134335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
134435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
134570be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
134635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
134735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len);
134835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
134935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
135035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(in_temp_offset, S_IRUGO | S_IWUSR,
135135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_in_temp_offset,
135235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_in_temp_offset, 0);
135335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
135435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_temp_offset(struct device *dev,
135535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
135635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
135735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
135835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
135970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
136035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
136135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf);
136235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
136335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
136435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_ex_temp_offset(struct device *dev,
136535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
136635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
136735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
136835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
136935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
137070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
137135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
137235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len);
137335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
137435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
137535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_temp_offset, S_IRUGO | S_IWUSR,
137635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_temp_offset,
137735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_ex_temp_offset, 0);
137835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
137935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_analog_temp_offset(struct device *dev,
138035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
138135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
138235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
138335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
138470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
138535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
138635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip,
138735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_ANALOG_TEMP_OFFSET, buf);
138835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
138935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
139035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_in_analog_temp_offset(struct device *dev,
139135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
139235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
139335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
139435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
139535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
139670be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
139735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
139835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip,
139935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_ANALOG_TEMP_OFFSET, buf, len);
140035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
140135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
140235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(in_analog_temp_offset, S_IRUGO | S_IWUSR,
140335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_in_analog_temp_offset,
140435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_in_analog_temp_offset, 0);
140535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
140635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev,
140735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
140835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
140935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
141035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
141170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
141235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
141335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip,
141435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_ANALOG_TEMP_OFFSET, buf);
141535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
141635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
141735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev,
141835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
141935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
142035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
142135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
142235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
142370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
142435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
142535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip,
142635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_ANALOG_TEMP_OFFSET, buf, len);
142735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
142835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
142935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_analog_temp_offset, S_IRUGO | S_IWUSR,
143035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_analog_temp_offset,
143135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_ex_analog_temp_offset, 0);
143235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
143335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip,
143435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int channel, char *buf)
143535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
143635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16 data;
143735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 msb, lsb, offset;
143835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
143935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
144035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (channel >= ADT7316_DA_MSB_DATA_REGS ||
144135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 0 &&
144235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) ||
144335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 1 &&
144435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)))
144535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
144635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
144735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	offset = chip->dac_bits - 8;
144835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
144935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->dac_bits > 8) {
145035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
145135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_DA_DATA_BASE + channel * 2, &lsb);
145235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
145335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
145435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
145535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
145635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client,
145735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ADT7316_DA_DATA_BASE + 1 + channel * 2, &msb);
145835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
145935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
146035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
146135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	data = (msb << offset) + (lsb & ((1 << offset) - 1));
146235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
146335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", data);
146435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
146535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
146635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
146735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int channel, const char *buf, size_t len)
146835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
146935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 msb, lsb, offset;
147035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
147135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
147235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
147335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (channel >= ADT7316_DA_MSB_DATA_REGS ||
147435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 0 &&
147535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) ||
147635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 1 &&
147735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)))
147835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
147935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
148035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	offset = chip->dac_bits - 8;
148135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
148235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 10, &data);
148335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data >= (1 << chip->dac_bits))
148435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
148535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
148635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->dac_bits > 8) {
148735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		lsb = data & (1 << offset);
148835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.write(chip->bus.client,
148935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_DA_DATA_BASE + channel * 2, lsb);
149035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
149135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
149235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
149335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
149435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	msb = data >> offset;
149535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client,
149635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ADT7316_DA_DATA_BASE + 1 + channel * 2, msb);
149735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
149835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
149935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
150035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
150135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
150235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
150335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_A(struct device *dev,
150435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
150535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
150635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
150735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
150870be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
150935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
151035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 0, buf);
151135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
151235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
151335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_A(struct device *dev,
151435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
151535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
151635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
151735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
151835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
151970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
152035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
152135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 0, buf, len);
152235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
152335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
152435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_A, S_IRUGO | S_IWUSR, adt7316_show_DAC_A,
152535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_A, 0);
152635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
152735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_B(struct device *dev,
152835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
152935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
153035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
153135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
153270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
153335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
153435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 1, buf);
153535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
153635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
153735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_B(struct device *dev,
153835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
153935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
154035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
154135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
154235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
154370be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
154435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
154535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 1, buf, len);
154635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
154735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
154835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_B, S_IRUGO | S_IWUSR, adt7316_show_DAC_B,
154935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_B, 0);
155035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
155135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_C(struct device *dev,
155235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
155335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
155435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
155535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
155670be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
155735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
155835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 2, buf);
155935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
156035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
156135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_C(struct device *dev,
156235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
156335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
156435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
156535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
156635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
156770be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
156835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
156935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 2, buf, len);
157035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
157135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
157235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_C, S_IRUGO | S_IWUSR, adt7316_show_DAC_C,
157335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_C, 0);
157435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
157535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_D(struct device *dev,
157635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
157735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
157835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
157935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
158070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
158135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
158235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 3, buf);
158335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
158435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
158535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_D(struct device *dev,
158635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
158735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
158835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
158935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
159035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
159170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
159235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
159335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 3, buf, len);
159435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
159535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
159635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_D, S_IRUGO | S_IWUSR, adt7316_show_DAC_D,
159735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_D, 0);
159835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
159935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_device_id(struct device *dev,
160035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
160135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
160235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
160335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
160470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
160535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 id;
160635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
160735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
160835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_ID, &id);
160935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
161035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
161135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", id);
161335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
161435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(device_id, S_IRUGO, adt7316_show_device_id, NULL, 0);
161635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_manufactorer_id(struct device *dev,
161835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
161935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
162035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
162135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
162270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
162335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 id;
162435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
162535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
162635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_MANUFACTURE_ID, &id);
162735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
162835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
162935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
163035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", id);
163135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
163235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
163335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(manufactorer_id, S_IRUGO,
163435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_manufactorer_id, NULL, 0);
163535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
163635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_device_rev(struct device *dev,
163735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
163835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
163935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
164035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
164170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
164235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 rev;
164335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
164435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
164535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_REV, &rev);
164635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
164735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
164835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
164935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", rev);
165035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
165135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
165235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(device_rev, S_IRUGO, adt7316_show_device_rev, NULL, 0);
165335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
165435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_bus_type(struct device *dev,
165535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
165635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
165735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
165835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
165970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
166035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 stat;
166135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
166235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
166335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_SPI_LOCK_STAT, &stat);
166435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
166535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
166635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
166735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (stat)
166835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "spi\n");
166935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
167035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "i2c\n");
167135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
167235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
167335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
167435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
167535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7316_attributes[] = {
167635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_modes.dev_attr.attr,
167735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_mode.dev_attr.attr,
167835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_reset.dev_attr.attr,
167935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enabled.dev_attr.attr,
168035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ad_channel.dev_attr.attr,
168135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_ad_channels.dev_attr.attr,
168235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_disable_averaging.dev_attr.attr,
168335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
168435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_powerdown.dev_attr.attr,
168535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
168635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_da_high_resolution.dev_attr.attr,
168735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
168835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
168935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
169035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
169135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
169235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_update_DAC.dev_attr.attr,
169335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
169435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
169535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
169635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_VDD.dev_attr.attr,
169735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp.dev_attr.attr,
169835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp.dev_attr.attr,
169935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp_offset.dev_attr.attr,
170035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
170135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
170235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
170335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_A.dev_attr.attr,
170435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_B.dev_attr.attr,
170535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_C.dev_attr.attr,
170635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_D.dev_attr.attr,
170735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_id.dev_attr.attr,
170835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_manufactorer_id.dev_attr.attr,
170935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_rev.dev_attr.attr,
171035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_bus_type.dev_attr.attr,
171135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
171235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
171335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
171435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic const struct attribute_group adt7316_attribute_group = {
171535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7316_attributes,
171635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
171735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
171835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7516_attributes[] = {
171935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_modes.dev_attr.attr,
172035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_mode.dev_attr.attr,
172135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_select_ex_temp.dev_attr.attr,
172235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_reset.dev_attr.attr,
172335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enabled.dev_attr.attr,
172435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ad_channel.dev_attr.attr,
172535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_ad_channels.dev_attr.attr,
172635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_disable_averaging.dev_attr.attr,
172735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
172835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_powerdown.dev_attr.attr,
172935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
173035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN_internal_Vref.dev_attr.attr,
173135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_da_high_resolution.dev_attr.attr,
173235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
173335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
173435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
173535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
173635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
173735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_update_DAC.dev_attr.attr,
173835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
173935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
174035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
174135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_VDD.dev_attr.attr,
174235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp.dev_attr.attr,
174335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp_AIN1.dev_attr.attr,
174435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN2.dev_attr.attr,
174535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN3.dev_attr.attr,
174635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN4.dev_attr.attr,
174735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp_offset.dev_attr.attr,
174835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
174935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
175035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
175135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_A.dev_attr.attr,
175235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_B.dev_attr.attr,
175335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_C.dev_attr.attr,
175435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_D.dev_attr.attr,
175535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_id.dev_attr.attr,
175635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_manufactorer_id.dev_attr.attr,
175735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_rev.dev_attr.attr,
175835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_bus_type.dev_attr.attr,
175935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
176035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
176135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
176235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic const struct attribute_group adt7516_attribute_group = {
176335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7516_attributes,
176435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
176535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
176690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic irqreturn_t adt7316_event_handler(int irq, void *private)
176735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
176890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	struct iio_dev *indio_dev = private;
176970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(indio_dev);
177035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 stat1, stat2;
1771383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron	int ret;
1772383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron	s64 time;
177335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
177435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1);
177535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!ret) {
1776383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
1777383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron			stat1 &= 0x1F;
177835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
1779383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		time = iio_get_time_ns();
1780383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 0))
17815aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
1782383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
1783383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1784383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_RISING),
1785383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
1786383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 1))
17875aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
1788383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
1789383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1790383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_FALLING),
1791383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
1792383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 2))
17935aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
1794383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
1795383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1796383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_RISING),
1797383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
1798383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 3))
17995aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
1800383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
1801383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1802383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_FALLING),
1803383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
1804383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 5))
18055aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
18066835cb6b438b77ba82ad5a23944bbfb12128f5dbJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1,
1807383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1808383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_EITHER),
1809383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
1810383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 6))
18115aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
18126835cb6b438b77ba82ad5a23944bbfb12128f5dbJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2,
1813383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1814383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_EITHER),
1815383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
1816383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron		if (stat1 & (1 << 7))
18175aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
18186835cb6b438b77ba82ad5a23944bbfb12128f5dbJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3,
1819383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1820383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_EITHER),
1821383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron				       time);
182235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		}
182335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2);
182435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!ret) {
182535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (stat2 & ADT7316_INT_MASK2_VDD)
18265aa9618896e0ba49b444731f9fafa7f7c18a13abJonathan Cameron			iio_push_event(indio_dev,
18276835cb6b438b77ba82ad5a23944bbfb12128f5dbJonathan Cameron				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
1828383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    0,
1829383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_TYPE_THRESH,
1830383f650f6cf739b256eb24c4a1d397d883de56ffJonathan Cameron							    IIO_EV_DIR_RISING),
183190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron				       iio_get_time_ns());
183235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
183335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
183490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	return IRQ_HANDLED;
183535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
183635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
183735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
183835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Show mask of enabled interrupts in Hex.
183935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
184035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_int_mask(struct device *dev,
184135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
184235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
184335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
184435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
184570be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
184635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
184735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "0x%x\n", chip->int_mask);
184835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
184935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
185035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
185135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Set 1 to the mask in Hex to enabled interrupts.
185235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
185335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_set_int_mask(struct device *dev,
185435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
185535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
185635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
185735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
185835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
185970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
186035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
186135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
186235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 mask;
186335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
186435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 16, &data);
186535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data >= ADT7316_VDD_INT_MASK + 1)
186635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
186735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
186835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data & ADT7316_VDD_INT_MASK)
186935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		mask = 0;			/* enable vdd int */
187035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
187135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		mask = ADT7316_INT_MASK2_VDD;	/* disable vdd int */
187235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
187335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK2, mask);
187435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!ret) {
187535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->int_mask &= ~ADT7316_VDD_INT_MASK;
187635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->int_mask |= data & ADT7316_VDD_INT_MASK;
187735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
187835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
187935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data & ADT7316_TEMP_AIN_INT_MASK) {
188035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX)
188135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			/* mask in reg is opposite, set 1 to disable */
188235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			mask = (~data) & ADT7316_TEMP_INT_MASK;
188335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
188435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			/* mask in reg is opposite, set 1 to disable */
188535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			mask = (~data) & ADT7316_TEMP_AIN_INT_MASK;
188635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
188735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK1, mask);
188835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
188935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->int_mask = mask;
189035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
189135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
189235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
189335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_show_ad_bound(struct device *dev,
189435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
189535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
189635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
189790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
189835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
189970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
190035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
190135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int data;
190235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
190335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
190435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
190590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		this_attr->address > ADT7316_EX_TEMP_LOW)
190635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
190735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
190890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	ret = chip->bus.read(chip->bus.client, this_attr->address, &val);
190935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
191035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
191135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
191235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	data = (int)val;
191335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
191435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
191535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) {
191635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data & 0x80)
191735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			data -= 256;
191835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
191935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
192035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", data);
192135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
192235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
192335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ad_bound(struct device *dev,
192435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
192535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
192635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
192735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
192890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
192935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
193070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
193135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	long data;
193235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
193335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
193435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
193535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
193690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		this_attr->address > ADT7316_EX_TEMP_LOW)
193735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
193835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
193935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtol(buf, 10, &data);
194035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
194135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
194235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
194335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
194435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) {
194535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 255 || data < 0)
194635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
194735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
194835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 127 || data < -128)
194935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
195035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
195135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data < 0)
195235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			data += 256;
195335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
195435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
195535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	val = (u8)data;
195635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
195790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	ret = chip->bus.write(chip->bus.client, this_attr->address, val);
195835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
195935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
196035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
196135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
196235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
196335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
196435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_int_enabled(struct device *dev,
196535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
196635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
196735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
196835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
196970be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
197035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
197135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN));
197235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
197335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
197435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_set_int_enabled(struct device *dev,
197535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
197635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
197735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
197835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
197935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
198070be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
198135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
198235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
198335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
198435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config1 = chip->config1 & (~ADT7316_INT_EN);
198535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
198635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 |= ADT7316_INT_EN;
198735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
198835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
198935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
199035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
199135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
199235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
199335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
199435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
199535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
199635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
199790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(int_mask,
199890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
199990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_int_mask, adt7316_set_int_mask,
200090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       0);
200190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(in_temp_high_value,
200290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
200390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
200490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7316_IN_TEMP_HIGH);
200590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(in_temp_low_value,
200690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
200790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
200890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7316_IN_TEMP_LOW);
200990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ex_temp_high_value,
201090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
201190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
201290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7316_EX_TEMP_HIGH);
201390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ex_temp_low_value,
201490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
201590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
201690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7316_EX_TEMP_LOW);
201790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron
201890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron/* NASTY duplication to be fixed */
201990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ex_temp_ain1_high_value,
202090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
202190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
202290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7316_EX_TEMP_HIGH);
202390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ex_temp_ain1_low_value,
202490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
202590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
202690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7316_EX_TEMP_LOW);
202790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ain2_high_value,
202890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
202990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
203090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7516_AIN2_HIGH);
203190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ain2_low_value,
203290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
203390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
203490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7516_AIN2_LOW);
203590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ain3_high_value,
203690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
203790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
203890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7516_AIN3_HIGH);
203990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ain3_low_value,
204090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
204190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
204290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7516_AIN3_LOW);
204390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ain4_high_value,
204490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
204590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
204690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7516_AIN4_HIGH);
204790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(ain4_low_value,
204890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
204990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_ad_bound, adt7316_set_ad_bound,
205090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       ADT7516_AIN4_LOW);
205190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameronstatic IIO_DEVICE_ATTR(int_enabled,
205290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       S_IRUGO | S_IWUSR,
205390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_show_int_enabled,
205490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		       adt7316_set_int_enabled, 0);
205535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
205635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7316_event_attributes[] = {
205790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_int_mask.dev_attr.attr,
205890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_in_temp_high_value.dev_attr.attr,
205990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_in_temp_low_value.dev_attr.attr,
206090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ex_temp_high_value.dev_attr.attr,
206190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ex_temp_low_value.dev_attr.attr,
206290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_int_enabled.dev_attr.attr,
206335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
206435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
206535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
206635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute_group adt7316_event_attribute_group = {
206735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7316_event_attributes,
20688e7d967244a8eebcdadb048efc5e66849ec0a6b6Jonathan Cameron	.name = "events",
206935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
207035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
207135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7516_event_attributes[] = {
207290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_int_mask.dev_attr.attr,
207390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_in_temp_high_value.dev_attr.attr,
207490f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_in_temp_low_value.dev_attr.attr,
207590f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ex_temp_ain1_high_value.dev_attr.attr,
207690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ex_temp_ain1_low_value.dev_attr.attr,
207790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ain2_high_value.dev_attr.attr,
207890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ain2_low_value.dev_attr.attr,
207990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ain3_high_value.dev_attr.attr,
208090f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ain3_low_value.dev_attr.attr,
208190f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ain4_high_value.dev_attr.attr,
208290f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_ain4_low_value.dev_attr.attr,
208390f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron	&iio_dev_attr_int_enabled.dev_attr.attr,
208435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
208535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
208635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
208735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute_group adt7516_event_attribute_group = {
208835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7516_event_attributes,
20898e7d967244a8eebcdadb048efc5e66849ec0a6b6Jonathan Cameron	.name = "events",
209035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
209135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
209201788c533acbd63702146a2be975ae4007cfb2cfLars-Peter Clausen#ifdef CONFIG_PM_SLEEP
209301788c533acbd63702146a2be975ae4007cfb2cfLars-Peter Clausenstatic int adt7316_disable(struct device *dev)
209435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
209535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
209670be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
209735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
209835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return _adt7316_store_enabled(chip, 0);
209935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
210035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
210101788c533acbd63702146a2be975ae4007cfb2cfLars-Peter Clausenstatic int adt7316_enable(struct device *dev)
210235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
210335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
210470be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(dev_info);
210535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
210635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return _adt7316_store_enabled(chip, 1);
210735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
210801788c533acbd63702146a2be975ae4007cfb2cfLars-Peter Clausen
210901788c533acbd63702146a2be975ae4007cfb2cfLars-Peter ClausenSIMPLE_DEV_PM_OPS(adt7316_pm_ops, adt7316_disable, adt7316_enable);
211001788c533acbd63702146a2be975ae4007cfb2cfLars-Peter ClausenEXPORT_SYMBOL_GPL(adt7316_pm_ops);
211135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#endif
211235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
21136fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameronstatic const struct iio_info adt7316_info = {
21146fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	.attrs = &adt7316_attribute_group,
21156fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	.event_attrs = &adt7316_event_attribute_group,
21166fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	.driver_module = THIS_MODULE,
21176fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron};
21186fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron
21196fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameronstatic const struct iio_info adt7516_info = {
21206fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	.attrs = &adt7516_attribute_group,
21216fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	.event_attrs = &adt7516_event_attribute_group,
21226fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	.driver_module = THIS_MODULE,
21236fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron};
21246fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron
212535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
212635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * device probe and remove
212735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
212835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangint __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
212935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *name)
213035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
213135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip;
213270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct iio_dev *indio_dev;
213335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned short *adt7316_platform_data = dev->platform_data;
213435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret = 0;
213535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
213670be42919a876af79187ce5385914597988583f9Jonathan Cameron	indio_dev = iio_allocate_device(sizeof(*chip));
213770be42919a876af79187ce5385914597988583f9Jonathan Cameron	if (indio_dev == NULL) {
213870be42919a876af79187ce5385914597988583f9Jonathan Cameron		ret = -ENOMEM;
213970be42919a876af79187ce5385914597988583f9Jonathan Cameron		goto error_ret;
214070be42919a876af79187ce5385914597988583f9Jonathan Cameron	}
214170be42919a876af79187ce5385914597988583f9Jonathan Cameron	chip = iio_priv(indio_dev);
214235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	/* this is only used for device removal purposes */
214370be42919a876af79187ce5385914597988583f9Jonathan Cameron	dev_set_drvdata(dev, indio_dev);
214435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
214535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->bus = *bus;
214635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
214735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (name[4] == '3')
214835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->id = ID_ADT7316 + (name[6] - '6');
214935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else if (name[4] == '5')
215035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->id = ID_ADT7516 + (name[6] - '6');
215135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
215235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -ENODEV;
215335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
215435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->ldac_pin = adt7316_platform_data[1];
215535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->ldac_pin) {
215635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA;
215735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
215835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->config1 |= ADT7516_SEL_AIN3;
215935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
216035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->int_mask = ADT7316_TEMP_INT_MASK | ADT7316_VDD_INT_MASK;
216135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
216235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->int_mask |= ADT7516_AIN_INT_MASK;
216335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
216470be42919a876af79187ce5385914597988583f9Jonathan Cameron	indio_dev->dev.parent = dev;
21656fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
216670be42919a876af79187ce5385914597988583f9Jonathan Cameron		indio_dev->info = &adt7516_info;
21676fe8135fccd66aedcc55ded70824342587fd2499Jonathan Cameron	else
216870be42919a876af79187ce5385914597988583f9Jonathan Cameron		indio_dev->info = &adt7316_info;
216970be42919a876af79187ce5385914597988583f9Jonathan Cameron	indio_dev->name = name;
217070be42919a876af79187ce5385914597988583f9Jonathan Cameron	indio_dev->modes = INDIO_DIRECT_MODE;
217135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
217235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->bus.irq > 0) {
217335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (adt7316_platform_data[0])
217435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->bus.irq_flags = adt7316_platform_data[0];
217535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
217690f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron		ret = request_threaded_irq(chip->bus.irq,
217790f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron					   NULL,
217890f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron					   &adt7316_event_handler,
217990f79e76871b570480d87ac15603aa2685008f78Jonathan Cameron					   chip->bus.irq_flags | IRQF_ONESHOT,
218070be42919a876af79187ce5385914597988583f9Jonathan Cameron					   indio_dev->name,
218170be42919a876af79187ce5385914597988583f9Jonathan Cameron					   indio_dev);
218235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
218326d25ae3f0d8ffe350aacc75b71198d6b35bd1f4Jonathan Cameron			goto error_free_dev;
218435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
218535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
218635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->config1 |= ADT7316_INT_POLARITY;
218735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
218835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
218935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
219035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret) {
219135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = -EIO;
219235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		goto error_unreg_irq;
219335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
219435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
219535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
219635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret) {
219735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = -EIO;
219835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		goto error_unreg_irq;
219935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
220035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
220126d25ae3f0d8ffe350aacc75b71198d6b35bd1f4Jonathan Cameron	ret = iio_device_register(indio_dev);
220226d25ae3f0d8ffe350aacc75b71198d6b35bd1f4Jonathan Cameron	if (ret)
220326d25ae3f0d8ffe350aacc75b71198d6b35bd1f4Jonathan Cameron		goto error_unreg_irq;
220426d25ae3f0d8ffe350aacc75b71198d6b35bd1f4Jonathan Cameron
220535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
220670be42919a876af79187ce5385914597988583f9Jonathan Cameron			indio_dev->name);
220735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
220835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return 0;
220935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
221035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangerror_unreg_irq:
221170be42919a876af79187ce5385914597988583f9Jonathan Cameron	free_irq(chip->bus.irq, indio_dev);
221235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangerror_free_dev:
221370be42919a876af79187ce5385914597988583f9Jonathan Cameron	iio_free_device(indio_dev);
221470be42919a876af79187ce5385914597988583f9Jonathan Cameronerror_ret:
221535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return ret;
221635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
221735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangEXPORT_SYMBOL(adt7316_probe);
221835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
221935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangint __devexit adt7316_remove(struct device *dev)
222035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
222170be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct iio_dev *indio_dev = dev_get_drvdata(dev);
222270be42919a876af79187ce5385914597988583f9Jonathan Cameron	struct adt7316_chip_info *chip = iio_priv(indio_dev);
222335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
2224d2fffd6c2fd60fe9ab63ef30758d9d43a5057549Jonathan Cameron	iio_device_unregister(indio_dev);
222535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->bus.irq)
222670be42919a876af79187ce5385914597988583f9Jonathan Cameron		free_irq(chip->bus.irq, indio_dev);
2227d2fffd6c2fd60fe9ab63ef30758d9d43a5057549Jonathan Cameron	iio_free_device(indio_dev);
222835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
222935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return 0;
223035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
223135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangEXPORT_SYMBOL(adt7316_remove);
223235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
223335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangMODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
223435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangMODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital"
223535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			" temperature sensor, ADC and DAC driver");
223635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangMODULE_LICENSE("GPL v2");
2237