From 79e204d323cd6c465e1a3a53598a655304be1d7a Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 27 Jan 2008 21:14:08 +0000 Subject: partial ISO15693 support (based on patch by Bjoern Kaiser) git-svn-id: https://svn.gnumonks.org/trunk/librfid@2057 e0336214-984f-0b4b-a45f-81c69e1f0ede --- src/rfid_asic_rc632.c | 596 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 425 insertions(+), 171 deletions(-) (limited to 'src/rfid_asic_rc632.c') diff --git a/src/rfid_asic_rc632.c b/src/rfid_asic_rc632.c index b8d8db3..8fc5cb9 100644 --- a/src/rfid_asic_rc632.c +++ b/src/rfid_asic_rc632.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "rfid_iso14443_common.h" @@ -138,6 +139,12 @@ rc632_clear_bits(struct rfid_asic_handle *handle, return rc632_reg_write(handle, reg, (tmp & ~val)&0xff); } +static int +rc632_clear_irqs(struct rfid_asic_handle *handle, u_int8_t bits) +{ + return rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, (~RC632_INT_SET)&bits); +} + static int rc632_rf_power(struct rfid_asic_handle *handle, int on) { @@ -284,20 +291,32 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) if (ret < 0) return ret; - if (cmd == 0) { - /* FIXME: read second time ?? */ - return 0; - } - { u_int8_t foo; rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &foo); - if (foo & 0x04) + DEBUGP_STATUS_FLAG(foo); + /* check if Error has occured (ERR flag set) */ + if (foo & RC632_STAT_ERR) { rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &foo); + DEBUGP_ERROR_FLAG(foo); + } + /* check if IRQ has occurred (IRQ flag set)*/ + if (foo & RC632_STAT_IRQ) { + ret = rc632_reg_read(handle, RC632_REG_INTERRUPT_RQ, &foo); + DEBUGP_INTERRUPT_FLAG(foo); + /* clear all interrupts */ + rc632_clear_irqs(handle, 0xff); + } + } + if (cmd == 0) { + /* FIXME: read second time ?? */ + DEBUGP("cmd == 0 (IDLE)\n"); + return 0; } /* Abort after some timeout */ if (cycles > timeout*100/USLEEP_PER_CYCLE) { + DEBUGP("timeout...\n"); return -ETIMEDOUT; } @@ -351,7 +370,7 @@ rc632_transmit(struct rfid_asic_handle *handle, static int tcl_toggle_pcb(struct rfid_asic_handle *handle) { - // FIXME: toggle something between 0x0a and 0x0b + /* FIXME: toggle something between 0x0a and 0x0b */ return 0; } @@ -364,11 +383,11 @@ rc632_transceive(struct rfid_asic_handle *handle, u_int64_t timer, unsigned int toggle) { - int ret, cur_tx_len; + int ret, cur_tx_len, i; u_int8_t rx_avail; const u_int8_t *cur_tx_buf = tx_buf; - DEBUGP("timer = %u\n", timer); + DEBUGP("timer=%u, rx_len=%u, tx_len=%u,", timer, rx_len, tx_len); if (tx_len > 64) cur_tx_len = 64; @@ -382,6 +401,7 @@ rc632_transceive(struct rfid_asic_handle *handle, ret = rc632_reg_write(handle, RC632_REG_COMMAND, 0x00); /* clear all interrupts */ ret = rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, 0x7f); + ret = rc632_reg_write(handle, RC632_REG_ERROR_FLAG, 0xff); do { ret = rc632_fifo_write(handle, cur_tx_len, cur_tx_buf, 0x03); @@ -404,7 +424,6 @@ rc632_transceive(struct rfid_asic_handle *handle, return ret; cur_tx_len = 64 - fifo_fill; - //printf("refilling tx fifo with %u bytes\n", cur_tx_len); } else cur_tx_len = 0; @@ -415,6 +434,66 @@ rc632_transceive(struct rfid_asic_handle *handle, //ret = rc632_wait_idle_timer(handle); ret = rc632_wait_idle(handle, timer); + + DEBUGP("rc632_wait_idle>>ret=%d %s\n",ret,(ret==-ETIMEDOUT)?"ETIMEDOUT":""); + if (ret < 0) + return ret; + + ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, &rx_avail); + if (ret < 0) + return ret; + + if (rx_avail > *rx_len) + DEBUGP("rx_avail(%d) > rx_len(%d), JFYI\n", rx_avail, *rx_len); + else if (*rx_len > rx_avail) + *rx_len = rx_avail; + + DEBUGP("rx_len == %d\n",*rx_len); + + if (rx_avail == 0) { + u_int8_t tmp; + + for (i = 0; i < 1; i++){ + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &tmp); + DEBUGP_ERROR_FLAG(tmp); + } + rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp); + + //return 0; + return -1; + } + + return rc632_fifo_read(handle, *rx_len, rx_buf); + /* FIXME: discard addidional bytes in FIFO */ +} + + +static int +rc632_receive(struct rfid_asic_handle *handle, + u_int8_t *rx_buf, + u_int8_t *rx_len, + u_int64_t timer) +{ + int ret, cur_tx_len, i; + u_int8_t rx_avail; + + /* + DEBUGP("timer = %u\n", timer); + ret = rc632_timer_set(handle, timer*10); + if (ret < 0) + return ret; + /* + ret = rc632_reg_write(handle, RC632_REG_COMMAND, 0x00); /* IDLE */ + /* clear all interrupts */ + ret = rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, 0x7f); + + ret = rc632_reg_write(handle, RC632_REG_COMMAND,RC632_CMD_RECEIVE); + if (ret < 0) + return ret; + + ret = rc632_wait_idle(handle, timer); if (ret < 0) return ret; @@ -432,14 +511,19 @@ rc632_transceive(struct rfid_asic_handle *handle, DEBUGP("rx_len == 0\n"); - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &tmp); - rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp); + for (i = 0; i < 1; i++) { + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &tmp); + DEBUGP_ERROR_FLAG(tmp); + } + rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp); return -1; } return rc632_fifo_read(handle, *rx_len, rx_buf); - /* FIXME: discard addidional bytes in FIFO */ + /* FIXME: discard additional bytes in FIFO */ } static int @@ -467,7 +551,7 @@ rc632_read_eeprom(struct rfid_asic_handle *handle) if (ret < 0) return ret; - // FIXME: do something with eeprom contents + /* FIXME: do something with eeprom contents */ return ret; } @@ -494,7 +578,7 @@ rc632_calc_crc16_from(struct rfid_asic_handle *handle) if (ret < 0) return ret; - usleep(10000); // FIXME: no checking for cmd completion? + usleep(10000); /* FIXME: no checking for cmd completion? * ret = rc632_reg_read(handle, RC632_REG_CRC_RESULT_LSB, &crc_lsb); if (ret < 0) @@ -504,7 +588,7 @@ rc632_calc_crc16_from(struct rfid_asic_handle *handle) if (ret < 0) return ret; - // FIXME: what to do with crc result? + /* FIXME: what to do with crc result? */ return ret; } @@ -527,14 +611,14 @@ rc632_register_dump(struct rfid_asic_handle *handle, u_int8_t *buf) static int generic_fifo_write() { - // FIXME: implementation (not needed for CM 5121) + /* FIXME: implementation (not needed for CM 5121) */ return -1; } static int generic_fifo_read() { - // FIXME: implementation (not neded for CM 5121) + /* FIXME: implementation (not neded for CM 5121) */ return -1; } @@ -642,7 +726,7 @@ rc632_iso14443a_init(struct rfid_asic_handle *handle) { int ret; - // FIXME: some fifo work (drain fifo?) + /* FIXME: some fifo work (drain fifo?) */ /* flush fifo (our way) */ ret = rc632_reg_write(handle, RC632_REG_CONTROL, @@ -863,6 +947,12 @@ rc632_iso14443ab_transceive(struct rfid_asic_handle *handle, channel_red = RC632_CR_PARITY_ENABLE|RC632_CR_PARITY_ODD; break; #endif + case RFID_15693_FRAME: + channel_red = RC632_CR_CRC3309 | RC632_CR_RX_CRC_ENABLE + | RC632_CR_TX_CRC_ENABLE; + break; + case RFID_15693_FRAME_ICODE1: + /* FIXME: implement */ default: return -EINVAL; break; @@ -871,7 +961,7 @@ rc632_iso14443ab_transceive(struct rfid_asic_handle *handle, channel_red); if (ret < 0) return ret; - + DEBUGP("tx_len=%u\n",tx_len); ret = rc632_transceive(handle, tx_buf, tx_len, rx_buf, &rxl, timeout, 0); *rx_len = rxl; if (ret < 0) @@ -962,6 +1052,138 @@ rc632_iso14443a_transceive_acf(struct rfid_asic_handle *handle, return 0; } +static void uuid_reversecpy(unsigned char* out, unsigned char* in, int len) +{ + int i = 0; + while (len > 0) { + out[i] = in[len]; + len--; + i++; + } +} + + +static int +rc632_iso15693_transceive_ac(struct rfid_asic_handle *handle, + struct iso15693_anticol_cmd *acf, + unsigned char uuid[ISO15693_UID_LEN], + char *bit_of_col) +{ + u_int8_t boc; + u_int8_t error_flag, tmp; + u_int8_t rx_len; + + int ret, tx_len, mask_len_bytes; + + struct iso15693_request_inventory { + struct iso15693_request head; + unsigned char mask_length; + /* mask_value[0] + (maybe crc[2]) */ + unsigned char data[ISO15693_UID_LEN]; + } req; + + struct { + struct iso15693_response head; + unsigned char dsfid; + unsigned char uuid[ISO15693_UID_LEN]; + } rx_buf; + + memset(uuid, 0, ISO15693_UID_LEN); + + *bit_of_col = 0; + rx_len = sizeof(rx_buf); + mask_len_bytes = (acf->mask_len % 8) ? acf->mask_len/8+1 : acf->mask_len/8; + + + if (acf->current_slot == 0) { + /* first call: transmit Inventory frame */ + DEBUGP("first_frame\n"); + req.head.command = ISO15693_CMD_INVENTORY; + req.head.flags = (acf->flags & 0xf0) + | RFID_15693_F_INV_TABLE_5 + | RFID_15693_F_RATE_HIGH; + //| RFID_15693_F_SUBC_TWO | RFID_15693_F_RATE_HIGH; + req.mask_length = acf->mask_len; + memset(req.data, 0, ISO15693_UID_LEN); + memcpy(req.data, acf->mask_bits, mask_len_bytes); + + tx_len = sizeof(struct iso15693_request) + 1 + mask_len_bytes; + + ret = rc632_transceive(handle, (u_int8_t *)&req, tx_len, + (u_int8_t *)&rx_buf, &rx_len, 10, 0); + acf->current_slot = 1; + DEBUGP("rc632_transceive ret: %d rx_len: %d\n",ret,rx_len); + /* if ((ret < 0)&&(ret != -ETIMEDOUT)) + return ret; */ + + } else { + /* second++ call: end timeslot with EOFpulse and read */ + DEBUGP("second++_frame\n"); + if ((acf->current_slot > 16) || + ((acf->flags & RFID_15693_F5_NSLOTS_1 == 0) + && (acf->current_slot > 1))) { + + memset(uuid, 0, ISO15693_UID_LEN); + return -1; + } + + /* reset EOF-pulse-bit to 0 */ + ret = rc632_clear_bits(handle, RC632_REG_CODER_CONTROL, + RC632_CDRCTRL_15693_EOF_PULSE); + usleep(50); + /* generate EOF pulse */ + ret = rc632_set_bits(handle, RC632_REG_CODER_CONTROL, + RC632_CDRCTRL_15693_EOF_PULSE); + if (ret < 0) + return ret; + // DEBUGP("waiting for EOF pulse\n"); + // ret = rc632_wait_idle(handle, 10); //wait for idle + + rx_len = sizeof(rx_buf); + ret = rc632_receive(handle, (u_int8_t*)&rx_buf, &rx_len, 50); + DEBUGP("rc632_receive ret: %d rx_len: %d\n", ret, rx_len); + acf->current_slot++; + + /* if ((ret < 0)&&(ret != -ETIMEDOUT)) + return ret; */ + } + + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + + if (ret == -ETIMEDOUT) { + /* no VICC answer in this timeslot*/ + memset(uuid, 0, ISO15693_UID_LEN); + return -ETIMEDOUT; + } else { + /* determine whether there was a collission */ + ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag); + DEBUGP_ERROR_FLAG(error_flag); + if (ret < 0) + return ret; + + if (error_flag & RC632_ERR_FLAG_COL_ERR) { + /* retrieve bit of collission */ + ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc); + if (ret < 0) + return ret; + *bit_of_col = boc; + memcpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + // uuid_reversecpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + DEBUGP("Collision in slot %d bit %d\n", + acf->current_slot,boc); + return -ECOLLISION; + } else { + /* no collision-> retrieve uuid */ + DEBUGP("no collision in slot %d\n", acf->current_slot); + memcpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + //uuid_reversecpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + } + } + + return 0; +} + enum rc632_rate { RC632_RATE_106 = 0x00, RC632_RATE_212 = 0x01, @@ -1086,8 +1308,8 @@ static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle, static int rc632_iso14443b_init(struct rfid_asic_handle *handle) { int ret; - - // FIXME: some FIFO work + ENTER(); + /* FIXME: some FIFO work */ /* flush fifo (our way) */ ret = rc632_reg_write(handle, RC632_REG_CONTROL, @@ -1192,170 +1414,201 @@ static int rc632_iso14443b_init(struct rfid_asic_handle *handle) return 0; } -static int -rc632_iso15693_init(struct rfid_asic_handle *h) -{ - int ret; - - ret = rc632_reg_write(h, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_MOD_SRC_INT | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX1_RF_EN)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CW_CONDUCTANCE, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_CONDUCTANCE, 0x03); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CODER_CONTROL, - (RC632_CDRCTRL_RATE_15693 | - 0x03)); /* FIXME */ - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_TYPE_B_FRAMING, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL1, - (RC632_RXCTRL1_SUBCP_16 | - RC632_RXCTRL1_ISO15693 | - RC632_RXCTRL1_GAIN_35DB)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_DECODER_CONTROL, - (RC632_DECCTRL_RXFR_15693 | - RC632_DECCTRL_RX_INVERT)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_BIT_PHASE, 0xe0); - if (ret < 0) - return ret; +struct register_file { + u_int8_t reg; + u_int8_t val; +}; - ret = rc632_reg_write(h, RC632_REG_RX_THRESHOLD, 0xff); - if (ret < 0) - return ret; +/* Register file for ISO15693 standard */ +static struct register_file iso15693_fast_script[] = { + { + .reg = RC632_REG_TX_CONTROL, + .val = RC632_TXCTRL_MOD_SRC_INT | + RC632_TXCTRL_TX2_INV | + RC632_TXCTRL_TX2_RF_EN | + RC632_TXCTRL_TX1_RF_EN, + }, { + .reg = RC632_REG_CW_CONDUCTANCE, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_CONDUCTANCE, + /* FIXME: nxp default for icode1/15693: 0x05 */ + //.val = 0x02, + .val = 0x21, /* omnikey */ + }, { + .reg = RC632_REG_CODER_CONTROL, + .val = RC632_CDRCTRL_TXCD_15693_FAST | + RC632_CDRCTRL_RATE_15693, + }, { + .reg = RC632_REG_MOD_WIDTH, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x3f, + }, { + .reg = RC632_REG_TYPE_B_FRAMING, + .val = 0x00, + }, { + .reg = RC632_REG_RX_CONTROL1, + .val = RC632_RXCTRL1_ISO15693 | + RC632_RXCTRL1_SUBCP_16 | + RC632_RXCTRL1_GAIN_35DB, + }, { + /* FIXME: this should always be the case */ + .reg = RC632_REG_RX_CONTROL2, + .val = RC632_RXCTRL2_DECSRC_INT, + }, { + .reg = RC632_REG_DECODER_CONTROL, + .val = RC632_DECCTRL_MANCHESTER | + RC632_DECCTRL_RX_INVERT | + RC632_DECCTRL_ZEROAFTERCOL | + RC632_DECCTRL_RXFR_15693, + }, { + .reg = RC632_REG_BIT_PHASE, + /* FIXME: nxp default for icode1/15693: 0x54 */ + //.val = 0x52, + .val = 0xd0, /* omnikey */ + }, { + .reg = RC632_REG_RX_THRESHOLD, + /* FIXME: nxp default for icode1/15693: 0x68 */ + //.val = 0x66, + .val = 0xed, + }, { + .reg = RC632_REG_BPSK_DEM_CONTROL, + .val = 0x00, + }, { + .reg = RC632_REG_CHANNEL_REDUNDANCY, + .val = RC632_CR_RX_CRC_ENABLE | + RC632_CR_TX_CRC_ENABLE | + RC632_CR_CRC3309, + }, { + .reg = RC632_REG_CRC_PRESET_LSB, + .val = 0xff, + }, { + .reg = RC632_REG_CRC_PRESET_MSB, + .val = 0xff, + }, +}; - ret = rc632_reg_write(h, RC632_REG_BPSK_DEM_CONTROL, 0x00); - if (ret < 0) - return ret; +/* Register file for I*Code standard */ +static struct register_file icode1_std_script[] = { + { + .reg = RC632_REG_TX_CONTROL, + .val = RC632_TXCTRL_MOD_SRC_INT | + RC632_TXCTRL_TX2_INV | + RC632_TXCTRL_TX2_RF_EN | + RC632_TXCTRL_TX1_RF_EN, + }, { + .reg = RC632_REG_CW_CONDUCTANCE, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_CONDUCTANCE, + /* FIXME: nxp default for icode1/15693: 0x05 */ + .val = 0x02, + }, { + .reg = RC632_REG_CODER_CONTROL, + .val = RC632_CDRCTRL_TXCD_ICODE_STD | + RC632_CDRCTRL_RATE_15693, + }, { + .reg = RC632_REG_MOD_WIDTH, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x3f, + }, { + .reg = RC632_REG_TYPE_B_FRAMING, + .val = 0x00, + }, { + .reg = RC632_REG_RX_CONTROL1, + .val = RC632_RXCTRL1_ISO15693 | + RC632_RXCTRL1_SUBCP_16 | + RC632_RXCTRL1_GAIN_35DB, + }, { + /* FIXME: this should always be the case */ + .reg = RC632_REG_RX_CONTROL2, + .val = RC632_RXCTRL2_DECSRC_INT, + }, { + .reg = RC632_REG_DECODER_CONTROL, + .val = RC632_DECCTRL_MANCHESTER | + RC632_DECCTRL_RXFR_ICODE, + }, { + .reg = RC632_REG_BIT_PHASE, + /* FIXME: nxp default for icode1/15693: 0x54 */ + .val = 0x52, + }, { + .reg = RC632_REG_RX_THRESHOLD, + /* FIXME: nxp default for icode1/15693: 0x68 */ + .val = 0x66, + }, { + .reg = RC632_REG_BPSK_DEM_CONTROL, + .val = 0x00, + }, { + .reg = RC632_REG_CHANNEL_REDUNDANCY, + /* 16bit CRC, no parity, not CRC3309 */ + .val = RC632_CR_RX_CRC_ENABLE | + RC632_CR_TX_CRC_ENABLE, + }, { + .reg = RC632_REG_CRC_PRESET_LSB, + .val = 0xfe, + }, { + .reg = RC632_REG_CRC_PRESET_MSB, + .val = 0xff, + } +}; - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL2, - (RC632_RXCTRL2_AUTO_PD | - RC632_RXCTRL2_DECSRC_INT)); - if (ret < 0) - return ret; +/* incremental changes on top of icode1_std_script */ +static struct register_file icode1_fast_patch[] = { + { + .reg = RC632_REG_CODER_CONTROL, + .val = RC632_CDRCTRL_TXCD_ICODE_FAST | + RC632_CDRCTRL_RATE_ICODE_FAST, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x73, /* 18.88uS */ + }, +}; - ret = rc632_reg_write(h, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_CRC3309 | - RC632_CR_RX_CRC_ENABLE | - RC632_CR_TX_CRC_ENABLE)); - if (ret < 0) - return ret; +static int +rc632_iso15693_init(struct rfid_asic_handle *h) +{ + int ret, i; + ENTER(); - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_LSB, 0xff); - if (ret < 0) - return ret; + /* flush fifo (our way) */ + ret = rc632_reg_write(h, RC632_REG_CONTROL, + RC632_CONTROL_FIFO_FLUSH); - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xff); - if (ret < 0) - return ret; + for (i = 0; i < ARRAY_SIZE(iso15693_fast_script); i++) { + ret = rc632_reg_write(h, iso15693_fast_script[i].reg, + iso15693_fast_script[i].val); + if (ret < 0) + return ret; + } return 0; } static int -rc632_iso15693_icode_init(struct rfid_asic_handle *h) +rc632_iso15693_icode1_init(struct rfid_asic_handle *h, int fast) { int ret; + int i; - ret = rc632_reg_write(h, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_MOD_SRC_INT | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX1_RF_EN)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CW_CONDUCTANCE, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_CONDUCTANCE, 0x02); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CODER_CONTROL, 0x2c); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_TYPE_B_FRAMING, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL1, 0x8b); /* FIXME */ - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_DECODER_CONTROL, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_BIT_PHASE, 0x52); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_THRESHOLD, 0x66); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_BPSK_DEM_CONTROL, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL2, - RC632_RXCTRL2_DECSRC_INT); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_RX_CRC_ENABLE | - RC632_CR_TX_CRC_ENABLE)); - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_LSB, 0xfe); - if (ret < 0) - return ret; + for (i = 0; i < ARRAY_SIZE(icode1_std_script); i++) { + ret = rc632_reg_write(h, icode1_std_script[i].reg, + icode1_std_script[i].val); + if (ret < 0) + return ret; + } - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xff); - if (ret < 0) - return ret; + if (fast) { + for (i = 0; i < ARRAY_SIZE(icode1_fast_patch); i++) { + ret = rc632_reg_write(h, icode1_fast_patch[i].reg, + icode1_fast_patch[i].val); + if (ret < 0) + return ret; + } + } return 0; } @@ -1646,6 +1899,7 @@ const struct rfid_asic rc632 = { }, .iso15693 = { .init = &rc632_iso15693_init, + .transceive_ac = &rc632_iso15693_transceive_ac, }, .mifare_classic = { .setkey = &rc632_mifare_set_key, -- cgit v1.2.3