Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 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 */ |
Andrew F. Davis | 81f5172 | 2016-05-01 15:36:54 -0500 | [diff] [blame] | 74 | #define AFE440X_TIAGAIN_ENSEPGAIN BIT(15) |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 75 | |
| 76 | /* CONTROL2 register fields */ |
| 77 | #define AFE440X_CONTROL2_PDN_AFE BIT(0) |
| 78 | #define AFE440X_CONTROL2_PDN_RX BIT(1) |
| 79 | #define AFE440X_CONTROL2_DYNAMIC4 BIT(3) |
| 80 | #define AFE440X_CONTROL2_DYNAMIC3 BIT(4) |
| 81 | #define AFE440X_CONTROL2_DYNAMIC2 BIT(14) |
| 82 | #define AFE440X_CONTROL2_DYNAMIC1 BIT(20) |
| 83 | |
| 84 | /* CONTROL3 register fields */ |
| 85 | #define AFE440X_CONTROL3_CLKDIV GENMASK(2, 0) |
| 86 | |
| 87 | /* CONTROL0 values */ |
| 88 | #define AFE440X_CONTROL0_WRITE 0x0 |
| 89 | #define AFE440X_CONTROL0_READ 0x1 |
| 90 | |
Andrew F. Davis | 24b9dea | 2016-05-01 15:36:58 -0500 | [diff] [blame] | 91 | #define AFE440X_INTENSITY_CHAN(_index, _mask) \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 92 | { \ |
| 93 | .type = IIO_INTENSITY, \ |
| 94 | .channel = _index, \ |
| 95 | .address = _index, \ |
| 96 | .scan_index = _index, \ |
| 97 | .scan_type = { \ |
| 98 | .sign = 's', \ |
| 99 | .realbits = 24, \ |
| 100 | .storagebits = 32, \ |
| 101 | .endianness = IIO_CPU, \ |
| 102 | }, \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 103 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
| 104 | _mask, \ |
Andrew F. Davis | 24b9dea | 2016-05-01 15:36:58 -0500 | [diff] [blame] | 105 | .indexed = true, \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 106 | } |
| 107 | |
Andrew F. Davis | 24b9dea | 2016-05-01 15:36:58 -0500 | [diff] [blame] | 108 | #define AFE440X_CURRENT_CHAN(_index) \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 109 | { \ |
| 110 | .type = IIO_CURRENT, \ |
| 111 | .channel = _index, \ |
| 112 | .address = _index, \ |
Andrew F. Davis | 9d3d9a5 | 2016-05-01 15:36:55 -0500 | [diff] [blame] | 113 | .scan_index = -1, \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 114 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
| 115 | BIT(IIO_CHAN_INFO_SCALE), \ |
Andrew F. Davis | 24b9dea | 2016-05-01 15:36:58 -0500 | [diff] [blame] | 116 | .indexed = true, \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 117 | .output = true, \ |
| 118 | } |
| 119 | |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 120 | struct afe440x_val_table { |
| 121 | int integer; |
| 122 | int fract; |
| 123 | }; |
| 124 | |
| 125 | #define AFE440X_TABLE_ATTR(_name, _table) \ |
| 126 | static ssize_t _name ## _show(struct device *dev, \ |
| 127 | struct device_attribute *attr, char *buf) \ |
| 128 | { \ |
| 129 | ssize_t len = 0; \ |
| 130 | int i; \ |
| 131 | \ |
| 132 | for (i = 0; i < ARRAY_SIZE(_table); i++) \ |
| 133 | len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", \ |
| 134 | _table[i].integer, \ |
| 135 | _table[i].fract); \ |
| 136 | \ |
| 137 | buf[len - 1] = '\n'; \ |
| 138 | \ |
| 139 | return len; \ |
| 140 | } \ |
| 141 | static DEVICE_ATTR_RO(_name) |
| 142 | |
| 143 | struct afe440x_attr { |
| 144 | struct device_attribute dev_attr; |
Andrew F. Davis | b36e825 | 2016-05-01 15:36:59 -0500 | [diff] [blame] | 145 | unsigned int field; |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 146 | const struct afe440x_val_table *val_table; |
| 147 | unsigned int table_size; |
| 148 | }; |
| 149 | |
| 150 | #define to_afe440x_attr(_dev_attr) \ |
| 151 | container_of(_dev_attr, struct afe440x_attr, dev_attr) |
| 152 | |
Andrew F. Davis | b36e825 | 2016-05-01 15:36:59 -0500 | [diff] [blame] | 153 | #define AFE440X_ATTR(_name, _field, _table) \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 154 | struct afe440x_attr afe440x_attr_##_name = { \ |
| 155 | .dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR), \ |
| 156 | afe440x_show_register, \ |
| 157 | afe440x_store_register), \ |
Andrew F. Davis | b36e825 | 2016-05-01 15:36:59 -0500 | [diff] [blame] | 158 | .field = _field, \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 159 | .val_table = _table, \ |
Andrew F. Davis | 81f5172 | 2016-05-01 15:36:54 -0500 | [diff] [blame] | 160 | .table_size = ARRAY_SIZE(_table), \ |
Andrew F. Davis | 87aec56 | 2016-02-02 11:50:44 -0600 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | #endif /* _AFE440X_H */ |