1 /* 2 * AFE440X Heart Rate Monitors and Low-Cost Pulse Oximeters 3 * 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 5 * Andrew F. Davis <afd@ti.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 */ 16 17 #ifndef _AFE440X_H 18 #define _AFE440X_H 19 20 /* AFE440X registers */ 21 #define AFE440X_CONTROL0 0x00 22 #define AFE440X_LED2STC 0x01 23 #define AFE440X_LED2ENDC 0x02 24 #define AFE440X_LED1LEDSTC 0x03 25 #define AFE440X_LED1LEDENDC 0x04 26 #define AFE440X_ALED2STC 0x05 27 #define AFE440X_ALED2ENDC 0x06 28 #define AFE440X_LED1STC 0x07 29 #define AFE440X_LED1ENDC 0x08 30 #define AFE440X_LED2LEDSTC 0x09 31 #define AFE440X_LED2LEDENDC 0x0a 32 #define AFE440X_ALED1STC 0x0b 33 #define AFE440X_ALED1ENDC 0x0c 34 #define AFE440X_LED2CONVST 0x0d 35 #define AFE440X_LED2CONVEND 0x0e 36 #define AFE440X_ALED2CONVST 0x0f 37 #define AFE440X_ALED2CONVEND 0x10 38 #define AFE440X_LED1CONVST 0x11 39 #define AFE440X_LED1CONVEND 0x12 40 #define AFE440X_ALED1CONVST 0x13 41 #define AFE440X_ALED1CONVEND 0x14 42 #define AFE440X_ADCRSTSTCT0 0x15 43 #define AFE440X_ADCRSTENDCT0 0x16 44 #define AFE440X_ADCRSTSTCT1 0x17 45 #define AFE440X_ADCRSTENDCT1 0x18 46 #define AFE440X_ADCRSTSTCT2 0x19 47 #define AFE440X_ADCRSTENDCT2 0x1a 48 #define AFE440X_ADCRSTSTCT3 0x1b 49 #define AFE440X_ADCRSTENDCT3 0x1c 50 #define AFE440X_PRPCOUNT 0x1d 51 #define AFE440X_CONTROL1 0x1e 52 #define AFE440X_LEDCNTRL 0x22 53 #define AFE440X_CONTROL2 0x23 54 #define AFE440X_ALARM 0x29 55 #define AFE440X_LED2VAL 0x2a 56 #define AFE440X_ALED2VAL 0x2b 57 #define AFE440X_LED1VAL 0x2c 58 #define AFE440X_ALED1VAL 0x2d 59 #define AFE440X_LED2_ALED2VAL 0x2e 60 #define AFE440X_LED1_ALED1VAL 0x2f 61 #define AFE440X_CONTROL3 0x31 62 #define AFE440X_PDNCYCLESTC 0x32 63 #define AFE440X_PDNCYCLEENDC 0x33 64 65 /* CONTROL0 register fields */ 66 #define AFE440X_CONTROL0_REG_READ BIT(0) 67 #define AFE440X_CONTROL0_TM_COUNT_RST BIT(1) 68 #define AFE440X_CONTROL0_SW_RESET BIT(3) 69 70 /* CONTROL1 register fields */ 71 #define AFE440X_CONTROL1_TIMEREN BIT(8) 72 73 /* TIAGAIN register fields */ 74 #define AFE440X_TIAGAIN_ENSEPGAIN_MASK BIT(15) 75 #define AFE440X_TIAGAIN_ENSEPGAIN_SHIFT 15 76 77 /* CONTROL2 register fields */ 78 #define AFE440X_CONTROL2_PDN_AFE BIT(0) 79 #define AFE440X_CONTROL2_PDN_RX BIT(1) 80 #define AFE440X_CONTROL2_DYNAMIC4 BIT(3) 81 #define AFE440X_CONTROL2_DYNAMIC3 BIT(4) 82 #define AFE440X_CONTROL2_DYNAMIC2 BIT(14) 83 #define AFE440X_CONTROL2_DYNAMIC1 BIT(20) 84 85 /* CONTROL3 register fields */ 86 #define AFE440X_CONTROL3_CLKDIV GENMASK(2, 0) 87 88 /* CONTROL0 values */ 89 #define AFE440X_CONTROL0_WRITE 0x0 90 #define AFE440X_CONTROL0_READ 0x1 91 92 struct afe440x_reg_info { 93 unsigned int reg; 94 unsigned int offreg; 95 unsigned int shift; 96 unsigned int mask; 97 }; 98 99 #define AFE440X_REG_INFO(_reg, _offreg, _sm) \ 100 { \ 101 .reg = _reg, \ 102 .offreg = _offreg, \ 103 .shift = _sm ## _SHIFT, \ 104 .mask = _sm ## _MASK, \ 105 } 106 107 #define AFE440X_INTENSITY_CHAN(_index, _name, _mask) \ 108 { \ 109 .type = IIO_INTENSITY, \ 110 .channel = _index, \ 111 .address = _index, \ 112 .scan_index = _index, \ 113 .scan_type = { \ 114 .sign = 's', \ 115 .realbits = 24, \ 116 .storagebits = 32, \ 117 .endianness = IIO_CPU, \ 118 }, \ 119 .extend_name = _name, \ 120 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 121 _mask, \ 122 } 123 124 #define AFE440X_CURRENT_CHAN(_index, _name) \ 125 { \ 126 .type = IIO_CURRENT, \ 127 .channel = _index, \ 128 .address = _index, \ 129 .scan_index = _index, \ 130 .extend_name = _name, \ 131 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 132 BIT(IIO_CHAN_INFO_SCALE), \ 133 .output = true, \ 134 } 135 136 enum afe440x_reg_type { 137 SIMPLE, 138 RESISTANCE, 139 CAPACITANCE, 140 }; 141 142 struct afe440x_val_table { 143 int integer; 144 int fract; 145 }; 146 147 #define AFE440X_TABLE_ATTR(_name, _table) \ 148 static ssize_t _name ## _show(struct device *dev, \ 149 struct device_attribute *attr, char *buf) \ 150 { \ 151 ssize_t len = 0; \ 152 int i; \ 153 \ 154 for (i = 0; i < ARRAY_SIZE(_table); i++) \ 155 len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", \ 156 _table[i].integer, \ 157 _table[i].fract); \ 158 \ 159 buf[len - 1] = '\n'; \ 160 \ 161 return len; \ 162 } \ 163 static DEVICE_ATTR_RO(_name) 164 165 struct afe440x_attr { 166 struct device_attribute dev_attr; 167 unsigned int reg; 168 unsigned int shift; 169 unsigned int mask; 170 enum afe440x_reg_type type; 171 const struct afe440x_val_table *val_table; 172 unsigned int table_size; 173 }; 174 175 #define to_afe440x_attr(_dev_attr) \ 176 container_of(_dev_attr, struct afe440x_attr, dev_attr) 177 178 #define AFE440X_ATTR(_name, _reg, _field, _type, _table, _size) \ 179 struct afe440x_attr afe440x_attr_##_name = { \ 180 .dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR), \ 181 afe440x_show_register, \ 182 afe440x_store_register), \ 183 .reg = _reg, \ 184 .shift = _field ## _SHIFT, \ 185 .mask = _field ## _MASK, \ 186 .type = _type, \ 187 .val_table = _table, \ 188 .table_size = _size, \ 189 } 190 191 #endif /* _AFE440X_H */ 192