summaryrefslogtreecommitdiff
path: root/drivers/iio/health/afe440x.h
blob: c671ab78a23ac6109b57fcc19a7925e7563149d1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
 * AFE440X Heart Rate Monitors and Low-Cost Pulse Oximeters
 *
 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
 *	Andrew F. Davis <afd@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#ifndef _AFE440X_H
#define _AFE440X_H

/* AFE440X registers */
#define AFE440X_CONTROL0		0x00
#define AFE440X_LED2STC			0x01
#define AFE440X_LED2ENDC		0x02
#define AFE440X_LED1LEDSTC		0x03
#define AFE440X_LED1LEDENDC		0x04
#define AFE440X_ALED2STC		0x05
#define AFE440X_ALED2ENDC		0x06
#define AFE440X_LED1STC			0x07
#define AFE440X_LED1ENDC		0x08
#define AFE440X_LED2LEDSTC		0x09
#define AFE440X_LED2LEDENDC		0x0a
#define AFE440X_ALED1STC		0x0b
#define AFE440X_ALED1ENDC		0x0c
#define AFE440X_LED2CONVST		0x0d
#define AFE440X_LED2CONVEND		0x0e
#define AFE440X_ALED2CONVST		0x0f
#define AFE440X_ALED2CONVEND		0x10
#define AFE440X_LED1CONVST		0x11
#define AFE440X_LED1CONVEND		0x12
#define AFE440X_ALED1CONVST		0x13
#define AFE440X_ALED1CONVEND		0x14
#define AFE440X_ADCRSTSTCT0		0x15
#define AFE440X_ADCRSTENDCT0		0x16
#define AFE440X_ADCRSTSTCT1		0x17
#define AFE440X_ADCRSTENDCT1		0x18
#define AFE440X_ADCRSTSTCT2		0x19
#define AFE440X_ADCRSTENDCT2		0x1a
#define AFE440X_ADCRSTSTCT3		0x1b
#define AFE440X_ADCRSTENDCT3		0x1c
#define AFE440X_PRPCOUNT		0x1d
#define AFE440X_CONTROL1		0x1e
#define AFE440X_LEDCNTRL		0x22
#define AFE440X_CONTROL2		0x23
#define AFE440X_ALARM			0x29
#define AFE440X_LED2VAL			0x2a
#define AFE440X_ALED2VAL		0x2b
#define AFE440X_LED1VAL			0x2c
#define AFE440X_ALED1VAL		0x2d
#define AFE440X_LED2_ALED2VAL		0x2e
#define AFE440X_LED1_ALED1VAL		0x2f
#define AFE440X_CONTROL3		0x31
#define AFE440X_PDNCYCLESTC		0x32
#define AFE440X_PDNCYCLEENDC		0x33

/* CONTROL0 register fields */
#define AFE440X_CONTROL0_REG_READ	BIT(0)
#define AFE440X_CONTROL0_TM_COUNT_RST	BIT(1)
#define AFE440X_CONTROL0_SW_RESET	BIT(3)

/* CONTROL1 register fields */
#define AFE440X_CONTROL1_TIMEREN	BIT(8)

/* TIAGAIN register fields */
#define AFE440X_TIAGAIN_ENSEPGAIN_MASK	BIT(15)
#define AFE440X_TIAGAIN_ENSEPGAIN_SHIFT	15

/* CONTROL2 register fields */
#define AFE440X_CONTROL2_PDN_AFE	BIT(0)
#define AFE440X_CONTROL2_PDN_RX		BIT(1)
#define AFE440X_CONTROL2_DYNAMIC4	BIT(3)
#define AFE440X_CONTROL2_DYNAMIC3	BIT(4)
#define AFE440X_CONTROL2_DYNAMIC2	BIT(14)
#define AFE440X_CONTROL2_DYNAMIC1	BIT(20)

/* CONTROL3 register fields */
#define AFE440X_CONTROL3_CLKDIV		GENMASK(2, 0)

/* CONTROL0 values */
#define AFE440X_CONTROL0_WRITE		0x0
#define AFE440X_CONTROL0_READ		0x1

struct afe440x_reg_info {
	unsigned int reg;
	unsigned int offreg;
	unsigned int shift;
	unsigned int mask;
};

#define AFE440X_REG_INFO(_reg, _offreg, _sm)			\
	{							\
		.reg = _reg,					\
		.offreg = _offreg,				\
		.shift = _sm ## _SHIFT,				\
		.mask = _sm ## _MASK,				\
	}

#define AFE440X_INTENSITY_CHAN(_index, _name, _mask)		\
	{							\
		.type = IIO_INTENSITY,				\
		.channel = _index,				\
		.address = _index,				\
		.scan_index = _index,				\
		.scan_type = {					\
				.sign = 's',			\
				.realbits = 24,			\
				.storagebits = 32,		\
				.endianness = IIO_CPU,		\
		},						\
		.extend_name = _name,				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
			_mask,					\
	}

#define AFE440X_CURRENT_CHAN(_index, _name)			\
	{							\
		.type = IIO_CURRENT,				\
		.channel = _index,				\
		.address = _index,				\
		.scan_index = _index,				\
		.extend_name = _name,				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
			BIT(IIO_CHAN_INFO_SCALE),		\
		.output = true,					\
	}

enum afe440x_reg_type {
	SIMPLE,
	RESISTANCE,
	CAPACITANCE,
};

struct afe440x_val_table {
	int integer;
	int fract;
};

#define AFE440X_TABLE_ATTR(_name, _table)				\
static ssize_t _name ## _show(struct device *dev,			\
			      struct device_attribute *attr, char *buf)	\
{									\
	ssize_t len = 0;						\
	int i;								\
									\
	for (i = 0; i < ARRAY_SIZE(_table); i++)			\
		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", \
				 _table[i].integer,			\
				 _table[i].fract);			\
									\
	buf[len - 1] = '\n';						\
									\
	return len;							\
}									\
static DEVICE_ATTR_RO(_name)

struct afe440x_attr {
	struct device_attribute dev_attr;
	unsigned int reg;
	unsigned int shift;
	unsigned int mask;
	enum afe440x_reg_type type;
	const struct afe440x_val_table *val_table;
	unsigned int table_size;
};

#define to_afe440x_attr(_dev_attr)				\
	container_of(_dev_attr, struct afe440x_attr, dev_attr)

#define AFE440X_ATTR(_name, _reg, _field, _type, _table, _size)	\
	struct afe440x_attr afe440x_attr_##_name = {		\
		.dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR),	\
				   afe440x_show_register,	\
				   afe440x_store_register),	\
		.reg = _reg,					\
		.shift = _field ## _SHIFT,			\
		.mask = _field ## _MASK,			\
		.type = _type,					\
		.val_table = _table,				\
		.table_size = _size,				\
	}

#endif /* _AFE440X_H */