187aec56eSAndrew F. Davis /* 287aec56eSAndrew F. Davis * AFE440X Heart Rate Monitors and Low-Cost Pulse Oximeters 387aec56eSAndrew F. Davis * 487aec56eSAndrew F. Davis * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 587aec56eSAndrew F. Davis * Andrew F. Davis <afd@ti.com> 687aec56eSAndrew F. Davis * 787aec56eSAndrew F. Davis * This program is free software; you can redistribute it and/or modify 887aec56eSAndrew F. Davis * it under the terms of the GNU General Public License version 2 as 987aec56eSAndrew F. Davis * published by the Free Software Foundation. 1087aec56eSAndrew F. Davis * 1187aec56eSAndrew F. Davis * This program is distributed in the hope that it will be useful, but 1287aec56eSAndrew F. Davis * WITHOUT ANY WARRANTY; without even the implied warranty of 1387aec56eSAndrew F. Davis * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1487aec56eSAndrew F. Davis * General Public License for more details. 1587aec56eSAndrew F. Davis */ 1687aec56eSAndrew F. Davis 1787aec56eSAndrew F. Davis #ifndef _AFE440X_H 1887aec56eSAndrew F. Davis #define _AFE440X_H 1987aec56eSAndrew F. Davis 2087aec56eSAndrew F. Davis /* AFE440X registers */ 2187aec56eSAndrew F. Davis #define AFE440X_CONTROL0 0x00 2287aec56eSAndrew F. Davis #define AFE440X_LED2STC 0x01 2387aec56eSAndrew F. Davis #define AFE440X_LED2ENDC 0x02 2487aec56eSAndrew F. Davis #define AFE440X_LED1LEDSTC 0x03 2587aec56eSAndrew F. Davis #define AFE440X_LED1LEDENDC 0x04 2687aec56eSAndrew F. Davis #define AFE440X_ALED2STC 0x05 2787aec56eSAndrew F. Davis #define AFE440X_ALED2ENDC 0x06 2887aec56eSAndrew F. Davis #define AFE440X_LED1STC 0x07 2987aec56eSAndrew F. Davis #define AFE440X_LED1ENDC 0x08 3087aec56eSAndrew F. Davis #define AFE440X_LED2LEDSTC 0x09 3187aec56eSAndrew F. Davis #define AFE440X_LED2LEDENDC 0x0a 3287aec56eSAndrew F. Davis #define AFE440X_ALED1STC 0x0b 3387aec56eSAndrew F. Davis #define AFE440X_ALED1ENDC 0x0c 3487aec56eSAndrew F. Davis #define AFE440X_LED2CONVST 0x0d 3587aec56eSAndrew F. Davis #define AFE440X_LED2CONVEND 0x0e 3687aec56eSAndrew F. Davis #define AFE440X_ALED2CONVST 0x0f 3787aec56eSAndrew F. Davis #define AFE440X_ALED2CONVEND 0x10 3887aec56eSAndrew F. Davis #define AFE440X_LED1CONVST 0x11 3987aec56eSAndrew F. Davis #define AFE440X_LED1CONVEND 0x12 4087aec56eSAndrew F. Davis #define AFE440X_ALED1CONVST 0x13 4187aec56eSAndrew F. Davis #define AFE440X_ALED1CONVEND 0x14 4287aec56eSAndrew F. Davis #define AFE440X_ADCRSTSTCT0 0x15 4387aec56eSAndrew F. Davis #define AFE440X_ADCRSTENDCT0 0x16 4487aec56eSAndrew F. Davis #define AFE440X_ADCRSTSTCT1 0x17 4587aec56eSAndrew F. Davis #define AFE440X_ADCRSTENDCT1 0x18 4687aec56eSAndrew F. Davis #define AFE440X_ADCRSTSTCT2 0x19 4787aec56eSAndrew F. Davis #define AFE440X_ADCRSTENDCT2 0x1a 4887aec56eSAndrew F. Davis #define AFE440X_ADCRSTSTCT3 0x1b 4987aec56eSAndrew F. Davis #define AFE440X_ADCRSTENDCT3 0x1c 5087aec56eSAndrew F. Davis #define AFE440X_PRPCOUNT 0x1d 5187aec56eSAndrew F. Davis #define AFE440X_CONTROL1 0x1e 5287aec56eSAndrew F. Davis #define AFE440X_LEDCNTRL 0x22 5387aec56eSAndrew F. Davis #define AFE440X_CONTROL2 0x23 5487aec56eSAndrew F. Davis #define AFE440X_ALARM 0x29 5587aec56eSAndrew F. Davis #define AFE440X_LED2VAL 0x2a 5687aec56eSAndrew F. Davis #define AFE440X_ALED2VAL 0x2b 5787aec56eSAndrew F. Davis #define AFE440X_LED1VAL 0x2c 5887aec56eSAndrew F. Davis #define AFE440X_ALED1VAL 0x2d 5987aec56eSAndrew F. Davis #define AFE440X_LED2_ALED2VAL 0x2e 6087aec56eSAndrew F. Davis #define AFE440X_LED1_ALED1VAL 0x2f 6187aec56eSAndrew F. Davis #define AFE440X_CONTROL3 0x31 6287aec56eSAndrew F. Davis #define AFE440X_PDNCYCLESTC 0x32 6387aec56eSAndrew F. Davis #define AFE440X_PDNCYCLEENDC 0x33 6487aec56eSAndrew F. Davis 6587aec56eSAndrew F. Davis /* CONTROL0 register fields */ 6687aec56eSAndrew F. Davis #define AFE440X_CONTROL0_REG_READ BIT(0) 6787aec56eSAndrew F. Davis #define AFE440X_CONTROL0_TM_COUNT_RST BIT(1) 6887aec56eSAndrew F. Davis #define AFE440X_CONTROL0_SW_RESET BIT(3) 6987aec56eSAndrew F. Davis 7087aec56eSAndrew F. Davis /* CONTROL1 register fields */ 7187aec56eSAndrew F. Davis #define AFE440X_CONTROL1_TIMEREN BIT(8) 7287aec56eSAndrew F. Davis 7387aec56eSAndrew F. Davis /* TIAGAIN register fields */ 7481f51727SAndrew F. Davis #define AFE440X_TIAGAIN_ENSEPGAIN BIT(15) 7587aec56eSAndrew F. Davis 7687aec56eSAndrew F. Davis /* CONTROL2 register fields */ 7787aec56eSAndrew F. Davis #define AFE440X_CONTROL2_PDN_AFE BIT(0) 7887aec56eSAndrew F. Davis #define AFE440X_CONTROL2_PDN_RX BIT(1) 7987aec56eSAndrew F. Davis #define AFE440X_CONTROL2_DYNAMIC4 BIT(3) 8087aec56eSAndrew F. Davis #define AFE440X_CONTROL2_DYNAMIC3 BIT(4) 8187aec56eSAndrew F. Davis #define AFE440X_CONTROL2_DYNAMIC2 BIT(14) 8287aec56eSAndrew F. Davis #define AFE440X_CONTROL2_DYNAMIC1 BIT(20) 8387aec56eSAndrew F. Davis 8487aec56eSAndrew F. Davis /* CONTROL3 register fields */ 8587aec56eSAndrew F. Davis #define AFE440X_CONTROL3_CLKDIV GENMASK(2, 0) 8687aec56eSAndrew F. Davis 8787aec56eSAndrew F. Davis /* CONTROL0 values */ 8887aec56eSAndrew F. Davis #define AFE440X_CONTROL0_WRITE 0x0 8987aec56eSAndrew F. Davis #define AFE440X_CONTROL0_READ 0x1 9087aec56eSAndrew F. Davis 9187aec56eSAndrew F. Davis struct afe440x_reg_info { 9287aec56eSAndrew F. Davis unsigned int reg; 9387aec56eSAndrew F. Davis unsigned int offreg; 9487aec56eSAndrew F. Davis unsigned int shift; 9587aec56eSAndrew F. Davis unsigned int mask; 9687aec56eSAndrew F. Davis }; 9787aec56eSAndrew F. Davis 9887aec56eSAndrew F. Davis #define AFE440X_REG_INFO(_reg, _offreg, _sm) \ 9987aec56eSAndrew F. Davis { \ 10087aec56eSAndrew F. Davis .reg = _reg, \ 10187aec56eSAndrew F. Davis .offreg = _offreg, \ 10287aec56eSAndrew F. Davis .shift = _sm ## _SHIFT, \ 10387aec56eSAndrew F. Davis .mask = _sm ## _MASK, \ 10487aec56eSAndrew F. Davis } 10587aec56eSAndrew F. Davis 10687aec56eSAndrew F. Davis #define AFE440X_INTENSITY_CHAN(_index, _name, _mask) \ 10787aec56eSAndrew F. Davis { \ 10887aec56eSAndrew F. Davis .type = IIO_INTENSITY, \ 10987aec56eSAndrew F. Davis .channel = _index, \ 11087aec56eSAndrew F. Davis .address = _index, \ 11187aec56eSAndrew F. Davis .scan_index = _index, \ 11287aec56eSAndrew F. Davis .scan_type = { \ 11387aec56eSAndrew F. Davis .sign = 's', \ 11487aec56eSAndrew F. Davis .realbits = 24, \ 11587aec56eSAndrew F. Davis .storagebits = 32, \ 11687aec56eSAndrew F. Davis .endianness = IIO_CPU, \ 11787aec56eSAndrew F. Davis }, \ 11887aec56eSAndrew F. Davis .extend_name = _name, \ 11987aec56eSAndrew F. Davis .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 12087aec56eSAndrew F. Davis _mask, \ 12187aec56eSAndrew F. Davis } 12287aec56eSAndrew F. Davis 12387aec56eSAndrew F. Davis #define AFE440X_CURRENT_CHAN(_index, _name) \ 12487aec56eSAndrew F. Davis { \ 12587aec56eSAndrew F. Davis .type = IIO_CURRENT, \ 12687aec56eSAndrew F. Davis .channel = _index, \ 12787aec56eSAndrew F. Davis .address = _index, \ 128*9d3d9a57SAndrew F. Davis .scan_index = -1, \ 12987aec56eSAndrew F. Davis .extend_name = _name, \ 13087aec56eSAndrew F. Davis .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 13187aec56eSAndrew F. Davis BIT(IIO_CHAN_INFO_SCALE), \ 13287aec56eSAndrew F. Davis .output = true, \ 13387aec56eSAndrew F. Davis } 13487aec56eSAndrew F. Davis 13587aec56eSAndrew F. Davis struct afe440x_val_table { 13687aec56eSAndrew F. Davis int integer; 13787aec56eSAndrew F. Davis int fract; 13887aec56eSAndrew F. Davis }; 13987aec56eSAndrew F. Davis 14087aec56eSAndrew F. Davis #define AFE440X_TABLE_ATTR(_name, _table) \ 14187aec56eSAndrew F. Davis static ssize_t _name ## _show(struct device *dev, \ 14287aec56eSAndrew F. Davis struct device_attribute *attr, char *buf) \ 14387aec56eSAndrew F. Davis { \ 14487aec56eSAndrew F. Davis ssize_t len = 0; \ 14587aec56eSAndrew F. Davis int i; \ 14687aec56eSAndrew F. Davis \ 14787aec56eSAndrew F. Davis for (i = 0; i < ARRAY_SIZE(_table); i++) \ 14887aec56eSAndrew F. Davis len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", \ 14987aec56eSAndrew F. Davis _table[i].integer, \ 15087aec56eSAndrew F. Davis _table[i].fract); \ 15187aec56eSAndrew F. Davis \ 15287aec56eSAndrew F. Davis buf[len - 1] = '\n'; \ 15387aec56eSAndrew F. Davis \ 15487aec56eSAndrew F. Davis return len; \ 15587aec56eSAndrew F. Davis } \ 15687aec56eSAndrew F. Davis static DEVICE_ATTR_RO(_name) 15787aec56eSAndrew F. Davis 15887aec56eSAndrew F. Davis struct afe440x_attr { 15987aec56eSAndrew F. Davis struct device_attribute dev_attr; 16087aec56eSAndrew F. Davis unsigned int reg; 16187aec56eSAndrew F. Davis unsigned int shift; 16287aec56eSAndrew F. Davis unsigned int mask; 16387aec56eSAndrew F. Davis const struct afe440x_val_table *val_table; 16487aec56eSAndrew F. Davis unsigned int table_size; 16587aec56eSAndrew F. Davis }; 16687aec56eSAndrew F. Davis 16787aec56eSAndrew F. Davis #define to_afe440x_attr(_dev_attr) \ 16887aec56eSAndrew F. Davis container_of(_dev_attr, struct afe440x_attr, dev_attr) 16987aec56eSAndrew F. Davis 17081f51727SAndrew F. Davis #define AFE440X_ATTR(_name, _reg, _field, _table) \ 17187aec56eSAndrew F. Davis struct afe440x_attr afe440x_attr_##_name = { \ 17287aec56eSAndrew F. Davis .dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR), \ 17387aec56eSAndrew F. Davis afe440x_show_register, \ 17487aec56eSAndrew F. Davis afe440x_store_register), \ 17587aec56eSAndrew F. Davis .reg = _reg, \ 17687aec56eSAndrew F. Davis .shift = _field ## _SHIFT, \ 17787aec56eSAndrew F. Davis .mask = _field ## _MASK, \ 17887aec56eSAndrew F. Davis .val_table = _table, \ 17981f51727SAndrew F. Davis .table_size = ARRAY_SIZE(_table), \ 18087aec56eSAndrew F. Davis } 18187aec56eSAndrew F. Davis 18287aec56eSAndrew F. Davis #endif /* _AFE440X_H */ 183