adt7316.c revision 35f6b6b86ede34a9f8c029943842640b2ffbfa19
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>
2035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
2135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include "../iio.h"
2235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include "../sysfs.h"
2335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#include "adt7316.h"
2435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
2535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
2635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 registers definition
2735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
2835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_STAT1		0x0
2935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_STAT2		0x1
3035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_IN_TEMP_VDD		0x3
3135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_IN_TEMP_MASK	0x3
3235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_VDD_MASK		0xC
3335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_VDD_OFFSET		2
3435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_EX_TEMP_AIN		0x4
3535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_EX_TEMP_MASK	0x3
3635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_LSB_AIN_SHIFT		2
3735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_MSB_DATA_BASE        0x6
3835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_MSB_DATA_REGS        3
3935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_MSB_DATA_REGS        6
4035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_VDD			0x6
4135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_IN_TEMP		0x7
4235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_EX_TEMP		0x8
4335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN1		0x8
4435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN2		0x9
4535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN3		0xA
4635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_MSB_AIN4		0xB
4735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_DATA_BASE		0x10
4835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_MSB_DATA_REGS	4
4935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_A		0x10
5035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_A		0x11
5135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_B		0x12
5235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_B		0x13
5335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_C		0x14
5435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_C		0x15
5535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LSB_DAC_D		0x16
5635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MSB_DAC_D		0x17
5735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_CONFIG1			0x18
5835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_CONFIG2			0x19
5935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_CONFIG3			0x1A
6035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LDAC_CONFIG		0x1B
6135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DAC_CONFIG		0x1C
6235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_MASK1		0x1D
6335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_MASK2		0x1E
6435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_OFFSET		0x1F
6535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_OFFSET		0x20
6635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_ANALOG_TEMP_OFFSET	0x21
6735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_ANALOG_TEMP_OFFSET	0x22
6835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VDD_HIGH		0x23
6935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VDD_LOW			0x24
7035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_HIGH		0x25
7135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_LOW		0x26
7235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_HIGH		0x27
7335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_LOW		0x28
7435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN2_HIGH		0x2B
7535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN2_LOW		0x2C
7635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN3_HIGH		0x2D
7735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN3_LOW		0x2E
7835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN4_HIGH		0x2F
7935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN4_LOW		0x30
8035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DEVICE_ID		0x4D
8135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_MANUFACTURE_ID		0x4E
8235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DEVICE_REV		0x4F
8335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_SPI_LOCK_STAT		0x7F
8435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
8535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
8635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 config1
8735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
8835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN			0x1
8935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_SEL_EX_TEMP		0x4
9035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_SEL_AIN1_2_EX_TEMP_MASK	0x6
9135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_SEL_AIN3		0x8
9235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_EN			0x20
9335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_POLARITY		0x40
9435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_PD			0x80
9535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
9635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
9735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 config2
9835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
9935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_MASK	0x3
10035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_MASK	0x7
10135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_VDD	0
10235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_IN		1
10335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_EX		2
10435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN1	2
10535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN2	3
10635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN3	4
10735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AD_SINGLE_CH_AIN4	5
10835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_AD_SINGLE_CH_MODE	0x10
10935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DISABLE_AVERAGING	0x20
11035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN_SMBUS_TIMEOUT	0x40
11135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_RESET			0x80
11235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
11335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
11435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 config3
11535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
11635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_ADCLK_22_5		0x1
11735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_HIGH_RESOLUTION	0x2
11835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_VIA_DAC_LDCA	0x4
11935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN_IN_VREF		0x10
12035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN_IN_TEMP_PROP_DACA	0x20
12135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EN_EX_TEMP_PROP_DACB	0x40
12235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
12335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
12435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 DAC config
12535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
12635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_2VREF_CH_MASK	0xF
12735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_MASK		0x30
12835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_SINGLE	0x00
12935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_AB_CD	0x10
13035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_ABCD		0x20
13135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DA_EN_MODE_LDAC		0x30
13235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VREF_BYPASS_DAC_AB	0x40
13335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VREF_BYPASS_DAC_CD	0x80
13435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
13535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
13635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 LDAC config
13735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
13835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_LDAC_EN_DA_MASK		0xF
13935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_DAC_IN_VREF		0x10
14035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_AB_IN_VREF		0x10
14135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_CD_IN_VREF		0x20
14235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_IN_VREF_OFFSET	4
14335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_DAC_IN_VREF_MASK	0x30
14435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
14535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
14635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 INT_MASK2
14735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
14835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_INT_MASK2_VDD		0x10
14935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
15035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
15135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * ADT7316 value masks
15235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
15335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VALUE_MASK		0xfff
15435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_T_VALUE_SIGN		0x400
15535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_T_VALUE_FLOAT_OFFSET	2
15635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_T_VALUE_FLOAT_MASK	0x2
15735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
15835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
15935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Chip ID
16035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
16135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7316		0x1
16235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7317		0x2
16335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7318		0x3
16435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7516		0x11
16535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7517		0x12
16635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT7519		0x14
16735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
16835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_FAMILY_MASK		0xF0
16935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT73XX		0x0
17035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ID_ADT75XX		0x10
17135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
17235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
17335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * struct adt7316_chip_info - chip specifc information
17435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
17535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
17635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstruct adt7316_chip_info {
17735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	const char		*name;
17835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev		*indio_dev;
17935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct work_struct	thresh_work;
18035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	s64			last_timestamp;
18135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_bus	bus;
18235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16			ldac_pin;
18335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16			int_mask;	/* 0x2f */
18435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			config1;
18535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			config2;
18635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			config3;
18735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			dac_config;	/* DAC config */
18835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			ldac_config;	/* LDAC config */
18935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			dac_bits;	/* 8, 10, 12 */
19035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8			id;		/* chip id */
19135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
19235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
19335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
19435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Logic interrupt mask for user application to enable
19535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * interrupts.
19635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
19735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_HIGH_INT_MASK	0x1
19835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_IN_TEMP_LOW_INT_MASK	0x2
19935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_HIGH_INT_MASK	0x4
20035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_LOW_INT_MASK	0x8
20135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_EX_TEMP_FAULT_INT_MASK	0x10
20235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN1_INT_MASK		0x4
20335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN2_INT_MASK		0x20
20435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN3_INT_MASK		0x40
20535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN4_INT_MASK		0x80
20635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_VDD_INT_MASK		0x100
20735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_TEMP_INT_MASK		0x1F
20835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7516_AIN_INT_MASK		0xE0
20935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define ADT7316_TEMP_AIN_INT_MASK	\
21035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	(ADT7316_TEMP_INT_MASK | ADT7316_TEMP_INT_MASK)
21135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
21235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
21335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * struct adt7316_chip_info - chip specifc information
21435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
21535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
21635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstruct adt7316_limit_regs {
21735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16	data_high;
21835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16	data_low;
21935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
22035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
22135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enabled(struct device *dev,
22235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
22335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
22435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
22535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
22635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
22735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
22835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN));
22935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
23035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
23135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip,
23235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int enable)
23335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
23435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
23535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
23635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
23735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (enable)
23835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 = chip->config1 | ADT7316_EN;
23935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
24035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 = chip->config1 & ~ADT7316_EN;
24135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
24335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
24435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
24535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
24735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
24835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return ret;
24935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
25035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
25135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
25235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enabled(struct device *dev,
25335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
25435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
25535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
25635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
25735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
25835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
25935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int enable;
26035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
26135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
26235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		enable = 1;
26335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
26435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		enable = 0;
26535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
26635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (_adt7316_store_enabled(chip, enable) < 0)
26735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
26835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
26935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return len;
27035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
27135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
27235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR,
27335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enabled,
27435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enabled,
27535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
27635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
27735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_select_ex_temp(struct device *dev,
27835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
27935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
28035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
28135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
28235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
28335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
28435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
28535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
28635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
28735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP));
28835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
28935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
29035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_select_ex_temp(struct device *dev,
29135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
29235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
29335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
29435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
29535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
29635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
29735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
29835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
29935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
30035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
30135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
30235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
30335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config1 = chip->config1 & (~ADT7516_SEL_EX_TEMP);
30435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
30535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 |= ADT7516_SEL_EX_TEMP;
30635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
30735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
30835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
30935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
31035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
31135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
31235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
31335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
31435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
31535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
31635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(select_ex_temp, S_IRUGO | S_IWUSR,
31735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_select_ex_temp,
31835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_select_ex_temp,
31935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
32035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
32135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_mode(struct device *dev,
32235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
32335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
32435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
32535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
32635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
32735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
32835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE)
32935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "single_channel\n");
33035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
33135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "round_robin\n");
33235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
33335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
33435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_mode(struct device *dev,
33535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
33635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
33735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
33835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
33935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
34035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
34135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
34235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
34335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
34435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MODE);
34535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "single_channel", 14))
34635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 |= ADT7316_AD_SINGLE_CH_MODE;
34735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
34835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
34935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
35035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
35135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
35235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
35335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
35435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
35535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
35635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
35735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
35835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_mode,
35935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_mode,
36035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
36135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
36235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_all_modes(struct device *dev,
36335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
36435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
36535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
36635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "single_channel\nround_robin\n");
36735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
36835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
36935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(all_modes, S_IRUGO, adt7316_show_all_modes, NULL, 0);
37035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
37135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ad_channel(struct device *dev,
37235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
37335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
37435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
37535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
37635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
37735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
37835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
37935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
38035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
38135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) {
38235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_VDD:
38335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - VDD\n");
38435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_IN:
38535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "1 - Internal Temperature\n");
38635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_EX:
38735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) &&
38835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
38935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "2 - AIN1\n");
39035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
39135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "2 - External Temperature\n");
39235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7516_AD_SINGLE_CH_AIN2:
39335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
39435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "3 - AIN2\n");
39535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
39635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "N/A\n");
39735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7516_AD_SINGLE_CH_AIN3:
39835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->config1 & ADT7516_SEL_AIN3)
39935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "4 - AIN3\n");
40035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
40135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "N/A\n");
40235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7516_AD_SINGLE_CH_AIN4:
40335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "5 - AIN4\n");
40435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	default:
40535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "N/A\n");
40635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	};
40735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
40835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
40935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_ad_channel(struct device *dev,
41035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
41135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
41235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
41335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
41435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
41535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
41635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
41735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data = 0;
41835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
41935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
42035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
42135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
42235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
42335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 10, &data);
42435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
42535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
42635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
42735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
42835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 5)
42935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
43035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
43135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 = chip->config2 & (~ADT7516_AD_SINGLE_CH_MASK);
43235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
43335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 2)
43435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
43535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
43635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MASK);
43735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
43835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
43935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 |= data;
44135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
44335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
44435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
44535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
44735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
44835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
44935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
45035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
45135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ad_channel, S_IRUGO | S_IWUSR,
45235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ad_channel,
45335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_ad_channel,
45435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
45535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
45635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_all_ad_channels(struct device *dev,
45735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
45835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
45935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
46035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
46135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
46235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
46335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
46435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
46535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
46635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
46735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
46835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"2 - External Temperature or AIN2\n"
46935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
47035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
47135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
47235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"2 - External Temperature\n");
47335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
47435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
47535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(all_ad_channels, S_IRUGO,
47635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_all_ad_channels, NULL, 0);
47735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
47835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_disable_averaging(struct device *dev,
47935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
48035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
48135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
48235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
48335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
48435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
48535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
48635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config2 & ADT7316_DISABLE_AVERAGING));
48735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
48835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
48935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_disable_averaging(struct device *dev,
49035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
49135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
49235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
49335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
49435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
49535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
49635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
49735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
49835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
49935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 & (~ADT7316_DISABLE_AVERAGING);
50035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
50135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 |= ADT7316_DISABLE_AVERAGING;
50235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
50335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
50435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
50535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
50635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
50735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
50835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
50935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
51035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
51135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
51235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(disable_averaging, S_IRUGO | S_IWUSR,
51335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_disable_averaging,
51435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_disable_averaging,
51535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
51635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
51735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enable_smbus_timeout(struct device *dev,
51835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
51935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
52035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
52135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
52235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
52335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
52435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
52535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT));
52635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
52735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
52835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enable_smbus_timeout(struct device *dev,
52935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
53035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
53135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
53235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
53335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
53435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
53535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
53635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
53735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
53835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 & (~ADT7316_EN_SMBUS_TIMEOUT);
53935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
54035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config2 |= ADT7316_EN_SMBUS_TIMEOUT;
54135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
54335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
54435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
54535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config2 = config2;
54735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
54835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
54935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
55035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
55135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
55235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enable_smbus_timeout,
55335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enable_smbus_timeout,
55435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
55535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
55635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
55735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_reset(struct device *dev,
55835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
55935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
56035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
56135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
56235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
56335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
56435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config2;
56535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
56635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
56735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config2 = chip->config2 | ADT7316_RESET;
56835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
56935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
57035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
57135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
57235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
57335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
57435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
57535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
57635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(reset, S_IWUSR,
57735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		NULL,
57835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_reset,
57935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
58035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
58135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_powerdown(struct device *dev,
58235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
58335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
58435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
58535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
58635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
58735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
58835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD));
58935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
59035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
59135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_powerdown(struct device *dev,
59235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
59335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
59435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
59535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
59635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
59735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
59835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
59935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
60035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
60135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config1 = chip->config1 & (~ADT7316_PD);
60235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
60335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 |= ADT7316_PD;
60435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
60535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
60635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
60735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
60835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
60935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
61035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
61135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
61235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
61335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
61435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(powerdown, S_IRUGO | S_IWUSR,
61535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_powerdown,
61635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_powerdown,
61735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
61835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
61935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_fast_ad_clock(struct device *dev,
62035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
62135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
62235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
62335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
62435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
62535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
62635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5));
62735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
62835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
62935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_fast_ad_clock(struct device *dev,
63035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
63135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
63235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
63335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
63435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
63535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
63635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
63735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
63835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
63935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config3 = chip->config3 & (~ADT7316_ADCLK_22_5);
64035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
64135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 |= ADT7316_ADCLK_22_5;
64235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
64335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
64435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
64535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
64635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
64735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
64835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
64935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
65035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
65135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
65235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(fast_ad_clock, S_IRUGO | S_IWUSR,
65335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_fast_ad_clock,
65435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_fast_ad_clock,
65535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
65635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
65735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_da_high_resolution(struct device *dev,
65835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
65935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
66035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
66135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
66235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
66335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
66435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) {
66535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
66635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "1 (12 bits)\n");
66735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
66835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "1 (10 bits)\n");
66935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
67035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
67135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "0 (8 bits)\n");
67235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
67335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
67435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_da_high_resolution(struct device *dev,
67535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
67635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
67735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
67835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
67935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
68035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
68135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
68235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
68335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
68435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_bits = 8;
68535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
68635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1)) {
68735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION;
68835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
68935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->dac_bits = 12;
69035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
69135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->dac_bits = 10;
69235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else
69335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION);
69435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
69535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
69635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
69735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
69835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
69935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
70035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
70135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
70235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
70335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
70435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(da_high_resolution, S_IRUGO | S_IWUSR,
70535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_da_high_resolution,
70635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_da_high_resolution,
70735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
70835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
70935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN_internal_Vref(struct device *dev,
71035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
71135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
71235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
71335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
71435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
71535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
71635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
71735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
71835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
71935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
72035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config3 & ADT7516_AIN_IN_VREF));
72135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
72235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
72335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_AIN_internal_Vref(struct device *dev,
72435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
72535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
72635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
72735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
72835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
72935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
73035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
73135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
73235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
73335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
73435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
73535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
73635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (memcmp(buf, "1", 1))
73735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 & (~ADT7516_AIN_IN_VREF);
73835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
73935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 = chip->config3 | ADT7516_AIN_IN_VREF;
74035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
74135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
74235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
74335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
74435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
74535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
74635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
74735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
74835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
74935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
75035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN_internal_Vref, S_IRUGO | S_IWUSR,
75135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_AIN_internal_Vref,
75235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_AIN_internal_Vref,
75335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
75435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
75535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
75635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enable_prop_DACA(struct device *dev,
75735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
75835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
75935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
76035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
76135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
76235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
76335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
76435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA));
76535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
76635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
76735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enable_prop_DACA(struct device *dev,
76835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
76935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
77035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
77135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
77235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
77335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
77435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
77535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
77635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
77735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config3 = chip->config3 & (~ADT7316_EN_IN_TEMP_PROP_DACA);
77835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
77935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 |= ADT7316_EN_IN_TEMP_PROP_DACA;
78035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
78135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
78235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
78335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
78435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
78535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
78635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
78735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
78835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
78935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
79035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enable_proportion_DACA, S_IRUGO | S_IWUSR,
79135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enable_prop_DACA,
79235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enable_prop_DACA,
79335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
79435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
79535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_enable_prop_DACB(struct device *dev,
79635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
79735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
79835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
79935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
80035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
80135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
80235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
80335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB));
80435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
80535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
80635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_enable_prop_DACB(struct device *dev,
80735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
80835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
80935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
81035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
81135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
81235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
81335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config3;
81435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
81535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
81635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config3 = chip->config3 & (~ADT7316_EN_EX_TEMP_PROP_DACB);
81735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
81835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config3 |= ADT7316_EN_EX_TEMP_PROP_DACB;
81935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
82135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
82235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
82335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config3 = config3;
82535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
82735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
82835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
82935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(enable_proportion_DACB, S_IRUGO | S_IWUSR,
83035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_enable_prop_DACB,
83135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_enable_prop_DACB,
83235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
83335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
83435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev,
83535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
83635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
83735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
83835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
83935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
84035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
84135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "0x%x\n",
84235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->dac_config & ADT7316_DA_2VREF_CH_MASK);
84335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
84435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
84535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
84635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
84735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
84835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
84935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
85035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
85135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
85235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
85335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data = 0;
85435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
85535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
85635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 16, &data);
85735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data > ADT7316_DA_2VREF_CH_MASK)
85835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
85935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_DA_2VREF_CH_MASK);
86135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config |= data;
86235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
86435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
86535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
86635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
86835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
86935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
87035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
87135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
87235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, S_IRUGO | S_IWUSR,
87335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DAC_2Vref_ch_mask,
87435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_2Vref_ch_mask,
87535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
87635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
87735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_update_mode(struct device *dev,
87835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
87935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
88035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
88135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
88235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
88335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
88435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
88535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "manual\n");
88635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else {
88735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) {
88835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		case ADT7316_DA_EN_MODE_SINGLE:
88935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "0 - auto at any MSB DAC writing\n");
89035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		case ADT7316_DA_EN_MODE_AB_CD:
89135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "1 - auto at MSB DAC AB and CD writing\n");
89235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		case ADT7316_DA_EN_MODE_ABCD:
89335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "2 - auto at MSB DAC ABCD writing\n");
89435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		default: /* ADT7316_DA_EN_MODE_LDAC */
89535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "3 - manual\n");
89635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		};
89735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
89835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
89935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
90035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_update_mode(struct device *dev,
90135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
90235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
90335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
90435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
90535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
90635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
90735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
90835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
90935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
91035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
91135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
91235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
91335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
91435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 10, &data);
91535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data > ADT7316_DA_EN_MODE_MASK)
91635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
91735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
91835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_DA_EN_MODE_MASK);
91935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config |= data;
92035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
92135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
92235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
92335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
92435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
92535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
92635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
92735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
92835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
92935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
93035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_update_mode, S_IRUGO | S_IWUSR,
93135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DAC_update_mode,
93235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_update_mode,
93335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
93435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
93535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_all_DAC_update_modes(struct device *dev,
93635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
93735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
93835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
93935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
94035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
94135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
94235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)
94335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0 - auto at any MSB DAC writing\n"
94435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"1 - auto at MSB DAC AB and CD writing\n"
94535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"2 - auto at MSB DAC ABCD writing\n"
94635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				"3 - manual\n");
94735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
94835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "manual\n");
94935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
95035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
95135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(all_DAC_update_modes, S_IRUGO,
95235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_all_DAC_update_modes, NULL, 0);
95335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
95435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
95535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_update_DAC(struct device *dev,
95635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
95735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
95835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
95935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
96035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
96135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
96235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 ldac_config;
96335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
96435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
96535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
96635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
96735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->dac_config & ADT7316_DA_EN_MODE_MASK) !=
96835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_DA_EN_MODE_LDAC)
96935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EPERM;
97035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
97135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = strict_strtoul(buf, 16, &data);
97235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret || data > ADT7316_LDAC_EN_DA_MASK)
97335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
97435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
97535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config = chip->ldac_config & (~ADT7316_LDAC_EN_DA_MASK);
97635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config |= data;
97735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
97835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG,
97935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config);
98035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
98135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
98235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
98335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		gpio_set_value(chip->ldac_pin, 0);
98435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		gpio_set_value(chip->ldac_pin, 1);
98535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
98635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
98735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
98835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
98935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
99035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(update_DAC, S_IRUGO | S_IWUSR,
99135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		NULL,
99235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_update_DAC,
99335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
99435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
99535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev,
99635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
99735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
99835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
99935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
100035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
100135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
100235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
100335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
100435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
100535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
100635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB));
100735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
100835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
100935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev,
101035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
101135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
101235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
101335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
101435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
101535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
101635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
101735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
101835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
101935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
102035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
102135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
102235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB);
102335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
102435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		dac_config |= ADT7316_VREF_BYPASS_DAC_AB;
102535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
102635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
102735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
102835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
102935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
103035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
103135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
103235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
103335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
103435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
103535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DA_AB_Vref_bypass, S_IRUGO | S_IWUSR,
103635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DA_AB_Vref_bypass,
103735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DA_AB_Vref_bypass,
103835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
103935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
104035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev,
104135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
104235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
104335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
104435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
104535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
104635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
104735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
104835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
104935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
105035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n",
105135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD));
105235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
105335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
105435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev,
105535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
105635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
105735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
105835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
105935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
106035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
106135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 dac_config;
106235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
106335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
106435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
106535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
106635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
106735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD);
106835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
106935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		dac_config |= ADT7316_VREF_BYPASS_DAC_CD;
107035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
107135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
107235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
107335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
107435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
107535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->dac_config = dac_config;
107635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
107735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
107835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
107935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
108035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DA_CD_Vref_bypass, S_IRUGO | S_IWUSR,
108135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DA_CD_Vref_bypass,
108235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DA_CD_Vref_bypass,
108335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
108435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
108535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_internal_Vref(struct device *dev,
108635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
108735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
108835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
108935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
109035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
109135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
109235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
109335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "0x%x\n",
109435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >>
109535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_DAC_IN_VREF_OFFSET);
109635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
109735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "%d\n",
109835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			!!(chip->dac_config & ADT7316_DAC_IN_VREF));
109935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
110035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
110135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
110235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
110335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
110435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
110535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
110635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
110735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
110835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 ldac_config;
110935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
111035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
111135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
111235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
111335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = strict_strtoul(buf, 16, &data);
111435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret || data > 3)
111535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
111635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
111735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK);
111835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data & 0x1)
111935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config |= ADT7516_DAC_AB_IN_VREF;
112035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else if (data & 0x2)
112135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config |= ADT7516_DAC_CD_IN_VREF;
112235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
112335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = strict_strtoul(buf, 16, &data);
112435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
112535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
112635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
112735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ldac_config = chip->ldac_config & (~ADT7316_DAC_IN_VREF);
112835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data)
112935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ldac_config = chip->ldac_config | ADT7316_DAC_IN_VREF;
113035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
113135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, ldac_config);
113335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
113435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
113535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->ldac_config = ldac_config;
113735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
113835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
113935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
114035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
114135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_internal_Vref, S_IRUGO | S_IWUSR,
114235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_DAC_internal_Vref,
114335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_internal_Vref,
114435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		0);
114535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
114635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
114735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int channel, char *buf)
114835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
114935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16 data;
115035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 msb, lsb;
115135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	char sign = ' ';
115235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
115335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
115435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) &&
115535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK))
115635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
115735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
115835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	switch (channel) {
115935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_IN:
116035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
116135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_LSB_IN_TEMP_VDD, &lsb);
116235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
116335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
116435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
116535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
116635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
116735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
116835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
116935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
117035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
117135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data |= lsb & ADT7316_LSB_IN_TEMP_MASK;
117235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		break;
117335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	case ADT7316_AD_SINGLE_CH_VDD:
117435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
117535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_LSB_IN_TEMP_VDD, &lsb);
117635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
117735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
117835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
117935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
118035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
118135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
118235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
118335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
118435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
118535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
118635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET;
118735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "%d\n", data);
118835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	default: /* ex_temp and ain */
118935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
119035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_LSB_EX_TEMP_AIN, &lsb);
119135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
119235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
119335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
119435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
119535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
119635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
119735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
119835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
119935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
120035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data |= lsb & (ADT7316_LSB_EX_TEMP_MASK <<
120135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(ADT7516_LSB_AIN_SHIFT * (channel -
120235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			(ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE))));
120335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
120435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
120535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return sprintf(buf, "%d\n", data);
120635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
120735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			break;
120835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	};
120935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
121035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data & ADT7316_T_VALUE_SIGN) {
121135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		/* convert supplement to positive value */
121235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data = (ADT7316_T_VALUE_SIGN << 1) - data;
121335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		sign = '-';
121435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
121535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
121635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%c%d.%.2d\n", sign,
121735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(data >> ADT7316_T_VALUE_FLOAT_OFFSET),
121835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(data & ADT7316_T_VALUE_FLOAT_MASK) * 25);
121935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
122035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
122135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_VDD(struct device *dev,
122235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
122335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
122435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
122535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
122635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
122735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
122835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf);
122935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
123035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(VDD, S_IRUGO, adt7316_show_VDD, NULL, 0);
123135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
123235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_temp(struct device *dev,
123335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
123435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
123535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
123635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
123735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
123835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
123935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf);
124035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
124135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
124235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(in_temp, S_IRUGO, adt7316_show_in_temp, NULL, 0);
124335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
124435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
124535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
124635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
124735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
124835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
124935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
125035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
125135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf);
125235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
125335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
125435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
125535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
125635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
125735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN2(struct device *dev,
125835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
125935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
126035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
126135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
126235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
126335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
126435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf);
126535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
126635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN2, S_IRUGO, adt7316_show_AIN2, NULL, 0);
126735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
126835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN3(struct device *dev,
126935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
127035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
127135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
127235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
127335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
127435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
127535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf);
127635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
127735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN3, S_IRUGO, adt7316_show_AIN3, NULL, 0);
127835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
127935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_AIN4(struct device *dev,
128035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
128135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
128235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
128335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
128435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
128535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
128635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf);
128735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
128835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(AIN4, S_IRUGO, adt7316_show_AIN4, NULL, 0);
128935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
129035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
129135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int offset_addr, char *buf)
129235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
129335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int data;
129435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
129535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
129635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
129735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, offset_addr, &val);
129835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
129935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
130035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
130135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	data = (int)val;
130235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (val & 0x80)
130335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data -= 256;
130435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
130535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", data);
130635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
130735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
130835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
130935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int offset_addr, const char *buf, size_t len)
131035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
131135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	long data;
131235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
131335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
131435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
131535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtol(buf, 10, &data);
131635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data > 127 || data < -128)
131735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
131835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
131935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data < 0)
132035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		data += 256;
132135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	val = (u8)data;
132335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, offset_addr, val);
132535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
132635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
132735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
132835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
132935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
133035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
133135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_temp_offset(struct device *dev,
133235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
133335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
133435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
133535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
133635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
133735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
133835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf);
133935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
134035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
134135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_in_temp_offset(struct device *dev,
134235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
134335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
134435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
134535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
134635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
134735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
134835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
134935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len);
135035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
135135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
135235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(in_temp_offset, S_IRUGO | S_IWUSR,
135335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_in_temp_offset,
135435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_in_temp_offset, 0);
135535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
135635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_temp_offset(struct device *dev,
135735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
135835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
135935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
136035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
136135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
136235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
136335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf);
136435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
136535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
136635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_ex_temp_offset(struct device *dev,
136735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
136835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
136935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
137035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
137135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
137235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
137335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
137435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len);
137535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
137635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
137735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_temp_offset, S_IRUGO | S_IWUSR,
137835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_temp_offset,
137935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_ex_temp_offset, 0);
138035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
138135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_analog_temp_offset(struct device *dev,
138235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
138335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
138435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
138535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
138635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
138735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
138835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip,
138935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_ANALOG_TEMP_OFFSET, buf);
139035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
139135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
139235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_in_analog_temp_offset(struct device *dev,
139335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
139435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
139535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
139635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
139735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
139835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
139935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
140035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip,
140135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_ANALOG_TEMP_OFFSET, buf, len);
140235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
140335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
140435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(in_analog_temp_offset, S_IRUGO | S_IWUSR,
140535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_in_analog_temp_offset,
140635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_in_analog_temp_offset, 0);
140735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
140835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev,
140935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
141035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
141135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
141235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
141335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
141435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
141535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_temp_offset(chip,
141635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_ANALOG_TEMP_OFFSET, buf);
141735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
141835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
141935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev,
142035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
142135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
142235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
142335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
142435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
142535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
142635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
142735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_temp_offset(chip,
142835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_ANALOG_TEMP_OFFSET, buf, len);
142935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
143035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
143135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(ex_analog_temp_offset, S_IRUGO | S_IWUSR,
143235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_analog_temp_offset,
143335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_ex_analog_temp_offset, 0);
143435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
143535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip,
143635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int channel, char *buf)
143735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
143835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u16 data;
143935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 msb, lsb, offset;
144035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
144135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
144235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (channel >= ADT7316_DA_MSB_DATA_REGS ||
144335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 0 &&
144435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) ||
144535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 1 &&
144635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)))
144735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
144835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
144935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	offset = chip->dac_bits - 8;
145035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
145135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->dac_bits > 8) {
145235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.read(chip->bus.client,
145335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_DA_DATA_BASE + channel * 2, &lsb);
145435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
145535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
145635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
145735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
145835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client,
145935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ADT7316_DA_DATA_BASE + 1 + channel * 2, &msb);
146035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
146135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
146235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
146335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	data = (msb << offset) + (lsb & ((1 << offset) - 1));
146435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
146535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", data);
146635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
146735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
146835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
146935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int channel, const char *buf, size_t len)
147035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
147135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 msb, lsb, offset;
147235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
147335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
147435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
147535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (channel >= ADT7316_DA_MSB_DATA_REGS ||
147635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 0 &&
147735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) ||
147835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(channel == 1 &&
147935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)))
148035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
148135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
148235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	offset = chip->dac_bits - 8;
148335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
148435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 10, &data);
148535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data >= (1 << chip->dac_bits))
148635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
148735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
148835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->dac_bits > 8) {
148935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		lsb = data & (1 << offset);
149035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = chip->bus.write(chip->bus.client,
149135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_DA_DATA_BASE + channel * 2, lsb);
149235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
149335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EIO;
149435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
149535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
149635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	msb = data >> offset;
149735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client,
149835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ADT7316_DA_DATA_BASE + 1 + channel * 2, msb);
149935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
150035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
150135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
150235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
150335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
150435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
150535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_A(struct device *dev,
150635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
150735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
150835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
150935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
151035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
151135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
151235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 0, buf);
151335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
151435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
151535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_A(struct device *dev,
151635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
151735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
151835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
151935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
152035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
152135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
152235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
152335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 0, buf, len);
152435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
152535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
152635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_A, S_IRUGO | S_IWUSR, adt7316_show_DAC_A,
152735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_A, 0);
152835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
152935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_B(struct device *dev,
153035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
153135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
153235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
153335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
153435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
153535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
153635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 1, buf);
153735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
153835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
153935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_B(struct device *dev,
154035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
154135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
154235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
154335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
154435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
154535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
154635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
154735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 1, buf, len);
154835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
154935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
155035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_B, S_IRUGO | S_IWUSR, adt7316_show_DAC_B,
155135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_B, 0);
155235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
155335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_C(struct device *dev,
155435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
155535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
155635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
155735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
155835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
155935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
156035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 2, buf);
156135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
156235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
156335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_C(struct device *dev,
156435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
156535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
156635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
156735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
156835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
156935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
157035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
157135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 2, buf, len);
157235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
157335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
157435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_C, S_IRUGO | S_IWUSR, adt7316_show_DAC_C,
157535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_C, 0);
157635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
157735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_DAC_D(struct device *dev,
157835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
157935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
158035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
158135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
158235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
158335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
158435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_DAC(chip, 3, buf);
158535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
158635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
158735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_store_DAC_D(struct device *dev,
158835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
158935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
159035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
159135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
159235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
159335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
159435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
159535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_store_DAC(chip, 3, buf, len);
159635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
159735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
159835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(DAC_D, S_IRUGO | S_IWUSR, adt7316_show_DAC_D,
159935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_store_DAC_D, 0);
160035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
160135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_device_id(struct device *dev,
160235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
160335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
160435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
160535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
160635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
160735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 id;
160835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
160935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_ID, &id);
161135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
161235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
161335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", id);
161535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
161635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(device_id, S_IRUGO, adt7316_show_device_id, NULL, 0);
161835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
161935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_manufactorer_id(struct device *dev,
162035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
162135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
162235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
162335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
162435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
162535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 id;
162635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
162735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
162835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_MANUFACTURE_ID, &id);
162935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
163035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
163135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
163235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", id);
163335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
163435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
163535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(manufactorer_id, S_IRUGO,
163635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_manufactorer_id, NULL, 0);
163735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
163835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_device_rev(struct device *dev,
163935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
164035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
164135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
164235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
164335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
164435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 rev;
164535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
164635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
164735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_REV, &rev);
164835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
164935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
165035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
165135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", rev);
165235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
165335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
165435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(device_rev, S_IRUGO, adt7316_show_device_rev, NULL, 0);
165535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
165635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_bus_type(struct device *dev,
165735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
165835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
165935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
166035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
166135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
166235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 stat;
166335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
166435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
166535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_SPI_LOCK_STAT, &stat);
166635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
166735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
166835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
166935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (stat)
167035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "spi\n");
167135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
167235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return sprintf(buf, "i2c\n");
167335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
167435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
167535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
167635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
167735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_name(struct device *dev,
167835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
167935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
168035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
168135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
168235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
168335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
168435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%s\n", chip->name);
168535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
168635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
168735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic IIO_DEVICE_ATTR(name, S_IRUGO, adt7316_show_name, NULL, 0);
168835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
168935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7316_attributes[] = {
169035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_modes.dev_attr.attr,
169135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_mode.dev_attr.attr,
169235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_reset.dev_attr.attr,
169335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enabled.dev_attr.attr,
169435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ad_channel.dev_attr.attr,
169535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_ad_channels.dev_attr.attr,
169635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_disable_averaging.dev_attr.attr,
169735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
169835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_powerdown.dev_attr.attr,
169935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
170035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_da_high_resolution.dev_attr.attr,
170135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
170235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
170335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
170435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
170535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
170635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_update_DAC.dev_attr.attr,
170735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
170835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
170935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
171035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_VDD.dev_attr.attr,
171135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp.dev_attr.attr,
171235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp.dev_attr.attr,
171335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp_offset.dev_attr.attr,
171435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
171535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
171635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
171735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_A.dev_attr.attr,
171835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_B.dev_attr.attr,
171935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_C.dev_attr.attr,
172035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_D.dev_attr.attr,
172135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_id.dev_attr.attr,
172235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_manufactorer_id.dev_attr.attr,
172335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_rev.dev_attr.attr,
172435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_bus_type.dev_attr.attr,
172535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_name.dev_attr.attr,
172635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
172735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
172835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
172935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic const struct attribute_group adt7316_attribute_group = {
173035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7316_attributes,
173135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
173235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
173335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7516_attributes[] = {
173435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_modes.dev_attr.attr,
173535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_mode.dev_attr.attr,
173635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_select_ex_temp.dev_attr.attr,
173735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_reset.dev_attr.attr,
173835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enabled.dev_attr.attr,
173935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ad_channel.dev_attr.attr,
174035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_ad_channels.dev_attr.attr,
174135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_disable_averaging.dev_attr.attr,
174235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
174335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_powerdown.dev_attr.attr,
174435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
174535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN_internal_Vref.dev_attr.attr,
174635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_da_high_resolution.dev_attr.attr,
174735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
174835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
174935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
175035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
175135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
175235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_update_DAC.dev_attr.attr,
175335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
175435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
175535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
175635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_VDD.dev_attr.attr,
175735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp.dev_attr.attr,
175835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp_AIN1.dev_attr.attr,
175935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN2.dev_attr.attr,
176035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN3.dev_attr.attr,
176135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_AIN4.dev_attr.attr,
176235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_temp_offset.dev_attr.attr,
176335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
176435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
176535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
176635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_A.dev_attr.attr,
176735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_B.dev_attr.attr,
176835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_C.dev_attr.attr,
176935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_DAC_D.dev_attr.attr,
177035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_id.dev_attr.attr,
177135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_manufactorer_id.dev_attr.attr,
177235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_device_rev.dev_attr.attr,
177335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_bus_type.dev_attr.attr,
177435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_dev_attr_name.dev_attr.attr,
177535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
177635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
177735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
177835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic const struct attribute_group adt7516_attribute_group = {
177935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7516_attributes,
178035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
178135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
178235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
178335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
178435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * temperature bound events
178535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
178635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
178735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(0)
178835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7316_IN_TEMP_LOW    IIO_BUFFER_EVENT_CODE(1)
178935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(2)
179035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7316_EX_TEMP_LOW    IIO_BUFFER_EVENT_CODE(3)
179135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT  IIO_BUFFER_EVENT_CODE(4)
179235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7516_AIN1           IIO_BUFFER_EVENT_CODE(5)
179335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7516_AIN2           IIO_BUFFER_EVENT_CODE(6)
179435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7516_AIN3           IIO_BUFFER_EVENT_CODE(7)
179535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7516_AIN4           IIO_BUFFER_EVENT_CODE(8)
179635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#define IIO_EVENT_CODE_ADT7316_VDD            IIO_BUFFER_EVENT_CODE(9)
179735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
179835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic void adt7316_interrupt_bh(struct work_struct *work_s)
179935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
180035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip =
180135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		container_of(work_s, struct adt7316_chip_info, thresh_work);
180235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 stat1, stat2;
180335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int i, ret, count;
180435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
180535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1);
180635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!ret) {
180735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
180835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			count = 8;
180935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
181035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			count = 5;
181135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
181235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		for (i = 0; i < count; i++) {
181335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			if (stat1 & (1 << i))
181435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				iio_push_event(chip->indio_dev, 0,
181535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang					IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i,
181635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang					chip->last_timestamp);
181735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		}
181835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
181935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
182035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2);
182135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!ret) {
182235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (stat2 & ADT7316_INT_MASK2_VDD)
182335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			iio_push_event(chip->indio_dev, 0,
182435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				IIO_EVENT_CODE_ADT7316_VDD,
182535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				chip->last_timestamp);
182635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
182735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
182835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	enable_irq(chip->bus.irq);
182935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
183035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
183135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic int adt7316_interrupt(struct iio_dev *dev_info,
183235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int index,
183335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		s64 timestamp,
183435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		int no_test)
183535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
183635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
183735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
183835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->last_timestamp = timestamp;
183935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	schedule_work(&chip->thresh_work);
184035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
184135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return 0;
184235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
184335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
184435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_SH(adt7316, &adt7316_interrupt);
184535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
184635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
184735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Show mask of enabled interrupts in Hex.
184835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
184935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_int_mask(struct device *dev,
185035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
185135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
185235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
185335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
185435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
185535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
185635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "0x%x\n", chip->int_mask);
185735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
185835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
185935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
186035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * Set 1 to the mask in Hex to enabled interrupts.
186135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
186235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_set_int_mask(struct device *dev,
186335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
186435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
186535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
186635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
186735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
186835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
186935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned long data;
187035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
187135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 mask;
187235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
187335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtoul(buf, 16, &data);
187435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret || data >= ADT7316_VDD_INT_MASK + 1)
187535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
187635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
187735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data & ADT7316_VDD_INT_MASK)
187835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		mask = 0;			/* enable vdd int */
187935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
188035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		mask = ADT7316_INT_MASK2_VDD;	/* disable vdd int */
188135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
188235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK2, mask);
188335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!ret) {
188435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->int_mask &= ~ADT7316_VDD_INT_MASK;
188535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->int_mask |= data & ADT7316_VDD_INT_MASK;
188635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
188735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
188835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (data & ADT7316_TEMP_AIN_INT_MASK) {
188935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX)
189035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			/* mask in reg is opposite, set 1 to disable */
189135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			mask = (~data) & ADT7316_TEMP_INT_MASK;
189235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		else
189335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			/* mask in reg is opposite, set 1 to disable */
189435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			mask = (~data) & ADT7316_TEMP_AIN_INT_MASK;
189535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
189635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK1, mask);
189735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
189835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->int_mask = mask;
189935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
190035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
190135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
190235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_show_ad_bound(struct device *dev,
190335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
190435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		u8 bound_reg,
190535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
190635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
190735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
190835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
190935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
191035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int data;
191135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
191235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
191335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
191435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		bound_reg > ADT7316_EX_TEMP_LOW)
191535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
191635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
191735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.read(chip->bus.client, bound_reg, &val);
191835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
191935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
192035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
192135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	data = (int)val;
192235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
192335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
192435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) {
192535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data & 0x80)
192635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			data -= 256;
192735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
192835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
192935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", data);
193035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
193135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
193235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ad_bound(struct device *dev,
193335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
193435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		u8 bound_reg,
193535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
193635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
193735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
193835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
193935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
194035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	long data;
194135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 val;
194235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
194335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
194435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
194535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		bound_reg > ADT7316_EX_TEMP_LOW)
194635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EPERM;
194735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
194835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = strict_strtol(buf, 10, &data);
194935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
195035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EINVAL;
195135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
195235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
195335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) {
195435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 255 || data < 0)
195535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
195635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
195735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data > 127 || data < -128)
195835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			return -EINVAL;
195935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
196035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (data < 0)
196135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			data += 256;
196235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
196335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
196435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	val = (u8)data;
196535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
196635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, bound_reg, val);
196735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
196835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
196935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
197035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
197135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
197235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
197335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_temp_high(struct device *dev,
197435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
197535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
197635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
197735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
197835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_TEMP_HIGH, buf);
197935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
198035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
198135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_in_temp_high(struct device *dev,
198235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
198335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
198435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
198535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
198635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
198735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_TEMP_HIGH, buf, len);
198835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
198935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
199035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_in_temp_low(struct device *dev,
199135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
199235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
199335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
199435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
199535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_TEMP_LOW, buf);
199635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
199735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
199835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_in_temp_low(struct device *dev,
199935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
200035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
200135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
200235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
200335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
200435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_IN_TEMP_LOW, buf, len);
200535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
200635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
200735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_temp_ain1_high(struct device *dev,
200835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
200935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
201035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
201135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
201235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_TEMP_HIGH, buf);
201335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
201435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
201535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ex_temp_ain1_high(struct device *dev,
201635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
201735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
201835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
201935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
202035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
202135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_TEMP_HIGH, buf, len);
202235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
202335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
202435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ex_temp_ain1_low(struct device *dev,
202535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
202635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
202735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
202835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
202935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_TEMP_LOW, buf);
203035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
203135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
203235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ex_temp_ain1_low(struct device *dev,
203335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
203435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
203535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
203635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
203735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
203835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7316_EX_TEMP_LOW, buf, len);
203935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
204035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
204135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ain2_high(struct device *dev,
204235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
204335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
204435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
204535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
204635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN2_HIGH, buf);
204735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
204835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
204935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ain2_high(struct device *dev,
205035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
205135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
205235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
205335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
205435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
205535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN2_HIGH, buf, len);
205635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
205735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
205835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ain2_low(struct device *dev,
205935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
206035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
206135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
206235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
206335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN2_LOW, buf);
206435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
206535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
206635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ain2_low(struct device *dev,
206735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
206835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
206935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
207035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
207135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
207235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN2_LOW, buf, len);
207335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
207435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
207535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ain3_high(struct device *dev,
207635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
207735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
207835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
207935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
208035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN3_HIGH, buf);
208135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
208235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
208335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ain3_high(struct device *dev,
208435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
208535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
208635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
208735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
208835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
208935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN3_HIGH, buf, len);
209035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
209135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
209235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ain3_low(struct device *dev,
209335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
209435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
209535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
209635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
209735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN3_LOW, buf);
209835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
209935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
210035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ain3_low(struct device *dev,
210135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
210235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
210335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
210435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
210535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
210635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN3_LOW, buf, len);
210735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
210835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
210935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ain4_high(struct device *dev,
211035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
211135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
211235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
211335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
211435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN4_HIGH, buf);
211535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
211635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
211735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ain4_high(struct device *dev,
211835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
211935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
212035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
212135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
212235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
212335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN4_HIGH, buf, len);
212435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
212535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
212635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_ain4_low(struct device *dev,
212735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
212835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
212935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
213035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_show_ad_bound(dev, attr,
213135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN4_LOW, buf);
213235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
213335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
213435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic inline ssize_t adt7316_set_ain4_low(struct device *dev,
213535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
213635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
213735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
213835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
213935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return adt7316_set_ad_bound(dev, attr,
214035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			ADT7516_AIN4_LOW, buf, len);
214135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
214235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
214335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_show_int_enabled(struct device *dev,
214435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
214535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		char *buf)
214635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
214735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
214835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
214935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
215035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN));
215135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
215235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
215335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic ssize_t adt7316_set_int_enabled(struct device *dev,
215435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		struct device_attribute *attr,
215535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *buf,
215635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		size_t len)
215735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
215835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
215935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
216035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	u8 config1;
216135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret;
216235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
216335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	config1 = chip->config1 & (~ADT7316_INT_EN);
216435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (!memcmp(buf, "1", 1))
216535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		config1 |= ADT7316_INT_EN;
216635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
216735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
216835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
216935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -EIO;
217035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
217135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->config1 = config1;
217235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
217335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return len;
217435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
217535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
217635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
217735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(int_mask, iio_event_adt7316,
217835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_int_mask, adt7316_set_int_mask, 0);
217935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(in_temp_high, iio_event_adt7316,
218035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_in_temp_high, adt7316_set_in_temp_high, 0);
218135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(in_temp_low, iio_event_adt7316,
218235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_in_temp_low, adt7316_set_in_temp_low, 0);
218335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ex_temp_high, iio_event_adt7316,
218435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_temp_ain1_high,
218535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_set_ex_temp_ain1_high, 0);
218635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ex_temp_low, iio_event_adt7316,
218735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_temp_ain1_low,
218835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_set_ex_temp_ain1_low, 0);
218935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ex_temp_ain1_high, iio_event_adt7316,
219035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_temp_ain1_high,
219135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_set_ex_temp_ain1_high, 0);
219235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ex_temp_ain1_low, iio_event_adt7316,
219335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ex_temp_ain1_low,
219435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_set_ex_temp_ain1_low, 0);
219535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ain2_high, iio_event_adt7316,
219635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ain2_high, adt7316_set_ain2_high, 0);
219735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ain2_low, iio_event_adt7316,
219835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ain2_low, adt7316_set_ain2_low, 0);
219935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ain3_high, iio_event_adt7316,
220035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ain3_high, adt7316_set_ain3_high, 0);
220135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ain3_low, iio_event_adt7316,
220235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ain3_low, adt7316_set_ain3_low, 0);
220335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ain4_high, iio_event_adt7316,
220435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ain4_high, adt7316_set_ain4_high, 0);
220535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(ain4_low, iio_event_adt7316,
220635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_ain4_low, adt7316_set_ain4_low, 0);
220735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangIIO_EVENT_ATTR_SH(int_enabled, iio_event_adt7316,
220835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		adt7316_show_int_enabled, adt7316_set_int_enabled, 0);
220935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
221035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7316_event_attributes[] = {
221135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_int_mask.dev_attr.attr,
221235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_in_temp_high.dev_attr.attr,
221335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_in_temp_low.dev_attr.attr,
221435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ex_temp_high.dev_attr.attr,
221535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ex_temp_low.dev_attr.attr,
221635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_int_enabled.dev_attr.attr,
221735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
221835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
221935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
222035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute_group adt7316_event_attribute_group = {
222135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7316_event_attributes,
222235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
222335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
222435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute *adt7516_event_attributes[] = {
222535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_int_mask.dev_attr.attr,
222635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_in_temp_high.dev_attr.attr,
222735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_in_temp_low.dev_attr.attr,
222835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ex_temp_ain1_high.dev_attr.attr,
222935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ex_temp_ain1_low.dev_attr.attr,
223035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ain2_high.dev_attr.attr,
223135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ain2_low.dev_attr.attr,
223235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ain3_high.dev_attr.attr,
223335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ain3_low.dev_attr.attr,
223435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ain4_high.dev_attr.attr,
223535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_ain4_low.dev_attr.attr,
223635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	&iio_event_attr_int_enabled.dev_attr.attr,
223735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	NULL,
223835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
223935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
224035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangstatic struct attribute_group adt7516_event_attribute_group = {
224135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	.attrs = adt7516_event_attributes,
224235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang};
224335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
224435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#ifdef CONFIG_PM
224535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangint adt7316_disable(struct device *dev)
224635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
224735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
224835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
224935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
225035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return _adt7316_store_enabled(chip, 0);
225135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
225235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangEXPORT_SYMBOL(adt7316_disable);
225335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
225435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangint adt7316_enable(struct device *dev)
225535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
225635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
225735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
225835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
225935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return _adt7316_store_enabled(chip, 1);
226035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
226135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangEXPORT_SYMBOL(adt7316_enable);
226235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang#endif
226335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
226435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang/*
226535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang * device probe and remove
226635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang */
226735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangint __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
226835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		const char *name)
226935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
227035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip;
227135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	unsigned short *adt7316_platform_data = dev->platform_data;
227235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	int ret = 0;
227335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
227435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip = kzalloc(sizeof(struct adt7316_chip_info), GFP_KERNEL);
227535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
227635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip == NULL)
227735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -ENOMEM;
227835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
227935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	/* this is only used for device removal purposes */
228035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dev_set_drvdata(dev, chip);
228135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
228235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->bus = *bus;
228335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->name = name;
228435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
228535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (name[4] == '3')
228635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->id = ID_ADT7316 + (name[6] - '6');
228735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else if (name[4] == '5')
228835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->id = ID_ADT7516 + (name[6] - '6');
228935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	else
229035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		return -ENODEV;
229135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
229235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->ldac_pin = adt7316_platform_data[1];
229335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->ldac_pin) {
229435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA;
229535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
229635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->config1 |= ADT7516_SEL_AIN3;
229735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
229835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->int_mask = ADT7316_TEMP_INT_MASK | ADT7316_VDD_INT_MASK;
229935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
230035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->int_mask |= ADT7516_AIN_INT_MASK;
230135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
230235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->indio_dev = iio_allocate_device();
230335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->indio_dev == NULL) {
230435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = -ENOMEM;
230535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		goto error_free_chip;
230635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
230735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
230835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->indio_dev->dev.parent = dev;
230935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
231035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->indio_dev->attrs = &adt7516_attribute_group;
231135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->indio_dev->event_attrs = &adt7516_event_attribute_group;
231235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	} else {
231335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->indio_dev->attrs = &adt7316_attribute_group;
231435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
231535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
231635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->indio_dev->dev_data = (void *)chip;
231735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->indio_dev->driver_module = THIS_MODULE;
231835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->indio_dev->num_interrupt_lines = 1;
231935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	chip->indio_dev->modes = INDIO_DIRECT_MODE;
232035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
232135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = iio_device_register(chip->indio_dev);
232235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret)
232335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		goto error_free_dev;
232435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
232535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->bus.irq > 0) {
232635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (adt7316_platform_data[0])
232735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->bus.irq_flags = adt7316_platform_data[0];
232835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
232935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = iio_register_interrupt_line(chip->bus.irq,
233035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				chip->indio_dev,
233135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				0,
233235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				chip->bus.irq_flags,
233335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				chip->name);
233435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (ret)
233535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			goto error_unreg_dev;
233635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
233735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		/*
233835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		 * The event handler list element refer to iio_event_adt7316.
233935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		 * All event attributes bind to the same event handler.
234035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		 * So, only register event handler once.
234135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		 */
234235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		iio_add_event_to_list(&iio_event_adt7316,
234335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang				&chip->indio_dev->interrupts[0]->ev_list);
234435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
234535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		INIT_WORK(&chip->thresh_work, adt7316_interrupt_bh);
234635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
234735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
234835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->config1 |= ADT7316_INT_POLARITY;
234935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
235035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
235135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
235235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret) {
235335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = -EIO;
235435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		goto error_unreg_irq;
235535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
235635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
235735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
235835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (ret) {
235935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		ret = -EIO;
236035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		goto error_unreg_irq;
236135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	}
236235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
236335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
236435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			chip->name);
236535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
236635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return 0;
236735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
236835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangerror_unreg_irq:
236935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	iio_unregister_interrupt_line(chip->indio_dev, 0);
237035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangerror_unreg_dev:
237135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	iio_device_unregister(chip->indio_dev);
237235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangerror_free_dev:
237335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	iio_free_device(chip->indio_dev);
237435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangerror_free_chip:
237535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	kfree(chip);
237635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
237735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return ret;
237835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
237935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangEXPORT_SYMBOL(adt7316_probe);
238035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
238135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhangint __devexit adt7316_remove(struct device *dev)
238235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang{
238335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
238435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *dev_info = dev_get_drvdata(dev);
238535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct adt7316_chip_info *chip = dev_info->dev_data;
238635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	struct iio_dev *indio_dev = chip->indio_dev;
238735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
238835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	dev_set_drvdata(dev, NULL);
238935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	if (chip->bus.irq)
239035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang		iio_unregister_interrupt_line(indio_dev, 0);
239135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	iio_device_unregister(indio_dev);
239235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	iio_free_device(chip->indio_dev);
239335f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	kfree(chip);
239435f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
239535f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang	return 0;
239635f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang}
239735f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangEXPORT_SYMBOL(adt7316_remove);
239835f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang
239935f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangMODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
240035f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangMODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital"
240135f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic Zhang			" temperature sensor, ADC and DAC driver");
240235f6b6b86ede34a9f8c029943842640b2ffbfa19Sonic ZhangMODULE_LICENSE("GPL v2");
2403