1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * AFE440X Heart Rate Monitors and Low-Cost Pulse Oximeters |
4 | * |
5 | * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ |
6 | * Andrew F. Davis <afd@ti.com> |
7 | */ |
8 | |
9 | #ifndef _AFE440X_H |
10 | #define _AFE440X_H |
11 | |
12 | /* AFE440X registers */ |
13 | #define AFE440X_CONTROL0 0x00 |
14 | #define AFE440X_LED2STC 0x01 |
15 | #define AFE440X_LED2ENDC 0x02 |
16 | #define AFE440X_LED1LEDSTC 0x03 |
17 | #define AFE440X_LED1LEDENDC 0x04 |
18 | #define AFE440X_ALED2STC 0x05 |
19 | #define AFE440X_ALED2ENDC 0x06 |
20 | #define AFE440X_LED1STC 0x07 |
21 | #define AFE440X_LED1ENDC 0x08 |
22 | #define AFE440X_LED2LEDSTC 0x09 |
23 | #define AFE440X_LED2LEDENDC 0x0a |
24 | #define AFE440X_ALED1STC 0x0b |
25 | #define AFE440X_ALED1ENDC 0x0c |
26 | #define AFE440X_LED2CONVST 0x0d |
27 | #define AFE440X_LED2CONVEND 0x0e |
28 | #define AFE440X_ALED2CONVST 0x0f |
29 | #define AFE440X_ALED2CONVEND 0x10 |
30 | #define AFE440X_LED1CONVST 0x11 |
31 | #define AFE440X_LED1CONVEND 0x12 |
32 | #define AFE440X_ALED1CONVST 0x13 |
33 | #define AFE440X_ALED1CONVEND 0x14 |
34 | #define AFE440X_ADCRSTSTCT0 0x15 |
35 | #define AFE440X_ADCRSTENDCT0 0x16 |
36 | #define AFE440X_ADCRSTSTCT1 0x17 |
37 | #define AFE440X_ADCRSTENDCT1 0x18 |
38 | #define AFE440X_ADCRSTSTCT2 0x19 |
39 | #define AFE440X_ADCRSTENDCT2 0x1a |
40 | #define AFE440X_ADCRSTSTCT3 0x1b |
41 | #define AFE440X_ADCRSTENDCT3 0x1c |
42 | #define AFE440X_PRPCOUNT 0x1d |
43 | #define AFE440X_CONTROL1 0x1e |
44 | #define AFE440X_LEDCNTRL 0x22 |
45 | #define AFE440X_CONTROL2 0x23 |
46 | #define AFE440X_ALARM 0x29 |
47 | #define AFE440X_LED2VAL 0x2a |
48 | #define AFE440X_ALED2VAL 0x2b |
49 | #define AFE440X_LED1VAL 0x2c |
50 | #define AFE440X_ALED1VAL 0x2d |
51 | #define AFE440X_LED2_ALED2VAL 0x2e |
52 | #define AFE440X_LED1_ALED1VAL 0x2f |
53 | #define AFE440X_CONTROL3 0x31 |
54 | #define AFE440X_PDNCYCLESTC 0x32 |
55 | #define AFE440X_PDNCYCLEENDC 0x33 |
56 | |
57 | /* CONTROL0 register fields */ |
58 | #define AFE440X_CONTROL0_REG_READ BIT(0) |
59 | #define AFE440X_CONTROL0_TM_COUNT_RST BIT(1) |
60 | #define AFE440X_CONTROL0_SW_RESET BIT(3) |
61 | |
62 | /* CONTROL1 register fields */ |
63 | #define AFE440X_CONTROL1_TIMEREN BIT(8) |
64 | |
65 | /* TIAGAIN register fields */ |
66 | #define AFE440X_TIAGAIN_ENSEPGAIN BIT(15) |
67 | |
68 | /* CONTROL2 register fields */ |
69 | #define AFE440X_CONTROL2_PDN_AFE BIT(0) |
70 | #define AFE440X_CONTROL2_PDN_RX BIT(1) |
71 | #define AFE440X_CONTROL2_DYNAMIC4 BIT(3) |
72 | #define AFE440X_CONTROL2_DYNAMIC3 BIT(4) |
73 | #define AFE440X_CONTROL2_DYNAMIC2 BIT(14) |
74 | #define AFE440X_CONTROL2_DYNAMIC1 BIT(20) |
75 | |
76 | /* CONTROL3 register fields */ |
77 | #define AFE440X_CONTROL3_CLKDIV GENMASK(2, 0) |
78 | |
79 | /* CONTROL0 values */ |
80 | #define AFE440X_CONTROL0_WRITE 0x0 |
81 | #define AFE440X_CONTROL0_READ 0x1 |
82 | |
83 | #define AFE440X_INTENSITY_CHAN(_index, _mask) \ |
84 | { \ |
85 | .type = IIO_INTENSITY, \ |
86 | .channel = _index, \ |
87 | .address = _index, \ |
88 | .scan_index = _index, \ |
89 | .scan_type = { \ |
90 | .sign = 's', \ |
91 | .realbits = 24, \ |
92 | .storagebits = 32, \ |
93 | .endianness = IIO_CPU, \ |
94 | }, \ |
95 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
96 | _mask, \ |
97 | .indexed = true, \ |
98 | } |
99 | |
100 | #define AFE440X_CURRENT_CHAN(_index) \ |
101 | { \ |
102 | .type = IIO_CURRENT, \ |
103 | .channel = _index, \ |
104 | .address = _index, \ |
105 | .scan_index = -1, \ |
106 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
107 | BIT(IIO_CHAN_INFO_SCALE), \ |
108 | .indexed = true, \ |
109 | .output = true, \ |
110 | } |
111 | |
112 | struct afe440x_val_table { |
113 | int integer; |
114 | int fract; |
115 | }; |
116 | |
117 | #define AFE440X_TABLE_ATTR(_name, _table) \ |
118 | static ssize_t _name ## _show(struct device *dev, \ |
119 | struct device_attribute *attr, char *buf) \ |
120 | { \ |
121 | ssize_t len = 0; \ |
122 | int i; \ |
123 | \ |
124 | for (i = 0; i < ARRAY_SIZE(_table); i++) \ |
125 | len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", \ |
126 | _table[i].integer, \ |
127 | _table[i].fract); \ |
128 | \ |
129 | buf[len - 1] = '\n'; \ |
130 | \ |
131 | return len; \ |
132 | } \ |
133 | static DEVICE_ATTR_RO(_name) |
134 | |
135 | struct afe440x_attr { |
136 | struct device_attribute dev_attr; |
137 | unsigned int field; |
138 | const struct afe440x_val_table *val_table; |
139 | unsigned int table_size; |
140 | }; |
141 | |
142 | #define to_afe440x_attr(_dev_attr) \ |
143 | container_of(_dev_attr, struct afe440x_attr, dev_attr) |
144 | |
145 | #define AFE440X_ATTR(_name, _field, _table) \ |
146 | struct afe440x_attr afe440x_attr_##_name = { \ |
147 | .dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR), \ |
148 | afe440x_show_register, \ |
149 | afe440x_store_register), \ |
150 | .field = _field, \ |
151 | .val_table = _table, \ |
152 | .table_size = ARRAY_SIZE(_table), \ |
153 | } |
154 | |
155 | #endif /* _AFE440X_H */ |
156 | |