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