hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * AFE440X Heart Rate Monitors and Low-Cost Pulse Oximeters
 *
 * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
 *    Andrew F. Davis <afd@ti.com>
 */
 
#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    BIT(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
 
#define AFE440X_INTENSITY_CHAN(_index, _mask)            \
   {                            \
       .type = IIO_INTENSITY,                \
       .channel = _index,                \
       .address = _index,                \
       .scan_index = _index,                \
       .scan_type = {                    \
               .sign = 's',            \
               .realbits = 24,            \
               .storagebits = 32,        \
               .endianness = IIO_CPU,        \
       },                        \
       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |    \
           _mask,                    \
       .indexed = true,                \
   }
 
#define AFE440X_CURRENT_CHAN(_index)                \
   {                            \
       .type = IIO_CURRENT,                \
       .channel = _index,                \
       .address = _index,                \
       .scan_index = -1,                \
       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |    \
           BIT(IIO_CHAN_INFO_SCALE),        \
       .indexed = true,                \
       .output = true,                    \
   }
 
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 field;
   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, _field, _table)            \
   struct afe440x_attr afe440x_attr_##_name = {        \
       .dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR),    \
                  afe440x_show_register,    \
                  afe440x_store_register),    \
       .field = _field,                \
       .val_table = _table,                \
       .table_size = ARRAY_SIZE(_table),        \
   }
 
#endif /* _AFE440X_H */