From: Erik Lilliebjerg Date: Wed, 29 Jun 2016 01:57:07 +0000 (-0700) Subject: iio: imu: nvi v.333 ICM DMP FW v.2 X-Git-Tag: tegra-l4t-r24.2~20 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/sojka/nv-tegra/linux-3.10.git/commitdiff_plain/8043ffcd092fb8f1275b82086ec4b492567ebb3c iio: imu: nvi v.333 ICM DMP FW v.2 - Implement Invensense ICM DMP FW v.2 that fixes sensor data timing gaps. Bug 1768847 Change-Id: I0bde444d2cdfa0721541fad40589135a37a74acd Signed-off-by: Erik Lilliebjerg Reviewed-on: http://git-master/r/1172879 (cherry picked from commit c95d320e9a4b85d13261d2572a39608e1dbb5f43) Reviewed-on: http://git-master/r/1185051 GVS: Gerrit_Virtual_Submit Tested-by: Robert Collins Reviewed-by: Robert Collins --- diff --git a/drivers/iio/imu/nvi_mpu/nvi.c b/drivers/iio/imu/nvi_mpu/nvi.c index 1efe07ac6a5..c5ed766a74e 100644 --- a/drivers/iio/imu/nvi_mpu/nvi.c +++ b/drivers/iio/imu/nvi_mpu/nvi.c @@ -29,7 +29,7 @@ #include "nvi.h" -#define NVI_DRIVER_VERSION (330) +#define NVI_DRIVER_VERSION (333) #define NVI_VENDOR "Invensense" #define NVI_NAME "mpu6xxx" #define NVI_NAME_MPU6050 "mpu6050" @@ -106,7 +106,8 @@ enum NVI_INFO { NVI_INFO_MEM_RD, NVI_INFO_MEM_WR, NVI_INFO_DMP_FW, - NVI_INFO_DMP_EN_MSK + NVI_INFO_DMP_EN_MSK, + NVI_INFO_FN_INIT }; /* regulator names in order of powering on */ @@ -206,6 +207,16 @@ static void nvi_enable_irq(struct nvi_state *st) } } +static void nvi_rc_clr(struct nvi_state *st, const char *fn) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(st->rc_msk); i++) + st->rc_msk[i] = 0; + if (st->sts & NVI_DBG_SPEW_MSG) + dev_info(&st->i2c->dev, "%s-%s\n", __func__, fn); +} + static int nvi_i2c_w(struct nvi_state *st, u16 len, u8 *buf) { struct i2c_msg msg; @@ -225,24 +236,33 @@ static int nvi_i2c_w(struct nvi_state *st, u16 len, u8 *buf) static int nvi_wr_reg_bank_sel(struct nvi_state *st, u8 reg_bank) { u8 buf[2]; + bool wr = true; int ret = 0; if (!st->hal->reg->reg_bank.reg) return 0; reg_bank <<= 4; - if (reg_bank != st->rc.reg_bank) { + if (st->rc_msk[NVI_RC_BANK_REG_BANK] & NVI_RC_MSK_REG_BANK) { + if (reg_bank == st->rc.reg_bank) + wr = false; + } + if (wr) { buf[0] = st->hal->reg->reg_bank.reg; buf[1] = reg_bank; ret = nvi_i2c_w(st, sizeof(buf), buf); if (ret) { dev_err(&st->i2c->dev, "%s 0x%x!->0x%x ERR=%d\n", __func__, st->rc.reg_bank, reg_bank, ret); + st->rc_msk[NVI_RC_BANK_REG_BANK] &= + ~NVI_RC_MSK_REG_BANK; } else { if (st->sts & NVI_DBG_SPEW_MSG) dev_info(&st->i2c->dev, "%s 0x%x->0x%x\n", __func__, st->rc.reg_bank, reg_bank); st->rc.reg_bank = reg_bank; + st->rc_msk[NVI_RC_BANK_REG_BANK] |= + NVI_RC_MSK_REG_BANK; } } return ret; @@ -285,26 +305,44 @@ static int nvi_i2c_write_le(struct nvi_state *st, const struct nvi_br *br, int nvi_i2c_write_rc(struct nvi_state *st, const struct nvi_br *br, u32 val, const char *fn, u8 *rc, bool be) { - bool wr = false; u16 len; + u64 rc_msk; + bool wr; + unsigned int rc_bank; unsigned int i; int ret = 0; len = br->len; if (!len) len++; + rc_bank = br->bank; + rc_bank <<= 7; /* registers only go to 0x7F */ + rc_bank |= br->reg; + rc_msk = ((1 << len) - 1) << (rc_bank % 64); + rc_bank /= 64; val |= br->dflt; - if (rc != NULL) { - for (i = 0; i < len; i++) { - if (*(rc + i) != (u8)(val >> (8 * i))) { + wr = st->rc_dis; + if (!wr) { + if (rc) { + if ((st->rc_msk[rc_bank] & rc_msk) == rc_msk) { + /* register is cached */ + for (i = 0; i < len; i++) { + if (*(rc + i) != + (u8)(val >> (8 * i))) { + /* register data changed */ + wr = true; + break; + } + } + } else { + /* register not cached */ wr = true; - break; } + } else { + wr = true; } - } else { - wr = true; } - if (wr || st->rc_dis) { + if (wr) { if (be) ret = nvi_i2c_write_be(st, br, len, val); else @@ -315,14 +353,19 @@ int nvi_i2c_write_rc(struct nvi_state *st, const struct nvi_br *br, u32 val, dev_err(&st->i2c->dev, "%s 0x%08x!=>0x%01x%02x ERR=%d\n", fn, val, br->bank, br->reg, ret); + st->rc_msk[rc_bank] &= ~rc_msk; } else { if (st->sts & NVI_DBG_SPEW_MSG && fn) dev_info(&st->i2c->dev, "%s 0x%08x=>0x%01x%02x\n", fn, val, br->bank, br->reg); - if (rc != NULL) { + if (rc) { for (i = 0; i < len; i++) *(rc + i) = (u8)(val >> (8 * i)); + st->rc_msk[rc_bank] |= rc_msk; + } else { + /* register data not cached */ + st->rc_msk[rc_bank] &= ~rc_msk; } } } @@ -359,13 +402,45 @@ int nvi_i2c_wr(struct nvi_state *st, const struct nvi_br *br, int nvi_i2c_wr_rc(struct nvi_state *st, const struct nvi_br *br, u8 val, const char *fn, u8 *rc) { + u64 rc_msk; + bool wr; + unsigned int rc_bank; int ret = 0; val |= br->dflt; - if (val != *rc || st->rc_dis) { + rc_bank = br->bank; + rc_bank <<= 7; /* registers only go to 0x7F */ + rc_bank |= br->reg; + rc_msk = 1 << (rc_bank % 64); + rc_bank /= 64; + wr = st->rc_dis; + if (!wr) { + if (rc) { + if (st->rc_msk[rc_bank] & rc_msk) { + /* register is cached */ + if (val != *rc) + /* register data changed */ + wr = true; + } else { + /* register not cached */ + wr = true; + } + } else { + wr = true; + } + } + if (wr) { ret = nvi_i2c_wr(st, br, val, fn); - if (!ret) - *rc = val; + if (ret) { + st->rc_msk[rc_bank] &= ~rc_msk; + } else { + if (rc) { + *rc = val; + st->rc_msk[rc_bank] |= rc_msk; + } else { + st->rc_msk[rc_bank] &= ~rc_msk; + } + } } return ret; } @@ -775,7 +850,8 @@ static int nvi_user_ctrl_rst(struct nvi_state *st, u8 user_ctrl) if (st->hal->reg->fifo_rst.reg) { /* ICM part */ if (st->en_msk & (1 << DEV_DMP)) { - ret = nvi_wr_fifo_cfg(st, 0); + ret = nvi_wr_fifo_cfg(st, + st->hal->dmp->fifo_mode); } else { n = 0; for (i = 0; i < DEV_AXIS_N; i++) { @@ -933,9 +1009,8 @@ int nvi_wr_pm1(struct nvi_state *st, const char *fn, u8 pm1) st->pm = NVI_PM_ERR; if (pm1 & BIT_H_RESET && !ret) { st->en_msk &= MSK_RST; - memset(&st->rc, 0, sizeof(st->rc)); - if (st->hal->fn->por2rc) - st->hal->fn->por2rc(st); + nvi_rc_clr(st, __func__); + st->rc_dis = false; for (i = 0; i < st->hal->src_n; i++) st->src[i].period_us_req = 0; @@ -948,11 +1023,9 @@ int nvi_wr_pm1(struct nvi_state *st, const char *fn, u8 pm1) } msleep(POR_MS); - st->rc.pm1 = pm1_rd; nvi_rd_accel_offset(st); nvi_rd_gyro_offset(st); nvi_dmp_fw(st); - st->rc_dis = false; } if (st->sts & NVI_DBG_SPEW_MSG) dev_info(&st->i2c->dev, "%s-%s pm1=%x err=%d\n", @@ -1177,6 +1250,7 @@ static int nvi_dmp_fw(struct nvi_state *st) #endif /* NVI_FW_CRC_CHECK */ int ret; + st->icm_dmp_war = false; if (!st->hal->dmp) return -EINVAL; @@ -1417,7 +1491,11 @@ static int nvi_en(struct nvi_state *st) if (i < DEV_N_AUX) break; - return nvi_pm(st, __func__, NVI_PM_AUTO); + ret_t = nvi_pm(st, __func__, NVI_PM_AUTO); + if (st->sts & (NVS_STS_SPEW_MSG | NVI_DBG_SPEW_MSG)) + dev_info(&st->i2c->dev, "%s en_msk=%x err=%d\n", + __func__, st->en_msk, ret_t); + return ret_t; } ret_t |= nvi_int_able(st, __func__, false); @@ -1843,7 +1921,8 @@ static int nvi_aux_bypass_request(struct nvi_state *st, bool enable) } else { if (st->aux.bypass_lock) { ns = nvs_timestamp() - st->aux.bypass_timeout_ns; - to = st->bypass_timeout_ms * 1000000; + to = st->bypass_timeout_ms; + to *= 1000000; if (ns > to) st->aux.bypass_lock = 0; else @@ -2775,7 +2854,8 @@ static int nvi_fifo_rd(struct nvi_state *st, int src, unsigned int fifo_n_max, } if (ts_n) { - ts_period = st->src[src].period_us_src * 1000; + ts_period = st->src[src].period_us_src; + ts_period *= 1000; if (sync && ts_end > st->src[src].ts_end && ts_end < ts_now && ts_end > (ts_now - (ts_period >> 2))) /* ts_irq is within the rate so sync to IRQ */ @@ -3092,6 +3172,7 @@ static int nvi_flush(void *client, int snsr_id) static int nvi_max_range(void *client, int snsr_id, int max_range) { struct nvi_state *st = (struct nvi_state *)client; + int ret = 0; unsigned int i = max_range; unsigned int ch; @@ -3128,7 +3209,9 @@ static int nvi_max_range(void *client, int snsr_id, int max_range) } } - return 0; + if (st->en_msk & (1 << DEV_DMP)) + ret = nvi_en(st); + return ret; } static int nvi_offset(void *client, int snsr_id, int channel, int offset) @@ -3231,9 +3314,9 @@ static int nvi_self_test(void *client, int snsr_id, char *buf) nvi_period_all(st); nvi_en(st); if (ret) - return sprintf(buf, "%d FAIL\n", ret); + return snprintf(buf, PAGE_SIZE, "%d FAIL\n", ret); - return sprintf(buf, "%d PASS\n", ret); + return snprintf(buf, PAGE_SIZE, "%d PASS\n", ret); } static int nvi_regs(void *client, int snsr_id, char *buf) @@ -3245,9 +3328,9 @@ static int nvi_regs(void *client, int snsr_id, char *buf) unsigned int j; int ret; - t = sprintf(buf, "registers: (only data != 0 shown)\n"); + t = snprintf(buf, PAGE_SIZE, "registers: (only data != 0 shown)\n"); for (j = 0; j < st->hal->reg_bank_n; j++) { - t += sprintf(buf + t, "bank %u:\n", j); + t += snprintf(buf + t, PAGE_SIZE - t, "bank %u:\n", j); for (i = 0; i < st->hal->regs_n; i++) { if ((j == st->hal->reg->fifo_rw.bank) && (i == st->hal->reg->fifo_rw.reg)) @@ -3255,9 +3338,10 @@ static int nvi_regs(void *client, int snsr_id, char *buf) ret = nvi_i2c_r(st, j, i, 1, &data); if (ret) - t += sprintf(buf + t, "0x%02x=ERR\n", i); + t += snprintf(buf + t, PAGE_SIZE - t, + "0x%02x=ERR\n", i); else if (data) - t += sprintf(buf + t, + t += snprintf(buf + t, PAGE_SIZE - t, "0x%02x=0x%02x\n", i, data); } } @@ -3276,6 +3360,7 @@ static int nvi_nvs_write(void *client, int snsr_id, unsigned int nvs) case NVI_INFO_MEM_WR: case NVI_INFO_DMP_FW: case NVI_INFO_DMP_EN_MSK: + case NVI_INFO_FN_INIT: break; case NVI_INFO_DBG_SPEW: @@ -3321,75 +3406,85 @@ static int nvi_nvs_read(void *client, int snsr_id, char *buf) st->info = NVI_INFO_VER; switch (info & 0xFF) { case NVI_INFO_VER: - t = sprintf(buf, "NVI driver v. %u\n", NVI_DRIVER_VERSION); + t = snprintf(buf, PAGE_SIZE, "NVI driver v. %u\n", + NVI_DRIVER_VERSION); if (st->en_msk & (1 << FW_LOADED)) { - t += sprintf(buf + t, "DMP FW v. %u\n", - st->hal->dmp->fw_ver); - t += sprintf(buf + t, "DMP enabled=%u\n", - !!(st->en_msk & (1 << DEV_DMP))); + t += snprintf(buf + t, PAGE_SIZE - t, "DMP FW v. %u\n", + st->hal->dmp->fw_ver); + t += snprintf(buf + t, PAGE_SIZE - t, + "DMP enabled=%u\n", + !!(st->en_msk & (1 << DEV_DMP))); } - t += sprintf(buf + t, "standby_en=%x\n", - !!(st->en_msk & (1 << EN_STDBY))); - t += sprintf(buf + t, "bypass_timeout_ms=%u\n", - st->bypass_timeout_ms); + t += snprintf(buf + t, PAGE_SIZE - t, "standby_en=%x\n", + !!(st->en_msk & (1 << EN_STDBY))); + t += snprintf(buf + t, PAGE_SIZE - t, "bypass_timeout_ms=%u\n", + st->bypass_timeout_ms); for (i = 0; i < DEV_N_AUX; i++) { if (st->snsr[i].push_delay_ns) - t += sprintf(buf + t, - "%s_push_delay_ns=%lld\n", - st->snsr[i].cfg.name, - st->snsr[i].push_delay_ns); + t += snprintf(buf + t, PAGE_SIZE - t, + "%s_push_delay_ns=%lld\n", + st->snsr[i].cfg.name, + st->snsr[i].push_delay_ns); } for (i = 0; i < DEV_N_AUX; i++) { if ((st->dmp_dev_msk | MSK_DEV_MPU_AUX) & (1 << i)) { if (st->dmp_en_msk & (1 << i)) - t += sprintf(buf + t, "%s_dmp_en=1\n", - st->snsr[i].cfg.name); + t += snprintf(buf + t, PAGE_SIZE - t, + "%s_dmp_en=1\n", + st->snsr[i].cfg.name); else - t += sprintf(buf + t, "%s_dmp_en=0\n", - st->snsr[i].cfg.name); + t += snprintf(buf + t, PAGE_SIZE - t, + "%s_dmp_en=0\n", + st->snsr[i].cfg.name); } } return t; case NVI_INFO_DBG: - t = sprintf(buf, "en_msk=%x\n", st->en_msk); - t += sprintf(buf + t, "sts=%x\n", st->sts); - t += sprintf(buf + t, "pm=%d\n", st->pm); - t += sprintf(buf + t, "bm_timeout_us=%u\n", st->bm_timeout_us); - t += sprintf(buf + t, "fifo_src=%d\n", st->fifo_src); + t = snprintf(buf, PAGE_SIZE, "en_msk=%x\n", st->en_msk); + t += snprintf(buf + t, PAGE_SIZE - t, "sts=%x\n", st->sts); + t += snprintf(buf + t, PAGE_SIZE - t, "pm=%d\n", st->pm); + t += snprintf(buf + t, PAGE_SIZE - t, "bm_timeout_us=%u\n", + st->bm_timeout_us); + t += snprintf(buf + t, PAGE_SIZE - t, "fifo_src=%d\n", + st->fifo_src); for (i = 0; i < DEV_N_AUX; i++) { - t += sprintf(buf + t, "snsr[%u] %s:\n", - i, st->snsr[i].cfg.name); - t += sprintf(buf + t, "enable=%x\n", - st->snsr[i].enable); - t += sprintf(buf + t, "period_us=%u\n", - st->snsr[i].period_us); - t += sprintf(buf + t, "timeout_us=%u\n", - st->snsr[i].timeout_us); - t += sprintf(buf + t, "odr=%u\n", - st->snsr[i].odr); - t += sprintf(buf + t, "ts_last=%lld\n", - st->snsr[i].ts_last); - t += sprintf(buf + t, "ts_reset=%x\n", - st->snsr[i].ts_reset); - t += sprintf(buf + t, "flush=%x\n", - st->snsr[i].flush); - t += sprintf(buf + t, "matrix=%x\n", - st->snsr[i].matrix); - t += sprintf(buf + t, "buf_shft=%d\n", - st->snsr[i].buf_shft); - t += sprintf(buf + t, "buf_n=%u\n", - st->snsr[i].buf_n); + t += snprintf(buf + t, PAGE_SIZE - t, "snsr[%u] %s:\n", + i, st->snsr[i].cfg.name); + t += snprintf(buf + t, PAGE_SIZE - t, "usr_cfg=%x\n", + st->snsr[i].usr_cfg); + t += snprintf(buf + t, PAGE_SIZE - t, "enable=%x\n", + st->snsr[i].enable); + t += snprintf(buf + t, PAGE_SIZE - t, "period_us=%u\n", + st->snsr[i].period_us); + t += snprintf(buf + t, PAGE_SIZE - t, + "timeout_us=%u\n", + st->snsr[i].timeout_us); + t += snprintf(buf + t, PAGE_SIZE - t, "odr=%u\n", + st->snsr[i].odr); + t += snprintf(buf + t, PAGE_SIZE - t, "ts_last=%lld\n", + st->snsr[i].ts_last); + t += snprintf(buf + t, PAGE_SIZE - t, "ts_reset=%x\n", + st->snsr[i].ts_reset); + t += snprintf(buf + t, PAGE_SIZE - t, "flush=%x\n", + st->snsr[i].flush); + t += snprintf(buf + t, PAGE_SIZE - t, "matrix=%x\n", + st->snsr[i].matrix); + t += snprintf(buf + t, PAGE_SIZE - t, "buf_shft=%d\n", + st->snsr[i].buf_shft); + t += snprintf(buf + t, PAGE_SIZE - t, "buf_n=%u\n", + st->snsr[i].buf_n); } if (st->hal->dmp) { /* nvi_dmp_clk_n */ st->hal->dmp->fn_clk_n(st, &n); - t += sprintf(buf + t, "nvi_dmp_clk_n=%u\n", n); - t += sprintf(buf + t, "st->dmp_clk_n=%u\n", - st->dmp_clk_n); + t += snprintf(buf + t, PAGE_SIZE - t, + "nvi_dmp_clk_n=%u\n", n); + t += snprintf(buf + t, PAGE_SIZE - t, + "st->dmp_clk_n=%u\n", st->dmp_clk_n); n = SRC_DMP; } else { n = 0; @@ -3398,47 +3493,58 @@ static int nvi_nvs_read(void *client, int snsr_id, char *buf) if (i >= st->hal->src_n && i != SRC_DMP) continue; - t += sprintf(buf + t, "src[%u]:\n", i); - t += sprintf(buf + t, "ts_reset=%x\n", - st->src[i].ts_reset); - t += sprintf(buf + t, "ts_end=%lld\n", - st->src[i].ts_end); - t += sprintf(buf + t, "ts_period=%lld\n", - st->src[i].ts_period); - t += sprintf(buf + t, "period_us_src=%u\n", - st->src[i].period_us_src); - t += sprintf(buf + t, "period_us_req=%u\n", - st->src[i].period_us_req); - t += sprintf(buf + t, "fifo_data_n=%u\n", - st->src[i].fifo_data_n); - t += sprintf(buf + t, "base_t=%u\n", - st->src[i].base_t); + t += snprintf(buf + t, PAGE_SIZE - t, "src[%u]:\n", i); + t += snprintf(buf + t, PAGE_SIZE - t, "ts_reset=%x\n", + st->src[i].ts_reset); + t += snprintf(buf + t, PAGE_SIZE - t, "ts_end=%lld\n", + st->src[i].ts_end); + t += snprintf(buf + t, PAGE_SIZE - t, + "ts_period=%lld\n", + st->src[i].ts_period); + t += snprintf(buf + t, PAGE_SIZE - t, + "period_us_src=%u\n", + st->src[i].period_us_src); + t += snprintf(buf + t, PAGE_SIZE - t, + "period_us_req=%u\n", + st->src[i].period_us_req); + t += snprintf(buf + t, PAGE_SIZE - t, + "period_us_min=%u\n", + st->src[i].period_us_min); + t += snprintf(buf + t, PAGE_SIZE - t, + "period_us_max=%u\n", + st->src[i].period_us_max); + t += snprintf(buf + t, PAGE_SIZE - t, + "fifo_data_n=%u\n", + st->src[i].fifo_data_n); + t += snprintf(buf + t, PAGE_SIZE - t, "base_t=%u\n", + st->src[i].base_t); } return t; case NVI_INFO_DBG_SPEW: - return sprintf(buf, "DBG spew=%x\n", - !!(st->sts & NVI_DBG_SPEW_MSG)); + return snprintf(buf, PAGE_SIZE, "DBG spew=%x\n", + !!(st->sts & NVI_DBG_SPEW_MSG)); case NVI_INFO_AUX_SPEW: - return sprintf(buf, "AUX spew=%x\n", - !!(st->sts & NVI_DBG_SPEW_AUX)); + return snprintf(buf, PAGE_SIZE, "AUX spew=%x\n", + !!(st->sts & NVI_DBG_SPEW_AUX)); case NVI_INFO_FIFO_SPEW: - return sprintf(buf, "FIFO spew=%x\n", - !!(st->sts & NVI_DBG_SPEW_FIFO)); + return snprintf(buf, PAGE_SIZE, "FIFO spew=%x\n", + !!(st->sts & NVI_DBG_SPEW_FIFO)); case NVI_INFO_TS_SPEW: - return sprintf(buf, "TS spew=%x\n", - !!(st->sts & NVI_DBG_SPEW_TS)); + return snprintf(buf, PAGE_SIZE, "TS spew=%x\n", + !!(st->sts & NVI_DBG_SPEW_TS)); case NVI_INFO_REG_WR: st->rc_dis = true; buf_rw[0] = (u8)(info >> 16); buf_rw[1] = (u8)(info >> 8); ret = nvi_i2c_write(st, info >> 24, 2, buf_rw); - return sprintf(buf, "REG WR: b=%02x r=%02x d=%02x ERR=%d\n", - info >> 24, buf_rw[0], buf_rw[1], ret); + return snprintf(buf, PAGE_SIZE, + "REG WR: b=%02x r=%02x d=%02x ERR=%d\n", + info >> 24, buf_rw[0], buf_rw[1], ret); case NVI_INFO_MEM_RD: n = (info >> 8) & 0xFF; @@ -3446,40 +3552,54 @@ static int nvi_nvs_read(void *client, int snsr_id, char *buf) n = sizeof(buf_rw); ret = nvi_mem_rd(st, info >> 16, n, buf_rw); if (ret) - return sprintf(buf, "MEM RD: ERR=%d\n", ret); + return snprintf(buf, PAGE_SIZE, + "MEM RD: ERR=%d\n", ret); - t = sprintf(buf, "MEM RD:\n"); + t = snprintf(buf, PAGE_SIZE, "MEM RD:\n"); for (i = 0; i < n; i++) { if (!(i % 8)) - t += sprintf(buf + t, "%04x: ", - (info >> 16) + i); - t += sprintf(buf + t, "%02x ", buf_rw[i]); + t += snprintf(buf + t, PAGE_SIZE - t, "%04x: ", + (info >> 16) + i); + t += snprintf(buf + t, PAGE_SIZE - t, "%02x ", + buf_rw[i]); if (!((i + 1) % 8)) - t += sprintf(buf + t, "\n"); + t += snprintf(buf + t, PAGE_SIZE - t, "\n"); } - t += sprintf(buf + t, "\n"); + t += snprintf(buf + t, PAGE_SIZE - t, "\n"); return t; case NVI_INFO_MEM_WR: st->mc_dis = true; buf_rw[0] = (u8)(info >> 8); ret = nvi_mem_wr(st, info >> 16, 1, buf_rw, true); - return sprintf(buf, "MEM WR: a=%04x d=%02x ERR=%d\n", - info >> 16, buf_rw[0], ret); + return snprintf(buf, PAGE_SIZE, + "MEM WR: a=%04x d=%02x ERR=%d\n", + info >> 16, buf_rw[0], ret); case NVI_INFO_DMP_FW: ret = nvi_dmp_fw(st); - return sprintf(buf, "DMP FW: ERR=%d\n", ret); + return snprintf(buf, PAGE_SIZE, "DMP FW: ERR=%d\n", ret); case NVI_INFO_DMP_EN_MSK: st->dmp_en_msk = (info >> 8) & MSK_DEV_ALL; - return sprintf(buf, "st->dmp_en_msk=%x\n", st->dmp_en_msk); + return snprintf(buf, PAGE_SIZE, "st->dmp_en_msk=%x\n", + st->dmp_en_msk); + + case NVI_INFO_FN_INIT: + if (st->hal->fn->init) { + ret = st->hal->fn->init(st); + return snprintf(buf, PAGE_SIZE, + "hal->fn->init() ret=%d\n", ret); + } else { + return snprintf(buf, PAGE_SIZE, + "no hal->fn->init()\n"); + } default: i = info - NVI_INFO_SNSR_SPEW; if (i < DEV_N) - return sprintf(buf, "%s spew=%x\n", - st->snsr[i].cfg.name, + return snprintf(buf, PAGE_SIZE, "%s spew=%x\n", + st->snsr[i].cfg.name, !!(st->sts & (NVI_DBG_SPEW_SNSR << i))); break; } @@ -3891,9 +4011,10 @@ static int nvi_of_dt_pre(struct nvi_state *st, struct device_node *dn) } of_property_read_u32(dn, "bypass_timeout_ms", &st->bypass_timeout_ms); for (i = 0; i < DEV_N_AUX; i++) { - sprintf(str, "%s_push_delay_ns", st->snsr[i].cfg.name); - of_property_read_u32(dn, str, - (u32 *)&st->snsr[i].push_delay_ns); + snprintf(str, sizeof(str), "%s_push_delay_ns", + st->snsr[i].cfg.name); + if (!of_property_read_u32(dn, str, &tmp)) + st->snsr[i].push_delay_ns = (s64)tmp; } return 0; @@ -3918,7 +4039,8 @@ static void nvi_of_dt_post(struct nvi_state *st, struct device_node *dn) tmp |= st->snsr[i].cfg.matrix[j]; if (tmp) { /* sensor has a matrix */ - sprintf(str, "%s_matrix_enable", st->snsr[i].cfg.name); + snprintf(str, sizeof(str), "%s_matrix_enable", + st->snsr[i].cfg.name); if (!of_property_read_u32(dn, str, &tmp)) { /* matrix override */ if (tmp) @@ -3939,8 +4061,8 @@ static void nvi_of_dt_post(struct nvi_state *st, struct device_node *dn) st->dmp_dev_msk = st->hal->dmp->dev_msk; st->dmp_en_msk = st->hal->dmp->en_msk; for (i = 0; i < DEV_N_AUX; i++) { - sprintf(str, "%s_dmp_en", - st->snsr[i].cfg.name); + snprintf(str, sizeof(str), "%s_dmp_en", + st->snsr[i].cfg.name); if (!of_property_read_u32(dn, str, &tmp)) { if (tmp) { msk = 1 << i; @@ -4047,6 +4169,8 @@ static int nvi_init(struct nvi_state *st, } nvi_pm(st, __func__, NVI_PM_AUTO); + nvi_rc_clr(st, __func__); + st->rc_dis = false; /* enable register cache after initialization */ nvi_state_local = st; return 0; } @@ -4092,6 +4216,7 @@ static int nvi_probe(struct i2c_client *client, st = &pd->st; i2c_set_clientdata(client, pd); + st->rc_dis = true; /* disable register cache during initialization */ st->i2c = client; pd->i2c_dev_id = i2c_dev_id; /* Init fw load worker thread */ diff --git a/drivers/iio/imu/nvi_mpu/nvi.h b/drivers/iio/imu/nvi_mpu/nvi.h index a907f8d8ee4..4d6d6abf48c 100644 --- a/drivers/iio/imu/nvi_mpu/nvi.h +++ b/drivers/iio/imu/nvi_mpu/nvi.h @@ -96,6 +96,10 @@ #define NVI_DBG_SPEW_FIFO (1 << (NVS_STS_EXT_N + 2)) #define NVI_DBG_SPEW_TS (1 << (NVS_STS_EXT_N + 3)) #define NVI_DBG_SPEW_SNSR (1 << (NVS_STS_EXT_N + 4)) + +#define NVI_RC_BANK_REG_BANK (0x7F / 64) +#define NVI_RC_MSK_REG_BANK ((u64)(1ULL << (0x7F % 64))) + /* register bits */ #define BITS_SELF_TEST_EN (0xE0) #define BIT_ACCEL_FCHOCIE_B (0x08) @@ -174,6 +178,8 @@ struct nvi_src { s64 ts_period; unsigned int period_us_src; unsigned int period_us_req; + unsigned int period_us_min; + unsigned int period_us_max; unsigned int fifo_data_n; u32 base_t; }; @@ -289,6 +295,8 @@ struct nvi_mc_icm { u32 data_out_ctl; u32 data_intr_ctl; u32 motion_event_ctl; + u32 acc_scale; + u32 acc_scale2; u32 accel_cal_rate; u32 ped_rate; u32 accel_alpha_var; @@ -304,6 +312,7 @@ struct nvi_mc_icm { u32 smd_delay2_thld; u32 smd_timer_thld; u32 wom_enable; + u32 wtf_8a; }; struct nvi_mc_mpu { @@ -328,6 +337,7 @@ struct nvi_dmp { unsigned int fw_mem_addr; unsigned int fw_start; unsigned int dmp_reset_delay_ms; + int fifo_mode; unsigned int dev_msk; unsigned int en_msk; unsigned int dd_n; @@ -341,7 +351,6 @@ struct nvi_dmp { }; struct nvi_fn { - void (*por2rc)(struct nvi_state *st); int (*pm)(struct nvi_state *st, u8 pm1, u8 pm2, u8 lp); int (*init)(struct nvi_state *st); int (*st_acc)(struct nvi_state *st); @@ -453,6 +462,7 @@ struct nvi_state { struct nvi_snsr snsr[DEV_N_AUX]; struct nvi_src src[SRC_N]; int fifo_src; + u64 rc_msk[8]; bool rc_dis; bool mc_dis; bool irq_dis; diff --git a/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.c b/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.c index 85da5457f57..b7684f931c9 100644 --- a/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.c +++ b/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.c @@ -11,6 +11,7 @@ */ #include +#include #include "nvi.h" #include "nvi_dmp_icm.h" @@ -18,6 +19,13 @@ (1 << DEV_QTN) | \ (1 << DEV_GMR) | \ (1 << DEV_GYU)) +#define AUX_PORT_DEV_GMF (0) +#define MSK_AUX_PORTS_DEV_GMF (0x3) +#define AUX_PORT_DEV_PRS (3) +#define MSK_AUX_PORTS_DEV_PRS (0x8) +#define MSK_EN_AUX_PORTS (((1 << (AUX_PORT_IO + DEV_N_AUX)) - \ + 1) & ~MSK_DEV_SNSR) + #define DEFAULT_ACCEL_GAIN (0x02000000) #define PED_ACCEL_GAIN (0x04000000) #define DMP_ACC_PERIOD_US_PED (19608) @@ -27,7 +35,6 @@ #define DMP_HDR1_HDR2_MSK (0x0008) #define DMP_HDR1_PUSH_MSK (0xFEF0) #define DMP_DATA_OUT_CTL_HDR2_MSK (0x0000FFFF) -#define DMP_DATA_OUT_CTL_HDR2_BIT (0x00080000) struct nvi_dmp_dev { @@ -38,12 +45,14 @@ struct nvi_dmp_dev { unsigned int period_us_dflt; unsigned int buf_n; int buf_shft; - u32 out_ctl; - u16 int_ctl; + u32 int_ctl; u16 odr_cfg; u16 odr_cntr; - int (*fn_init)(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl); + unsigned int odr_src; + int (*fn_init)(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk); + int (*fn_initd)(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk); }; struct nvi_dmp_hdr { @@ -54,6 +63,64 @@ struct nvi_dmp_hdr { }; +struct inv_dmp_acc_scale { + u32 scale; + u32 scale2; +}; + +/* input param: fsr for accel parts + * 1: 1g. 2: 2g. 4: 4g. 8: 8g. 16: 16g. 32: 32g. + * The goal is to set 1g data to 2^25, 2g data to 2^26, etc. + * For 2g parts, raw accel data is 1g = 2^14, 2g = 2^15. + * DMP takes raw accel data and shifts by 16 bits, so this scale means to shift + * by -5 bits. + * In Q-30 math, >> 5 equals multiply by 2^25 = 33554432. + * For 8g parts, raw accel data is 4g = 2^14, 8g = 2^15. + * DMP takes raw accel data and shifts by 16 bits, so this scale means to shift + * by -3 bits. + * In Q-30 math, >> 3 equals multiply by 2^27 = 134217728. + */ +static struct inv_dmp_acc_scale inv_dmp_acc_scales[] = { + { + .scale = 0x02000000, + .scale2 = 0x00080000, + }, + { + .scale = 0x04000000, + .scale2 = 0x00040000, + }, + { + .scale = 0x08000000, + .scale2 = 0x00020000, + }, + { + .scale = 0x10000000, + .scale2 = 0x00010000, + }, +}; + +static int nvi_dmp_acc_init(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) +{ + int ret = 0; +#if ICM_DMP_FW_VER == 2 + unsigned int i; + + i = st->snsr[DEV_ACC].usr_cfg; + ret |= nvi_mem_wr_be_mc(st, ACC_SCALE, 4, + inv_dmp_acc_scales[i].scale, + &st->mc.icm.acc_scale); + ret |= nvi_mem_wr_be_mc(st, ACC_SCALE2, 4, + inv_dmp_acc_scales[i].scale2, + &st->mc.icm.acc_scale2); +#endif /* ICM_DMP_FW_VER */ + ret |= st->hal->fn->en_acc(st); + if (irq_msk & (1 << DEV_ACC) || en_msk & ((1 << DEV_QTN) | + (1 << DEV_GMR))) + *out_ctl |= ACCEL_ACCURACY_SET; + return ret; +} + struct inv_dmp_acc_wtf { unsigned int period_us; unsigned int rate; @@ -100,8 +167,8 @@ static struct inv_dmp_acc_wtf inv_dmp_acc_wtfs[] = { }, }; -static int nvi_dmp_acc_init(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl) +static int nvi_dmp_acc_initd(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { unsigned int min_diff = -1; unsigned int tmp; @@ -109,7 +176,6 @@ static int nvi_dmp_acc_init(struct nvi_state *st, unsigned int en_msk, unsigned int j; int ret; - ret = st->hal->fn->en_acc(st); i = ARRAY_SIZE(inv_dmp_acc_wtfs) - 1; if (st->src[SRC_ACC].period_us_src > inv_dmp_acc_wtfs[i].period_us) { /* i = ARRAY_SIZE(inv_dmp_acc_wtfs) - 1 */ @@ -127,9 +193,8 @@ static int nvi_dmp_acc_init(struct nvi_state *st, unsigned int en_msk, } } - ret |= nvi_mem_wr_be_mc(st, ACCEL_CAL_RATE, 2, - inv_dmp_acc_wtfs[i].rate, - &st->mc.icm.accel_cal_rate); + ret = nvi_mem_wr_be_mc(st, ACCEL_CAL_RATE, 2, inv_dmp_acc_wtfs[i].rate, + &st->mc.icm.accel_cal_rate); ret |= nvi_mem_wr_be_mc(st, PED_RATE, 4, inv_dmp_acc_wtfs[i].rate, &st->mc.icm.ped_rate); ret |= nvi_mem_wr_be_mc(st, ACCEL_ALPHA_VAR, 4, @@ -143,6 +208,27 @@ static int nvi_dmp_acc_init(struct nvi_state *st, unsigned int en_msk, return ret; } +/* gmf = GeoMagnetic Field (compass) */ +static int nvi_dmp_gmf_init(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) +{ + if (st->aux.port[AUX_PORT_DEV_GMF].nmp.type != + SECONDARY_SLAVE_TYPE_COMPASS) + /* disable without error if no compass */ + return 1; + + if (!st->aux.port[AUX_PORT_DEV_GMF].nmp.handler) + /* no handler */ + return 1; + + st->src[SRC_AUX].period_us_max = + st->hal->src[SRC_AUX].period_us_min * 8; + if (irq_msk & (1 << (AUX_PORT_DEV_GMF + DEV_N_AUX)) || + en_msk & (1 << DEV_GMR)) + *out_ctl |= CPASS_ACCURACY_SET; + return 0; +} + struct inv_dmp_gmf_wtf { unsigned int period_us; unsigned int ct; @@ -196,8 +282,8 @@ static struct inv_dmp_gmf_wtf inv_dmp_gmf_wtfs[] = { }; /* gmf = GeoMagnetic Field (compass) */ -static int nvi_dmp_gmf_init(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl) +static int nvi_dmp_gmf_initd(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { unsigned int min_diff = -1; unsigned int tmp; @@ -205,10 +291,6 @@ static int nvi_dmp_gmf_init(struct nvi_state *st, unsigned int en_msk, unsigned int j; int ret; - if (st->aux.port[0].nmp.type != SECONDARY_SLAVE_TYPE_COMPASS) - /* DMP shouldn't run if AUX device not supported */ - return -EINVAL; - i = ARRAY_SIZE(inv_dmp_gmf_wtfs) - 1; if (st->src[SRC_AUX].period_us_src > inv_dmp_gmf_wtfs[i].period_us) { /* i = ARRAY_SIZE(inv_dmp_gmf_wtfs) - 1 */ @@ -229,38 +311,48 @@ static int nvi_dmp_gmf_init(struct nvi_state *st, unsigned int en_msk, ret = nvi_mem_wr_be_mc(st, CPASS_TIME_BUFFER, 2, inv_dmp_gmf_wtfs[i].ct, &st->mc.icm.cpass_time_buffer); + ret |= nvi_mem_wr_be_mc(st, + CPASS_RADIUS_3D_THRESH_ANOMALY, 4, + inv_dmp_gmf_wtfs[i].rad_3d, + &st->mc.icm.cpass_rad_3d_thr); +#if ICM_DMP_FW_VER == 0 ret |= nvi_mem_wr_be_mc(st, CPASS_ALPHA_VAR, 4, inv_dmp_gmf_wtfs[i].alpha_c, &st->mc.icm.cpass_alpha_var); ret |= nvi_mem_wr_be_mc(st, CPASS_A_VAR, 4, inv_dmp_gmf_wtfs[i].a_c, &st->mc.icm.cpass_a_var); - ret |= nvi_mem_wr_be_mc(st, - CPASS_RADIUS_3D_THRESH_ANOMALY, 4, - inv_dmp_gmf_wtfs[i].rad_3d, - &st->mc.icm.cpass_rad_3d_thr); ret |= nvi_mem_wr_be_mc(st, CPASS_NOMOT_VAR_THRESH, 4, inv_dmp_gmf_wtfs[i].nomot_var_thr, &st->mc.icm.cpass_nomot_var_thr); +#endif /* ICM_DMP_FW_VER */ return ret; } /* prs = pressure */ -static int nvi_dmp_prs_init(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl) +static int nvi_dmp_prs_init(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { - return 1; + if (st->aux.port[AUX_PORT_DEV_PRS].nmp.type != + SECONDARY_SLAVE_TYPE_PRESSURE) + /* disable without error if no pressure */ + return 1; + + return 0; } -static int nvi_dmp_gyr_init(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl) +static int nvi_dmp_gyr_init(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { + if (irq_msk & (1 << DEV_GYR) || en_msk & ((1 << DEV_QTN) | + (1 << DEV_GMR))) + *out_ctl |= GYRO_ACCURACY_SET; st->snsr[DEV_GYR].sts = 1; return st->hal->fn->en_gyr(st); } -static int nvi_dmp_sm_init(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl) +static int nvi_dmp_sm_init(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { #if ICM_DMP_FW_VER == 0 int ret; @@ -275,71 +367,79 @@ static int nvi_dmp_sm_init(struct nvi_state *st, unsigned int en_msk, st->snsr[DEV_SM].cfg.delay_us_max, &st->mc.icm.smd_delay2_thld); return ret; -#else /* ICM_DMP_FW_VER */ - /* ICM_DMP_FW_VER == 1 */ +#elif ICM_DMP_FW_VER == 1 return nvi_mem_wr_be_mc(st, SMD_TIMER_THLD, 4, st->snsr[DEV_SM].cfg.thresh_hi, &st->mc.icm.smd_timer_thld); +#elif ICM_DMP_FW_VER == 2 + return nvi_mem_wr_be_mc(st, SMD_CNTR_TH, 4, + st->snsr[DEV_SM].cfg.thresh_hi, + &st->mc.icm.smd_timer_thld); +#else + return 0; #endif /* ICM_DMP_FW_VER */ } -static int nvi_dmp_gmr_init(struct nvi_state *st, unsigned int en_msk, - u32 *out_ctl) +static int nvi_dmp_gmr_init(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { - if (out_ctl) { - if (en_msk & ((1 << DEV_GYR) | (1 << DEV_GYU))) - /* if gyro is enabled GMR becomes QTN 9-axis */ - *out_ctl |= 0x04000000; - else - *out_ctl |= 0x04000200; - } + if (en_msk & ((1 << DEV_GYR) | (1 << DEV_GYU))) + /* if gyro is enabled GMR becomes QTN 9-axis */ + st->src[SRC_AUX].period_us_min = + st->hal->src[SRC_AUX].period_us_min * 2; + else + /* gyro not enabled so GMR enabled */ + *out_ctl |= GEOMAG_EN; return 0; } static struct nvi_dmp_dev nvi_dmp_devs[] = { { .dev = DEV_ACC, +#if ICM_DMP_FW_VER == 2 + .buf_n = 6, + .buf_shft = 0, +#else /* ICM_DMP_FW_VER < 2 */ .buf_n = 12, .buf_shft = -11, - .out_ctl = 0x80004000, +#endif /* ICM_DMP_FW_VER */ .int_ctl = ACCEL_SET, .odr_cfg = ODR_ACCEL, .odr_cntr = ODR_CNTR_ACCEL, + .odr_src = SRC_ACC, .fn_init = &nvi_dmp_acc_init, + .fn_initd = &nvi_dmp_acc_initd, }, { .dev = DEV_GYR, - .depend_msk = (1 << DEV_GYU), .buf_n = 12, - .out_ctl = 0x00402000, .int_ctl = GYRO_CALIBR_SET, .odr_cfg = ODR_GYRO_CALIBR, .odr_cntr = ODR_CNTR_GYRO_CALIBR, + .odr_src = SRC_GYR, .fn_init = &nvi_dmp_gyr_init, }, { .dev = DEV_GYU, .depend_msk = (1 << DEV_GYR), .buf_n = 6, - .out_ctl = 0x40000000, .int_ctl = GYRO_SET, .odr_cfg = ODR_GYRO, .odr_cntr = ODR_CNTR_GYRO, + .odr_src = SRC_GYR, }, { .dev = DEV_QTN, .depend_msk = (1 << DEV_ACC) | - (1 << DEV_GYR) | - (1 << DEV_GYU), + (1 << DEV_GYR), .src_msk = (1 << SRC_ACC) | - (1 << SRC_GYR) | - (1 << SRC_AUX), + (1 << SRC_GYR), .period_us_dflt = ICM_DMP_PERIOD_US, .buf_n = 12, - .out_ctl = 0x08000000, .int_ctl = QUAT6_SET, .odr_cfg = ODR_QUAT6, .odr_cntr = ODR_CNTR_QUAT6, + .odr_src = SRC_GYR, }, { .dev = DEV_GMR, @@ -353,6 +453,7 @@ static struct nvi_dmp_dev nvi_dmp_devs[] = { .int_ctl = QUAT9_SET, .odr_cfg = ODR_QUAT9, .odr_cntr = ODR_CNTR_QUAT9, + .odr_src = SRC_ACC, .fn_init = &nvi_dmp_gmr_init, }, { @@ -365,24 +466,24 @@ static struct nvi_dmp_dev nvi_dmp_devs[] = { }, { .dev = DEV_AUX, - .aux_port = 0, - .depend_msk = (0x03 << DEV_N_AUX), + .aux_port = AUX_PORT_DEV_GMF, + .depend_msk = (MSK_AUX_PORTS_DEV_GMF << DEV_N_AUX), .buf_n = 6, - .out_ctl = 0x20001000, .int_ctl = CPASS_SET, .odr_cfg = ODR_CPASS, .odr_cntr = ODR_CNTR_CPASS, + .odr_src = SRC_AUX, .fn_init = &nvi_dmp_gmf_init, + .fn_initd = &nvi_dmp_gmf_initd, }, { .dev = DEV_AUX, - .aux_port = 2, - .depend_msk = (0x0C << DEV_N_AUX), + .aux_port = AUX_PORT_DEV_PRS, .buf_n = 6, - .out_ctl = 0x00800000, .int_ctl = PRESSURE_SET, .odr_cfg = ODR_PRESSURE, .odr_cntr = ODR_CNTR_PRESSURE, + .odr_src = SRC_AUX, .fn_init = &nvi_dmp_prs_init, }, }; @@ -392,23 +493,23 @@ static struct nvi_dmp_hdr nvi_dmp_hdr2s[] = { { .dev = DEV_ACC, .data_n = 2, - .hdr_msk = 0x4000, + .hdr_msk = ACCEL_ACCURACY_SET, }, { .dev = DEV_GYR, .data_n = 2, - .hdr_msk = 0x2000, + .hdr_msk = GYRO_ACCURACY_SET, }, { .dev = DEV_AUX, - .aux_port = 0, + .aux_port = AUX_PORT_DEV_GMF, .data_n = 2, - .hdr_msk = 0x1000, + .hdr_msk = CPASS_ACCURACY_SET, }, { - .dev = -1, + .dev = -1, /* WTF */ .data_n = 6, - .hdr_msk = 0x0080, + .hdr_msk = ACT_RECOG_SET, }, }; @@ -416,61 +517,65 @@ static struct nvi_dmp_hdr nvi_dmp_hdr2s[] = { static struct nvi_dmp_hdr nvi_dmp_hdr1s[] = { { .dev = DEV_ACC, +#if ICM_DMP_FW_VER == 2 + .data_n = 6, +#else /* ICM_DMP_FW_VER < 2 */ .data_n = 12, - .hdr_msk = 0x8000, +#endif /* ICM_DMP_FW_VER */ + .hdr_msk = ACCEL_SET, }, { .dev = DEV_GYU, .data_n = 6, - .hdr_msk = 0x4000, + .hdr_msk = GYRO_SET, }, { .dev = DEV_AUX, - .aux_port = 0, + .aux_port = AUX_PORT_DEV_GMF, .data_n = 6, - .hdr_msk = 0x2000, + .hdr_msk = CPASS_SET, }, { .dev = DEV_AUX, - .aux_port = -1, + .aux_port = -1, /* ALS */ .data_n = 8, - .hdr_msk = 0x1000, + .hdr_msk = ALS_SET, }, { .dev = DEV_QTN, .data_n = 12, - .hdr_msk = 0x0800, + .hdr_msk = QUAT6_SET, }, { .dev = DEV_GMR, .data_n = 14, - .hdr_msk = 0x0400, + .hdr_msk = QUAT9_SET, }, { .dev = -1, /* PQUAT6 */ .data_n = 6, - .hdr_msk = 0x0200, + .hdr_msk = PQUAT6_SET, }, { .dev = DEV_AUX, - .aux_port = 2, + .aux_port = AUX_PORT_DEV_PRS, .data_n = 6, - .hdr_msk = 0x0080, + .hdr_msk = PRESSURE_SET, }, { .dev = DEV_GYR, .data_n = 12, - .hdr_msk = 0x0040, + .hdr_msk = GYRO_CALIBR_SET, }, { .dev = -1, /* CPASS_CALIBR */ .data_n = 12, - .hdr_msk = 0x0020, + .hdr_msk = CPASS_CALIBR_SET, }, { .dev = DEV_STP, .data_n = 4, - .hdr_msk = 0x0010, + .hdr_msk = PED_STEPDET_SET, }, }; @@ -652,30 +757,62 @@ static int nvi_dmp_clk_n(struct nvi_state *st, u32 *clk_n) return nvi_mem_rd_le(st, DMPRATE_CNTR, 4, clk_n); } -static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) +static unsigned int nvi_dmp_gmf_us_periods[] = { + 200000, + 166667, + 142857, + 125000, + 111111, + 100000, + 90909, + 83333, + 76923, + 71429, + 66667, + 58824, + 55556, + 45455, + 40000, + 35714, + 31250, + 27027, + 22222, + 19608, + 13333, + 9804, + 4444, +}; + +static int nvi_dmp_period(struct nvi_state *st, u32 *out_ctl, + unsigned int en_msk, unsigned int irq_msk) { struct nvi_dmp_dev *dd; - u16 int_ctl = 0; + u32 int_ctl; u16 odr_cfg; unsigned int period_us_req[SRC_N]; unsigned int period_us; - unsigned int period_us_int = -1; + unsigned int period_us_int; + unsigned int dev_msk; unsigned int src_msk; unsigned int src; unsigned int i; - unsigned int j = -1; + unsigned int j; int ret; int ret_t = 0; + /* sensor enabled = sensor enabled by HAL (irq_msk) + * sensor active = sensor on as dependency to another sensor + */ /* initialize source period */ for (src = 0; src < st->hal->src_n; src++) period_us_req[src] = st->hal->src[src].period_us_max; - /* set source's period_us_req[] to fastest DMP device */ + /* set source's period_us_req[] to fastest enabled sensor */ for (i = 0; i < ARRAY_SIZE(nvi_dmp_devs); i++) { dd = &nvi_dmp_devs[i]; - if ((!st->snsr[dd->dev].period_us) || !(en_msk & + if ((!st->snsr[dd->dev].period_us) || !(irq_msk & (1 << dd->dev))) + /* sensor not enabled or non-valid period */ continue; src_msk = dd->src_msk; /* use all of device's sources */ @@ -683,27 +820,18 @@ static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) src_msk |= (1 << st->hal->dev[dd->dev]->src); for (src = 0; src < st->hal->src_n; src++) { if (!(src_msk & (1 << src))) + /* sensor doesn't use this source */ continue; if (st->snsr[dd->dev].period_us < period_us_req[src]) period_us_req[src] = st->snsr[dd->dev].period_us; - } - } - - /* override above fastest speeds with any faster defaults */ - for (i = 0; i < ARRAY_SIZE(nvi_dmp_devs); i++) { - dd = &nvi_dmp_devs[i]; - if ((!dd->period_us_dflt) || !(en_msk & (1 << dd->dev))) - continue; - - src_msk = dd->src_msk; /* use all of device's sources */ - if (st->hal->dev[dd->dev]->src >= 0) - src_msk |= (1 << st->hal->dev[dd->dev]->src); - for (src = 0; src < st->hal->src_n; src++) { - if (src_msk & (1 << src) && (dd->period_us_dflt < - period_us_req[src])) - period_us_req[src] = dd->period_us_dflt; + /* override above speeds with any faster defaults */ + if (dd->period_us_dflt) { + if (dd->period_us_dflt < period_us_req[src]) + period_us_req[src] = + dd->period_us_dflt; + } } } @@ -711,24 +839,42 @@ static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) * SRC_AUX has timestamps set to ts_now = 0 since SRC_AUX has fixed * rates and can't sync with the other sources. */ - period_us = -1; - for (src = 0; src < st->hal->src_n; src++) { - if (period_us_req[src] < period_us) - period_us = period_us_req[src]; + period_us = min(period_us_req[SRC_GYR], period_us_req[SRC_ACC]); + /* The latest INV driver implements this WAR with a twist: the gmf + * lookup table, nvi_dmp_gmf_us_periods. + */ + if (en_msk & (1 << (DEV_N_AUX + AUX_PORT_DEV_GMF))) { + /* compass is enabled */ + if (period_us_req[SRC_AUX] <= period_us) { + j = ARRAY_SIZE(nvi_dmp_gmf_us_periods) - 1; + for (i = 0; i < j; i++) { + if (period_us_req[SRC_AUX] >= + nvi_dmp_gmf_us_periods[i]) + break; + } + period_us = nvi_dmp_gmf_us_periods[i]; + } + + period_us_req[SRC_AUX] = period_us; } - for (src = 0; src < st->hal->src_n; src++) - period_us_req[src] = period_us; + + period_us_req[SRC_GYR] = period_us; + period_us_req[SRC_ACC] = period_us; /* WAR: end */ /* program the sources */ for (src = 0; src < st->hal->src_n; src++) { - if (!(st->hal->src[src].dev_msk & en_msk)) + dev_msk = st->hal->src[src].dev_msk; + if (dev_msk & (1 << DEV_AUX)) + dev_msk |= MSK_EN_AUX_PORTS; + if (!(dev_msk & en_msk)) + /* no active sensors use this source */ continue; - if (period_us_req[src] < st->hal->src[src].period_us_min) - period_us_req[src] = st->hal->src[src].period_us_min; - if (period_us_req[src] > st->hal->src[src].period_us_max) - period_us_req[src] = st->hal->src[src].period_us_max; + if (period_us_req[src] < st->src[src].period_us_min) + period_us_req[src] = st->src[src].period_us_min; + if (period_us_req[src] > st->src[src].period_us_max) + period_us_req[src] = st->src[src].period_us_max; st->src[src].period_us_req = period_us_req[src]; switch (src) { case SRC_GYR: @@ -737,6 +883,10 @@ static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) st->src[src].base_t; if (i) i--; +/* WAR: start + * It appears that the latest INV ICM DMP FW runs everything off of the SRC_GYR + */ +#if 0 /* WAR: must program both SRC_ACC & SRC_GYR regardless if used*/ ret = nvi_i2c_write_rc(st, &st->hal->reg->smplrt[src], i, __func__, (u8 *)&st->rc.smplrt[src], true); @@ -745,6 +895,26 @@ static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) else st->src[src].period_us_src = ((i + 1) * st->src[src].base_t) / 1000; +#endif /* WAR */ + ret = nvi_i2c_write_rc(st, + &st->hal->reg->smplrt[SRC_GYR], + i, __func__, + (u8 *)&st->rc.smplrt[SRC_GYR], true); + if (ret) + ret_t |= ret; + else + st->src[SRC_GYR].period_us_src = ((i + 1) * + st->src[SRC_GYR].base_t) / 1000; + ret = nvi_i2c_write_rc(st, + &st->hal->reg->smplrt[SRC_ACC], + i, __func__, + (u8 *)&st->rc.smplrt[SRC_ACC], true); + if (ret) + ret_t |= ret; + else + st->src[SRC_ACC].period_us_src = ((i + 1) * + st->src[SRC_ACC].base_t) / 1000; +/* WAR: end */ break; case SRC_AUX: @@ -753,43 +923,54 @@ static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) } } - /* now set each DMP device's ODR based on their source */ + /* now set each DMP device's ODR based on their period */ + int_ctl = 0; + period_us_int = -1; + j = -1; for (i = 0; i < ARRAY_SIZE(nvi_dmp_devs); i++) { dd = &nvi_dmp_devs[i]; - if (dd->dev >= DEV_N_AUX || !(dd->odr_cfg | dd->odr_cntr)) - /* dd (DMP Device) is not ODR configurable */ + if (!(en_msk & (1 << dd->dev))) + /* device disabled */ continue; - if (!(en_msk & (1 << dd->dev))) + if (dd->fn_initd) + /* settings after src initialized (initd) */ + ret |= dd->fn_initd(st, out_ctl, en_msk, irq_msk); + if (dd->dev >= DEV_N_AUX || !(dd->odr_cfg | dd->odr_cntr)) + /* dd (DMP Device) is not ODR configurable */ continue; if (dd->dev == DEV_AUX) { if (!(en_msk & (1 << (dd->aux_port + DEV_N_AUX)))) + /* AUX sensor not enabled */ continue; period_us = st->aux.port[dd->aux_port].period_us; } else { period_us = st->snsr[dd->dev].period_us; } + if (st->bm_timeout_us) { /* batch mode on */ int_ctl |= dd->int_ctl; } else { - if (dd->int_ctl && period_us) { - /* IRQ on fastest period */ + if (*out_ctl & (dd->int_ctl << 16) && period_us) { + /* IRQ on fastest period with data out */ if (period_us < period_us_int) { period_us_int = period_us; j = i; } } } - src = st->hal->dev[dd->dev]->src; - if (src < st->hal->src_n) { - odr_cfg = period_us / st->src[src].period_us_src; + if (irq_msk & (1 << dd->dev)) { + /* ODR rate for sent sensor data */ + odr_cfg = period_us / + st->src[dd->odr_src].period_us_src; if (odr_cfg) odr_cfg--; } else { - odr_cfg = -1; + /* data is not sent so timing is synced to src */ + odr_cfg = 0; } if (dd->dev == DEV_AUX) st->aux.port[dd->aux_port].odr = odr_cfg; @@ -800,9 +981,9 @@ static int nvi_dmp_period(struct nvi_state *st, unsigned int en_msk) ret_t |= nvi_mem_wr_be(st, dd->odr_cntr, 2, 0); } - if (j != -1) + if (j < ARRAY_SIZE(nvi_dmp_devs)) int_ctl |= nvi_dmp_devs[j].int_ctl; - if (en_msk & (1 << DEV_STP)) + if (irq_msk & (1 << DEV_STP)) int_ctl |= PED_STEPDET_SET; ret_t |= nvi_mem_wr_be_mc(st, DATA_INTR_CTL, 2, int_ctl, &st->mc.icm.data_intr_ctl); @@ -848,15 +1029,19 @@ static struct nvi_dmp_dev *nvi_dd(struct nvi_state *st, static int nvi_dd_init(struct nvi_state *st, unsigned int dev) { struct nvi_dmp_dev *dd; + unsigned int en_msk; int ret = -EINVAL; + u32 out_ctl = 0; dd = nvi_dd(st, dev, -1); if (dd == NULL) return -EINVAL; - if (dd->fn_init) - ret = dd->fn_init(st, st->en_msk | (st->aux.dmp_en_msk << - DEV_N_AUX), NULL); + if (dd->fn_init) { + en_msk = st->en_msk & MSK_DEV_ALL; + en_msk |= (st->aux.dmp_en_msk << DEV_N_AUX); + ret = dd->fn_init(st, &out_ctl, en_msk, 0); + } return ret; } @@ -893,10 +1078,11 @@ static int nvi_dmp_init_gmf(struct nvi_state *st) unsigned int j; unsigned int k; - if (st->aux.port[0].nmp.type != SECONDARY_SLAVE_TYPE_COMPASS) + if (st->aux.port[AUX_PORT_DEV_GMF].nmp.type != + SECONDARY_SLAVE_TYPE_COMPASS) return -EINVAL; - nmp = &st->aux.port[0].nmp; + nmp = &st->aux.port[AUX_PORT_DEV_GMF].nmp; for (i = 0; i < AXIS_N; i++) { for (j = 0; j < AXIS_N; j++) mtrx[AXIS_N * j + i] = @@ -970,7 +1156,10 @@ static int nvi_dmp_init(struct nvi_state *st) static int nvi_dd_able(struct nvi_state *st, unsigned int en_msk, unsigned int irq_msk) { - u16 evnt_ctl = 0; +#if ICM_DMP_FW_VER == 2 + u32 wtf_8a = 0; +#endif /* ICM_DMP_FW_VER == 2 */ + u32 evnt_ctl = 0; u32 out_ctl = 0; struct nvi_dmp_dev *dd; bool en; @@ -978,9 +1167,10 @@ static int nvi_dd_able(struct nvi_state *st, int ret; st->en_msk &= ~MSK_DEV_SNSR; - ret = nvi_dmp_period(st, en_msk); - if (ret) - return ret; + for (i = 0; i < st->hal->src_n; i++) { + st->src[i].period_us_min = st->hal->src[i].period_us_min; + st->src[i].period_us_max = st->hal->src[i].period_us_max; + } for (i = 0; i < ARRAY_SIZE(nvi_dmp_devs); i++) { dd = &nvi_dmp_devs[i]; @@ -997,7 +1187,8 @@ static int nvi_dd_able(struct nvi_state *st, } if (en) { if (dd->fn_init) { - ret = dd->fn_init(st, en_msk, &out_ctl); + ret = dd->fn_init(st, &out_ctl, + en_msk, irq_msk); if (ret < 0) return ret; @@ -1008,8 +1199,8 @@ static int nvi_dd_able(struct nvi_state *st, } if (en) { - if (dd->out_ctl && (irq_msk & (1 << dd->dev))) - out_ctl |= dd->out_ctl; + if (dd->int_ctl && (irq_msk & (1 << dd->dev))) + out_ctl |= (dd->int_ctl << 16); st->snsr[dd->dev].buf_n = dd->buf_n; st->snsr[dd->dev].buf_shft = dd->buf_shft; } else { @@ -1021,6 +1212,12 @@ static int nvi_dd_able(struct nvi_state *st, } st->aux.dmp_en_msk = en_msk >> DEV_N_AUX; + /* WAR: run all timestamp/IRQ timing off SRC_ACC (always on) */ + en_msk |= (1 << DEV_ACC); + ret = nvi_dmp_period(st, &out_ctl, en_msk, irq_msk); + if (ret) + return ret; + if (st->aux.dmp_en_msk) { ret = nvi_aux_enable(st, __func__, true, true); if (ret) @@ -1029,21 +1226,23 @@ static int nvi_dd_able(struct nvi_state *st, if (out_ctl & DMP_DATA_OUT_CTL_HDR2_MSK) /* header 2 needs to be enabled */ - out_ctl |= DMP_DATA_OUT_CTL_HDR2_BIT; + out_ctl |= (HEADER2_SET << 16); ret = nvi_mem_wr_be_mc(st, DATA_OUT_CTL1, 4, out_ctl, &st->mc.icm.data_out_ctl); if (ret) return ret; /* inv_enable_accel_cal_V3 */ - /* inv_enable_gyro_cal_V3 */ if (en_msk & (1 << DEV_ACC)) - evnt_ctl |= (ACCEL_CAL_EN | GYRO_CAL_EN); + evnt_ctl |= ACCEL_CAL_EN; + /* inv_enable_gyro_cal_V3 */ + if (en_msk & (1 << DEV_GYR)) + evnt_ctl |= GYRO_CAL_EN; /* inv_enable_compass_cal_V3 */ - if (en_msk & (0x03 << DEV_N_AUX)) + if (en_msk & (1 << (DEV_N_AUX + AUX_PORT_DEV_GMF))) evnt_ctl |= COMPASS_CAL_EN; /* inv_enable_9axes_V3 */ - if (out_ctl & CPASS_ACCURACY_MASK || en_msk & (1 << DEV_GMR)) + if (out_ctl & CPASS_ACCURACY_SET || en_msk & (1 << DEV_GMR)) evnt_ctl |= NINE_AXIS_EN; /* inv_setup_events */ if (en_msk & (1 << DEV_STP)) @@ -1055,7 +1254,17 @@ static int nvi_dd_able(struct nvi_state *st, /* SMD_EN is self-clearing so we don't want it in the cache */ st->mc.icm.motion_event_ctl &= ~SMD_EN; /* inv_set_wom */ - ret |= nvi_dmp_irq(st, irq_msk & en_msk); + ret |= nvi_dmp_irq(st, irq_msk); +#if ICM_DMP_FW_VER == 2 + if (en_msk & (1 << DEV_ACC)) + wtf_8a |= 0x02; + if (en_msk & (1 << DEV_GYR)) + wtf_8a |= 0x01; + if (en_msk & MSK_EN_AUX_PORTS) + wtf_8a |= 0x08; + ret |= nvi_mem_wr_be_mc(st, 0x8A, 2, wtf_8a, + &st->mc.icm.wtf_8a); +#endif /* ICM_DMP_FW_VER == 2 */ if (!ret) st->en_msk |= (en_msk & ((1 << DEV_N_AUX) - 1)); return ret; @@ -1074,6 +1283,7 @@ static int nvi_dmp_en(struct nvi_state *st) if (dd->dev == DEV_AUX) { if (st->snsr[DEV_AUX].enable & (1 << dd->aux_port)) { irq_msk |= (1 << DEV_AUX); + irq_msk |= (1 << (dd->aux_port + DEV_N_AUX)); en_msk |= (1 << DEV_AUX); en_msk |= (1 << (dd->aux_port + DEV_N_AUX)); en_msk |= dd->depend_msk; @@ -1089,7 +1299,9 @@ static int nvi_dmp_en(struct nvi_state *st) if (!st->icm_dmp_war) { st->icm_dmp_war = true; + st->mc_dis = true; /* initialize cache */ ret = nvi_dd_able(st, ICM_DMP_DEV_MSK | MSK_DEV_MPU, irq_msk); + st->mc_dis = false; /* enable cache */ } ret |= nvi_dd_able(st, en_msk, irq_msk); if (!ret) { @@ -2009,8 +2221,7 @@ static const u8 const dmp_fw_20628[] = { 0xCA, 0xF2, 0x35, 0xF1, 0x96, 0x8F, 0xA6, 0xD9, 0x00, 0xD8, 0xF1, 0xFF }; -#else /* ICM_DMP_FW_VER */ -/* ICM_DMP_FW_VER == 1 */ +#elif ICM_DMP_FW_VER == 1 static const u8 const dmp_fw_20628[] = { /* bank 0: 0x0090 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2920,6 +3131,916 @@ static const u8 const dmp_fw_20628[] = { 0xF1, 0xCA, 0xF2, 0x35, 0xF1, 0x96, 0x8F, 0xA6, 0xD9, 0x00, 0xD8, 0xF1, 0xFF }; +#else /* ICM_DMP_FW_VER == 2 */ +static const u8 const dmp_fw_20628[] = { + /* bank 0: 0x0090 */ + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0xFF, + 0xFF, 0xF7, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, + 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, + 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, + 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, + 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, + 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, + /* bank 1: 0x0100 */ + 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x9C, 0x40, + 0xFE, 0xF8, 0x56, 0xBE, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x5C, 0x28, 0xF6, 0x0C, 0xF5, 0xC2, 0x8F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x38, + 0x04, 0xF6, 0xE8, 0xF4, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x01, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x47, 0xAE, 0x14, + 0x3E, 0xB8, 0x51, 0xEC, 0x00, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0x2B, 0x80, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x57, 0x0A, 0x3D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x50, 0x50, 0x3F, 0xAF, 0xAF, 0xB0, + 0x02, 0x00, 0x00, 0x00, 0x36, 0x66, 0x66, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0x2B, 0x80, + 0x8E, 0x17, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank 2: 0x0200 */ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3E, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9C, 0x40, 0x0C, 0xCC, 0xCC, 0xCD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0xB8, 0x51, 0xEC, 0x01, 0x47, 0xAE, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x33, 0x33, 0x33, 0x0C, 0xCC, 0xCC, 0xCD, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4B, 0xD1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, + 0x06, 0xD5, 0x8E, 0x27, 0xE1, 0x05, 0x86, 0xB2, + 0x38, 0xB3, 0x8D, 0x1F, 0xCF, 0x87, 0xC3, 0x8F, + 0x06, 0xD5, 0x8E, 0x27, 0x1F, 0xA1, 0xAB, 0x12, + 0x3A, 0x50, 0xFF, 0xCB, 0x31, 0x7D, 0xD5, 0x43, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank 3: 0x0300 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x06, 0x36, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x8D, 0xF2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0xC1, 0xD5, 0x21, 0xCB, 0xCF, 0x2A, 0x67, + 0x51, 0xF6, 0x2F, 0x9C, 0xC5, 0x87, 0x95, 0xAC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x31, 0x88, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x49, 0x6E, 0x64, 0xC5, 0x92, 0x24, 0x82, + 0x59, 0xFA, 0xEE, 0x8D, 0xC2, 0x29, 0xFE, 0xD7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x28, 0xCC, 0xCC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank 4: 0x0400 */ + 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x3A, 0x03, 0xE8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x3F, 0xC1, 0xA7, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x5E, 0x00, 0x00, 0x00, 0xFA, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x13, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x20, 0x00, + /* bank 5: 0x0500 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x61, 0xA8, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x2E, 0xE0, 0x00, 0x06, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0xCC, 0xCC, 0xCD, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank 6: 0x0600 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x49, 0x1B, 0x75, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x0C, 0xCD, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank 7: 0x0700 */ + 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x46, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xD4, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank 8: 0x0800 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x3A, 0x98, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x4E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x47, 0xAE, 0x14, 0x4E, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x4E, 0x40, 0x00, 0x00, + 0x4A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD8, 0xDC, 0xB8, 0xB0, 0xB4, 0xF3, 0xAA, 0xF8, + 0xF9, 0xD1, 0xD9, 0x88, 0x9A, 0xF8, 0xF7, 0x3E, + 0xD8, 0xF3, 0x8A, 0x9A, 0xA7, 0x31, 0xD1, 0xD9, + 0xF4, 0x08, 0xF7, 0xD8, 0xF3, 0x9F, 0x31, 0xD1, + 0xD9, 0xF4, 0x08, 0xF7, 0xDA, 0xF1, 0xFF, 0xD8, + 0xF1, 0xA4, 0xDF, 0xA5, 0xDE, 0xF3, 0xA8, 0xDE, + /* bank 8: 0x0800 */ + 0xD0, 0xDF, 0xA4, 0x84, 0x9F, 0x24, 0xF2, 0xA9, + 0xF8, 0xF9, 0xD1, 0xDA, 0xDE, 0xA8, 0xDE, 0xDF, + 0xDF, 0xDF, 0xD8, 0xF4, 0xB1, 0x8D, 0xF3, 0xA8, + 0xD0, 0xB0, 0xB4, 0x8F, 0xF4, 0xB9, 0xAF, 0xD0, + 0xC7, 0xBE, 0xBE, 0xB8, 0xAE, 0xD0, 0xF3, 0x9F, + 0x75, 0xB2, 0x86, 0xF4, 0xBE, 0xB9, 0xAF, 0xD0, + 0xC3, 0xF1, 0xBE, 0xB8, 0xB0, 0xA3, 0xDE, 0xDF, + 0xDF, 0xDF, 0xF2, 0xA3, 0x81, 0xC0, 0x80, 0xCD, + 0xC7, 0xCF, 0xBC, 0xBD, 0xB4, 0xA3, 0x88, 0x93, + 0xF1, 0x62, 0x6E, 0x76, 0x7E, 0xBE, 0xA2, 0x42, + 0xA0, 0x4E, 0x56, 0x5E, 0xBE, 0xBE, 0xBC, 0xA3, + 0x8B, 0x93, 0x2D, 0x55, 0x7D, 0xA2, 0x86, 0x9D, + 0x08, 0xFD, 0x0F, 0xBC, 0xBC, 0xA3, 0x83, 0x92, + 0x01, 0xA9, 0x9E, 0x0E, 0x16, 0x1E, 0xBE, 0xBE, + 0x99, 0xA5, 0x2C, 0x54, 0x7C, 0xBA, 0xA5, 0x2C, + 0x54, 0x7C, 0xBD, 0xBD, 0xBC, 0xBC, 0xB1, 0xB6, + 0x83, 0x95, 0xA5, 0xF1, 0x0E, 0x16, 0x1E, 0xB2, + 0xA7, 0x85, 0x95, 0x2A, 0xF0, 0x50, 0x78, 0x87, + 0x93, 0xF1, 0x01, 0xDA, 0xA5, 0xDF, 0xDF, 0xDF, + 0xD8, 0xA4, 0xDF, 0xDF, 0xDF, 0xB0, 0x80, 0xF2, + 0xA4, 0xC3, 0xCB, 0xC5, 0xF1, 0xB1, 0x8E, 0x94, + 0xA4, 0x0E, 0x16, 0x1E, 0xB2, 0x86, 0xBE, 0xA0, + 0x2C, 0x34, 0x3C, 0xBD, 0xBD, 0xB4, 0x96, 0xB8, + 0xA1, 0x2C, 0x34, 0x3C, 0xBD, 0xB6, 0x94, 0xBE, + 0xA6, 0x2C, 0xFD, 0x35, 0x34, 0xFD, 0x35, 0x3C, + 0xFD, 0x35, 0xBE, 0xBC, 0xB2, 0x8E, 0x94, 0xA6, + 0x2D, 0x55, 0x7D, 0xBA, 0xA4, 0x2D, 0x55, 0x7D, + 0xB8, 0xB0, 0xB4, 0xA6, 0x8F, 0x96, 0x2E, 0x36, + 0x3E, 0xBC, 0xBC, 0xBD, 0xA6, 0x86, 0x9F, 0xF5, + 0x34, 0x54, 0x74, 0xBC, 0xBE, 0xF1, 0x90, 0xFC, + 0xC3, 0x00, 0xD9, 0xF4, 0x0A, 0x5A, 0xD8, 0xF3, + 0xA0, 0xDF, 0xF1, 0xBC, 0x86, 0x91, 0xA9, 0x2D, + /* bank 9: 0x0900 */ + 0x55, 0x7D, 0xBC, 0xBC, 0xA9, 0x80, 0x90, 0xFC, + 0x51, 0x00, 0x10, 0xFC, 0x51, 0x00, 0x10, 0xFC, + 0x51, 0x00, 0x10, 0xFC, 0xC1, 0x04, 0xD9, 0xF2, + 0xA0, 0xDF, 0xF4, 0x0A, 0x5A, 0xD8, 0xF6, 0xA0, + 0xFA, 0x80, 0x90, 0x38, 0xF3, 0xDE, 0xDA, 0xF8, + 0xF4, 0x0A, 0x5A, 0xD8, 0xF1, 0xBD, 0x95, 0xFC, + 0xC1, 0x04, 0xD9, 0xBD, 0xBD, 0xF4, 0x0A, 0x5A, + 0xDA, 0xBD, 0xBD, 0xD8, 0xF6, 0xBC, 0xBC, 0xBD, + 0xBD, 0xBE, 0xBE, 0xB5, 0xA7, 0x84, 0x92, 0x1A, + 0xF8, 0xF9, 0xD1, 0xDB, 0x84, 0x93, 0xF7, 0x6A, + 0xB6, 0x87, 0x96, 0xF3, 0x09, 0xFF, 0xDA, 0xBC, + 0xBD, 0xBE, 0xD8, 0xF3, 0xBC, 0xBC, 0xBD, 0xBD, + 0xBE, 0xBE, 0xB9, 0xB2, 0xA9, 0x80, 0xCD, 0xF2, + 0xC4, 0xC5, 0xBA, 0xF3, 0xA0, 0xD0, 0xDE, 0xB1, + 0xB4, 0xF7, 0xA7, 0x89, 0x91, 0x72, 0x89, 0x91, + 0x47, 0xB6, 0x97, 0x4A, 0xB9, 0xF2, 0xA9, 0xD0, + 0xFA, 0xF9, 0xD1, 0xD9, 0xF4, 0x0A, 0x8E, 0xD8, + 0xF3, 0xBA, 0xA7, 0xF9, 0xDB, 0xFB, 0xD9, 0xF1, + 0xB9, 0xB0, 0x81, 0xA9, 0xC3, 0xF2, 0xC5, 0xF3, + 0xBA, 0xA0, 0xD0, 0xF8, 0xD8, 0xF1, 0xB1, 0x89, + 0xA7, 0xDF, 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, + 0xC5, 0xF1, 0xB2, 0xB5, 0xB9, 0x87, 0x97, 0xA5, + 0x22, 0xF0, 0x48, 0x70, 0x3C, 0x98, 0x40, 0x68, + 0x34, 0x58, 0x99, 0x60, 0xF1, 0xBC, 0xB3, 0x8E, + 0x95, 0xAA, 0x25, 0x4D, 0x75, 0xBC, 0xBC, 0xB8, + 0xB0, 0xB4, 0xA7, 0x88, 0x9F, 0xF7, 0x5A, 0xF9, + 0xD9, 0xF1, 0xBA, 0xA5, 0xDF, 0xDF, 0xDF, 0xB8, + 0xDA, 0xF3, 0xA8, 0xF8, 0x88, 0x9D, 0xD0, 0x7C, + 0xD8, 0xF7, 0xA7, 0x88, 0x9F, 0x52, 0xF9, 0xD9, + 0xF1, 0xBA, 0xA4, 0xDF, 0xDF, 0xDF, 0xB8, 0xDA, + 0xF3, 0xA8, 0x88, 0x9C, 0xD0, 0xDF, 0x68, 0x70, + 0x9D, 0x60, 0x70, 0x78, 0xD8, 0xF7, 0xA7, 0x88, + /* bank 10: 0x0A00 */ + 0x9F, 0x42, 0xF9, 0xBA, 0xA0, 0xD0, 0xF3, 0xD9, + 0xDE, 0xD8, 0xF8, 0xF9, 0xD1, 0xB8, 0xDA, 0xA8, + 0x88, 0x9E, 0xD0, 0x64, 0x68, 0xD8, 0xA8, 0x84, + 0x98, 0xD0, 0xF7, 0x7E, 0xF0, 0xB2, 0xB6, 0xBA, + 0x85, 0x91, 0xA7, 0x24, 0x70, 0x59, 0x44, 0x69, + 0x38, 0x64, 0x48, 0x31, 0x2D, 0x51, 0x79, 0x87, + 0xF1, 0xA1, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x81, + 0xA7, 0x04, 0x28, 0x50, 0x78, 0xFD, 0x7F, 0xF1, + 0xA7, 0x87, 0x96, 0x59, 0x91, 0xA1, 0x02, 0x0E, + 0x16, 0x1E, 0xF0, 0x84, 0x91, 0xA7, 0x24, 0x70, + 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0x2D, + 0x51, 0x79, 0xA2, 0x87, 0x0D, 0x20, 0x59, 0x70, + 0x15, 0x38, 0x40, 0x69, 0xA4, 0xF1, 0x62, 0xF0, + 0x19, 0x31, 0x48, 0xB8, 0xB1, 0xB4, 0xF1, 0xA6, + 0x80, 0xC6, 0xF4, 0xB0, 0x81, 0xF3, 0xA7, 0xC6, + 0xB1, 0x8F, 0x97, 0xF7, 0x02, 0xF9, 0xDA, 0xF4, + 0x0B, 0xBD, 0xD8, 0xB0, 0xF7, 0xA7, 0x88, 0x9F, + 0x52, 0xF9, 0xD9, 0xF4, 0x0B, 0xB6, 0xD8, 0xF1, + 0xB2, 0xB6, 0xA6, 0x82, 0x92, 0x2A, 0xF0, 0x50, + 0xFD, 0x08, 0xF1, 0xA7, 0x84, 0x94, 0x02, 0xFD, + 0x08, 0xB0, 0xB4, 0x86, 0x97, 0x00, 0xB1, 0xBA, + 0xA7, 0x81, 0x61, 0xD9, 0xF4, 0x0B, 0xF3, 0xD8, + 0xF1, 0x41, 0xDA, 0xF4, 0x0B, 0xF3, 0xD8, 0xF1, + 0xB8, 0xB2, 0xA6, 0x82, 0xC0, 0xD8, 0xF1, 0xB0, + 0xB6, 0x86, 0x92, 0xA7, 0x16, 0xFD, 0x04, 0x0F, + 0xFD, 0x04, 0xF0, 0xBA, 0x87, 0x91, 0xA7, 0x24, + 0x58, 0x3D, 0x40, 0x34, 0x49, 0x2D, 0x51, 0xB2, + 0x87, 0xF1, 0xA1, 0x00, 0x2C, 0x54, 0x7C, 0xF0, + 0x81, 0xA7, 0x04, 0x28, 0x50, 0x78, 0xFD, 0x7F, + 0xF1, 0xA7, 0x87, 0x96, 0x59, 0x91, 0xA1, 0x02, + 0x0E, 0x16, 0x1E, 0xD8, 0xF7, 0xB0, 0xB4, 0xBA, + 0x88, 0x9E, 0xA7, 0x6A, 0xF9, 0xD9, 0xF4, 0x0D, + /* bank 11: 0x0B00 */ + 0x0B, 0xD8, 0xF0, 0xB1, 0xB5, 0x8A, 0x9A, 0xA3, + 0x2C, 0x50, 0x78, 0xF2, 0xA5, 0xDE, 0xF8, 0xF8, + 0xF1, 0xB5, 0xB2, 0xA7, 0x83, 0x90, 0x21, 0xDB, + 0xB6, 0xB1, 0x80, 0x93, 0x29, 0xD9, 0xF2, 0xA5, + 0xF8, 0xD8, 0xF1, 0xB2, 0xB6, 0xA7, 0x83, 0x93, + 0x31, 0xF3, 0xA5, 0xDE, 0xD9, 0xF8, 0xF8, 0xD8, + 0xF1, 0xA9, 0x89, 0x99, 0xF0, 0x34, 0x83, 0x38, + 0xF1, 0xA7, 0x29, 0xF5, 0x87, 0x90, 0x18, 0xD9, + 0xF3, 0xA5, 0xF8, 0xD8, 0xA8, 0x80, 0x91, 0xF0, + 0x0C, 0x31, 0x14, 0x28, 0x1C, 0x20, 0x04, 0x39, + 0xA7, 0x88, 0x98, 0x04, 0x28, 0x51, 0x79, 0x1D, + 0x30, 0x14, 0x38, 0xB1, 0xB8, 0x8A, 0xA7, 0xD0, + 0x97, 0x2C, 0x50, 0x50, 0x78, 0x78, 0xBC, 0xBA, + 0xB0, 0xA7, 0x85, 0x98, 0x04, 0x28, 0x50, 0x78, + 0xF1, 0x84, 0x97, 0x29, 0xD9, 0xBE, 0xB8, 0xA5, + 0x8D, 0x98, 0x20, 0x2C, 0x34, 0x3C, 0xBE, 0xBE, + 0xBA, 0xAA, 0xDE, 0xDF, 0xF8, 0xF4, 0x0C, 0x95, + 0xD8, 0xF1, 0xBA, 0xAA, 0xF8, 0xA7, 0x84, 0x9A, + 0x01, 0xD9, 0xAA, 0xDF, 0xF8, 0xD8, 0xF1, 0xBC, + 0xBC, 0x9A, 0xFC, 0xC1, 0x04, 0xD9, 0xAA, 0xFB, + 0xA6, 0xB2, 0x89, 0x96, 0x42, 0xB4, 0x97, 0xF0, + 0x78, 0xA7, 0x86, 0xF1, 0x38, 0xFD, 0x01, 0xB6, + 0x97, 0x01, 0xA6, 0xD0, 0xB6, 0x9A, 0x52, 0x87, + 0xF0, 0x18, 0xD8, 0xBD, 0xB0, 0xB4, 0xBA, 0x87, + 0x96, 0xA7, 0xF5, 0x78, 0xBD, 0xBD, 0xF3, 0xD9, + 0xA5, 0xF8, 0xD8, 0xB2, 0xB6, 0xF1, 0xA9, 0x89, + 0x93, 0x1A, 0xB0, 0x87, 0x99, 0x60, 0xB8, 0xA7, + 0xD0, 0xB2, 0x89, 0xC1, 0xB0, 0xBA, 0xF3, 0xA5, + 0xF9, 0xF9, 0xB8, 0xF1, 0xDA, 0xA7, 0xD0, 0xDF, + 0xD8, 0xA7, 0xD0, 0xFA, 0xF9, 0xD1, 0xBA, 0xDA, + 0xA7, 0x87, 0x90, 0x6A, 0x66, 0xB2, 0xA0, 0x87, + 0x01, 0x2C, 0xF0, 0xA7, 0x80, 0x90, 0x04, 0x28, + /* bank 12: 0x0C00 */ + 0xFD, 0x7F, 0xF1, 0xA7, 0x87, 0x96, 0x59, 0x90, + 0xA0, 0x02, 0x0E, 0xD8, 0xF0, 0xBA, 0xB2, 0xB6, + 0xA8, 0x80, 0x91, 0x0C, 0x31, 0x14, 0x28, 0x1C, + 0x20, 0x04, 0x39, 0xD8, 0xF7, 0xB8, 0xB4, 0xB0, + 0xA7, 0x9D, 0x88, 0x72, 0xF9, 0xBC, 0xBD, 0xBE, + 0xD9, 0xF4, 0x0E, 0x72, 0xD8, 0xF2, 0xB8, 0xAD, + 0xF8, 0xF9, 0xD1, 0xDA, 0xDE, 0xBA, 0xA1, 0xDE, + 0xAE, 0xDE, 0xF8, 0xD8, 0xF2, 0xB1, 0xB5, 0xB9, + 0xAE, 0xF9, 0xDA, 0xF4, 0x0E, 0x59, 0xD8, 0xF2, + 0x8E, 0xC2, 0xF1, 0xB2, 0x80, 0x9A, 0xF5, 0xAF, + 0x24, 0xD9, 0xF4, 0x0E, 0x59, 0xD8, 0xF5, 0x44, + 0xD9, 0xF4, 0x0E, 0x59, 0xD8, 0xF5, 0x64, 0xD9, + 0xF4, 0x0E, 0x59, 0xD8, 0xF1, 0xB1, 0xB6, 0x8B, + 0x90, 0xAF, 0x2D, 0x55, 0x7D, 0xB5, 0x8C, 0x9F, + 0xAD, 0x0E, 0x16, 0x1E, 0x8B, 0x9D, 0xAB, 0x2C, + 0x54, 0x7C, 0x8D, 0x9F, 0xAA, 0x2E, 0x56, 0x7E, + 0x8A, 0x9C, 0xAA, 0x2C, 0x54, 0x7C, 0x9B, 0xAC, + 0x26, 0x46, 0x66, 0xAF, 0x8D, 0x9D, 0x00, 0x9C, + 0x0D, 0xDB, 0x11, 0x8F, 0x19, 0xF4, 0x0D, 0x9B, + 0xD8, 0x0E, 0x59, 0xD8, 0xF1, 0xB2, 0x81, 0xB6, + 0x90, 0xAF, 0x2D, 0x55, 0x7D, 0xB1, 0x8F, 0xB5, + 0x9F, 0xAF, 0xF5, 0x2C, 0x54, 0x7C, 0xF1, 0xB2, + 0x8C, 0x9F, 0xAD, 0x6D, 0xDB, 0x71, 0x79, 0xF4, + 0x0D, 0xC9, 0xD8, 0xF3, 0xBA, 0xA1, 0xDE, 0xF8, + 0xF1, 0x80, 0xA1, 0xC3, 0xC5, 0xC7, 0xF4, 0x0D, + 0xD8, 0xD8, 0xF3, 0xB6, 0xBA, 0x91, 0xFC, 0xC0, + 0x28, 0xDA, 0xA1, 0xF8, 0xD9, 0xF4, 0x0E, 0x59, + 0xD8, 0xF3, 0xB9, 0xAE, 0xF8, 0xF9, 0xD1, 0xD9, + 0xF8, 0xF4, 0x0E, 0x59, 0xD8, 0xF1, 0xBA, 0xB1, + 0xB5, 0xA0, 0x8B, 0x93, 0x3E, 0x5E, 0x7E, 0xAB, + 0x83, 0xC0, 0xC5, 0xB2, 0xB6, 0xA3, 0x87, 0xC0, + 0xC3, 0xC5, 0xC7, 0xA2, 0x88, 0xC0, 0xC3, 0xC5, + /* bank 13: 0x0D00 */ + 0xC7, 0xA4, 0x86, 0xC0, 0xC3, 0xC5, 0xC7, 0xA5, + 0x85, 0xC4, 0xC7, 0xAC, 0x8D, 0xC0, 0xF3, 0xAE, + 0xDE, 0xF8, 0xF4, 0x11, 0x36, 0xD8, 0xF1, 0xA7, + 0x83, 0xC0, 0xC3, 0xC5, 0xC7, 0xA8, 0x82, 0xC0, + 0xC3, 0xC5, 0xC7, 0xA6, 0x84, 0xC0, 0xC3, 0xC5, + 0xC7, 0xA5, 0x85, 0xD0, 0xC0, 0xC3, 0x8D, 0x9D, + 0xAF, 0x39, 0xD9, 0xF4, 0x0E, 0x59, 0xD8, 0xF1, + 0x83, 0xB5, 0x9E, 0xAE, 0x34, 0xFD, 0x0A, 0x54, + 0xFD, 0x0A, 0x74, 0xFD, 0x0A, 0xF2, 0xAF, 0xDE, + 0xF8, 0xF8, 0xF8, 0xB6, 0x81, 0x9F, 0x05, 0xF8, + 0xF9, 0xD1, 0xDA, 0x8F, 0xA1, 0xC0, 0xF4, 0x0E, + 0x60, 0xD8, 0xF2, 0xBA, 0xAE, 0xF8, 0xF9, 0xD1, + 0xDA, 0xF3, 0xBE, 0xBE, 0xBC, 0xBC, 0xBD, 0xBD, + 0xB8, 0xB0, 0xB4, 0xA5, 0x85, 0x9C, 0x08, 0xBE, + 0xBC, 0xBD, 0xD8, 0xF7, 0xBC, 0xBC, 0xBD, 0xBD, + 0xBB, 0xB4, 0xB0, 0xAF, 0x9E, 0x88, 0x62, 0xF9, + 0xBC, 0xBD, 0xD9, 0xF4, 0x10, 0xB4, 0xD8, 0xF1, + 0xBC, 0xBC, 0xB1, 0x85, 0xBA, 0xB5, 0xA0, 0x98, + 0x06, 0x26, 0x46, 0xBC, 0xB9, 0xB3, 0xB6, 0xF1, + 0xAF, 0x81, 0x90, 0x2D, 0x55, 0x7D, 0xB1, 0xB5, + 0xAF, 0x8F, 0x9F, 0xF5, 0x2C, 0x54, 0x7C, 0xF1, + 0xBB, 0xAF, 0x86, 0x9F, 0x69, 0xDB, 0x71, 0x79, + 0xDA, 0xF3, 0xA0, 0xDF, 0xF8, 0xF1, 0xA1, 0xDE, + 0xF2, 0xF8, 0xD8, 0xB3, 0xB7, 0xF1, 0x8C, 0x9B, + 0xAF, 0x19, 0xD9, 0xAC, 0xDE, 0xF3, 0xA0, 0xDF, + 0xF8, 0xD8, 0xAF, 0x80, 0x90, 0x69, 0xD9, 0xA0, + 0xFA, 0xF1, 0xB2, 0x80, 0xA1, 0xC3, 0xC5, 0xC7, + 0xF2, 0xA0, 0xD0, 0xDF, 0xF8, 0xF4, 0x10, 0x9E, + 0xD8, 0xF2, 0xA0, 0xD0, 0xDF, 0xF1, 0xBC, 0xBC, + 0xB1, 0xAD, 0x8A, 0x9E, 0x26, 0x46, 0x66, 0xBC, + 0xB3, 0xB3, 0xF3, 0xA2, 0xDE, 0xF8, 0xF4, 0x10, + 0xBF, 0xD8, 0xF1, 0xAA, 0x8D, 0xC1, 0xF2, 0xA1, + /* bank 14: 0x0E00 */ + 0xF8, 0xF9, 0xD1, 0xDA, 0xF4, 0x0F, 0x2A, 0xD8, + 0xF1, 0xAF, 0x8A, 0x9A, 0x21, 0x8F, 0x90, 0xF5, + 0x10, 0xDA, 0xF4, 0x0F, 0x2A, 0xD8, 0xF1, 0x91, + 0xFC, 0xC0, 0x04, 0xD9, 0xF4, 0x0F, 0x71, 0xD8, + 0xF3, 0xA1, 0xDE, 0xF8, 0xA0, 0xDF, 0xF8, 0xF4, + 0x10, 0x9E, 0xF3, 0x91, 0xFC, 0xC0, 0x07, 0xD9, + 0xF4, 0x0F, 0x71, 0xD8, 0xF1, 0xAF, 0xB1, 0x84, + 0x9C, 0x01, 0xB3, 0xB5, 0x80, 0x97, 0xDB, 0xF3, + 0x21, 0xB9, 0xA7, 0xD9, 0xF8, 0xF4, 0x0F, 0x71, + 0xD8, 0xF3, 0xB9, 0xA7, 0xDE, 0xF8, 0xBB, 0xF1, + 0xA3, 0x87, 0xC0, 0xC3, 0xC5, 0xC7, 0xA4, 0x88, + 0xC0, 0xC3, 0xC5, 0xC7, 0xA5, 0x89, 0xC0, 0xC3, + 0xC5, 0xC7, 0xA6, 0x86, 0xC4, 0xC7, 0xA1, 0x82, + 0xC3, 0xC5, 0xC7, 0xF3, 0xA1, 0xDE, 0xF4, 0x10, + 0xB4, 0xD8, 0xF1, 0xBB, 0xB3, 0xB7, 0xA1, 0xF8, + 0xF9, 0xD1, 0xDA, 0xF2, 0xA0, 0xD0, 0xDF, 0xF8, + 0xD8, 0xF1, 0xB9, 0xB1, 0xB6, 0xA8, 0x87, 0x90, + 0x2D, 0x55, 0x7D, 0xF5, 0xB5, 0xA8, 0x88, 0x98, + 0x2C, 0x54, 0x7C, 0xF1, 0xAF, 0x86, 0x98, 0x29, + 0xDB, 0x31, 0x39, 0xF4, 0x10, 0xB4, 0xD8, 0xF1, + 0xB3, 0xB6, 0xA7, 0x8A, 0x90, 0x4C, 0x54, 0x5C, + 0xBA, 0xA0, 0x81, 0x90, 0x2D, 0x55, 0x7D, 0xBB, + 0xF2, 0xA2, 0xF8, 0xF9, 0xD1, 0xDA, 0xDE, 0xF4, + 0x10, 0xB4, 0xD8, 0xF1, 0xBA, 0xB0, 0xAB, 0x8F, + 0xC0, 0xC7, 0xB3, 0xA3, 0x83, 0xC0, 0xC3, 0xC5, + 0xC7, 0xA2, 0x84, 0xC0, 0xC3, 0xC5, 0xC7, 0xA4, + 0x85, 0xC0, 0xC3, 0xC5, 0xC7, 0xA5, 0x86, 0xC0, + 0xC3, 0xAC, 0x8C, 0xC2, 0xF3, 0xAE, 0xDE, 0xF8, + 0xF8, 0xF4, 0x11, 0x36, 0xD8, 0xF1, 0xB2, 0xBB, + 0xA3, 0x83, 0xC0, 0xC3, 0xC5, 0xC7, 0xA4, 0x82, + 0xC0, 0xC3, 0xC5, 0xC7, 0xA5, 0x84, 0xC0, 0xC3, + 0xC5, 0xC7, 0xA6, 0x85, 0xC0, 0xC3, 0xAC, 0x8C, + /* bank 15: 0x0F00 */ + 0xC4, 0xB3, 0xB7, 0xAF, 0x85, 0x95, 0x56, 0xFD, + 0x0F, 0x86, 0x96, 0x06, 0xFD, 0x0F, 0xF0, 0x84, + 0x9F, 0xAF, 0x4C, 0x70, 0xFD, 0x0F, 0xF1, 0x86, + 0x96, 0x2E, 0xFD, 0x0F, 0x84, 0x9F, 0x72, 0xFD, + 0x0F, 0xDF, 0xAF, 0x2C, 0x54, 0x7C, 0xAF, 0x8C, + 0x69, 0xDB, 0x71, 0x79, 0x8B, 0x9C, 0x61, 0xF4, + 0x10, 0x35, 0xDA, 0x10, 0xB4, 0xD8, 0xF1, 0xAB, + 0x83, 0x91, 0x28, 0xFD, 0x05, 0x54, 0xFD, 0x05, + 0x7C, 0xFD, 0x05, 0xB8, 0xBD, 0xBD, 0xB5, 0xA3, + 0x8B, 0x95, 0x05, 0x2D, 0x55, 0xBD, 0xB4, 0xBB, + 0xAD, 0x8E, 0x93, 0x0E, 0x16, 0x1E, 0xB7, 0xF3, + 0xA2, 0xDE, 0xF8, 0xF8, 0xF4, 0x10, 0xBF, 0xD8, + 0xF2, 0xA1, 0xF8, 0xF9, 0xD1, 0xD9, 0xF1, 0xAF, + 0x8D, 0x9A, 0x01, 0xF5, 0x8F, 0x90, 0xDB, 0x00, + 0xF4, 0x10, 0xB4, 0xDA, 0xF1, 0xAA, 0x8D, 0xC0, + 0xAE, 0x8B, 0xC1, 0xC3, 0xC5, 0xA1, 0xDE, 0xA7, + 0x83, 0xC0, 0xC3, 0xC5, 0xC7, 0xA8, 0x84, 0xC0, + 0xC3, 0xC5, 0xC7, 0xA9, 0x85, 0xC0, 0xC3, 0xC5, + 0xC7, 0xA6, 0x86, 0xD0, 0xC0, 0xC3, 0xA2, 0x81, + 0xC3, 0xC5, 0xC7, 0xF4, 0x10, 0xB4, 0xF1, 0xBB, + 0xB3, 0xA3, 0xDE, 0xDF, 0xDF, 0xDF, 0xA4, 0x8C, + 0xC4, 0xC5, 0xC5, 0xC5, 0xA5, 0xDE, 0xDF, 0xDF, + 0xDF, 0xA6, 0xDE, 0xDF, 0xD8, 0xF3, 0xB9, 0xAE, + 0xDF, 0xBA, 0xAE, 0xDE, 0xBB, 0xA2, 0xDE, 0xD8, + 0xF3, 0xA2, 0xF8, 0xF9, 0xD1, 0xD9, 0xF4, 0x11, + 0x34, 0xD8, 0xF5, 0xAD, 0x8D, 0x9D, 0x2C, 0x54, + 0x7C, 0xF1, 0xAF, 0x49, 0xDA, 0xC3, 0xC5, 0xD9, + 0xC5, 0xC3, 0xD8, 0xAF, 0x9F, 0x69, 0xD0, 0xDA, + 0xC7, 0xD9, 0x8F, 0xC3, 0x8D, 0xAF, 0xC7, 0xD8, + 0xB9, 0xA9, 0x8F, 0x9F, 0xF0, 0x54, 0x78, 0xF1, + 0xFD, 0x0F, 0xA6, 0xB1, 0x89, 0xC2, 0xB3, 0xAF, + 0x8F, 0x9F, 0x2E, 0xFD, 0x11, 0xB1, 0xB5, 0xA9, + /* bank 16: 0x1000 */ + 0x89, 0x9F, 0x2C, 0xF3, 0xAE, 0xDF, 0xF8, 0xF8, + 0xF4, 0x12, 0xEB, 0xD8, 0xF1, 0xAD, 0x86, 0x99, + 0x06, 0xFD, 0x10, 0xDF, 0xF8, 0xFD, 0x0F, 0xAD, + 0x8D, 0x9D, 0x4C, 0xBB, 0xB3, 0xAD, 0x8F, 0x9D, + 0x2A, 0xFD, 0x0F, 0xB7, 0x92, 0xFC, 0xC0, 0x04, + 0xD9, 0xF4, 0x0E, 0xF9, 0xD8, 0xFC, 0xC0, 0x08, + 0xD9, 0xF4, 0x10, 0x5F, 0xD8, 0xF1, 0xD8, 0xF3, + 0xBA, 0xB2, 0xB6, 0xAE, 0xF8, 0xF9, 0xD1, 0xD9, + 0xF4, 0x12, 0xE9, 0xD8, 0xF1, 0xAF, 0xDE, 0xF9, + 0xFD, 0x0F, 0x80, 0x90, 0x2C, 0x54, 0x7C, 0xA0, + 0x2A, 0xF0, 0x50, 0x78, 0xFD, 0x0F, 0xF1, 0xA2, + 0x82, 0x9C, 0x00, 0x24, 0x44, 0x64, 0xA9, 0x8F, + 0x94, 0xF0, 0x04, 0xFD, 0x0F, 0x0C, 0x30, 0xFD, + 0x0F, 0x1C, 0x95, 0x20, 0x48, 0xFD, 0x0F, 0xF1, + 0x99, 0xC1, 0x2C, 0x54, 0x7C, 0xAA, 0x82, 0x99, + 0x02, 0xFD, 0x0F, 0x2E, 0xFD, 0x0F, 0x56, 0xFD, + 0x0F, 0x7E, 0xFD, 0x0F, 0xAC, 0x83, 0x9F, 0xF0, + 0x04, 0x28, 0x50, 0x78, 0xFD, 0x0F, 0x8C, 0x90, + 0xF1, 0x21, 0xF5, 0x8C, 0x9C, 0x2C, 0xF1, 0xAF, + 0xDE, 0xF1, 0x89, 0xAF, 0x9F, 0xFC, 0xC0, 0x00, + 0xD9, 0xC1, 0x8A, 0xC1, 0x82, 0xC1, 0xD8, 0xFC, + 0xC0, 0x04, 0xD9, 0xC3, 0x8A, 0xC3, 0x82, 0xC3, + 0xD8, 0xFC, 0xC0, 0x08, 0xD9, 0xC5, 0x8A, 0xC5, + 0x82, 0xC5, 0xD8, 0xFC, 0xC0, 0x0C, 0xD9, 0xC7, + 0x8A, 0xC7, 0x82, 0xC7, 0xD8, 0xFC, 0xC0, 0x10, + 0xD9, 0xF4, 0x12, 0xA3, 0xD8, 0xF1, 0x8B, 0xAB, + 0xD0, 0xC0, 0x9F, 0x2E, 0xFD, 0x0F, 0xA0, 0xDE, + 0xAB, 0xD0, 0x90, 0x65, 0xA0, 0x8F, 0x9F, 0x4A, + 0xFD, 0x0F, 0xAB, 0x8B, 0x90, 0x00, 0xB9, 0xA9, + 0xC1, 0xF3, 0xAE, 0xDF, 0xF8, 0xF4, 0x12, 0xEB, + 0xD8, 0xF1, 0xBA, 0xB1, 0xB6, 0x89, 0xAB, 0xC1, + 0xB2, 0xAF, 0xD0, 0x8B, 0x9F, 0x3E, 0xFD, 0x0F, + /* bank 17: 0x1100 */ + 0x5A, 0xFD, 0x0F, 0x9F, 0xFC, 0xC0, 0x00, 0xD9, + 0xF1, 0x8F, 0xA2, 0xC6, 0xD8, 0xFC, 0xC0, 0x04, + 0xD9, 0x8F, 0xA2, 0xC7, 0x84, 0xAB, 0xD0, 0xC0, + 0xAF, 0x8A, 0x9B, 0x1E, 0xFD, 0x0F, 0x36, 0xFD, + 0x0F, 0xA4, 0x8F, 0x30, 0xAA, 0x9A, 0x40, 0xD8, + 0x9F, 0xFC, 0xC0, 0x08, 0xD9, 0x8F, 0xA2, 0xD0, + 0xC6, 0x84, 0xAB, 0xD0, 0xC2, 0xAF, 0x8A, 0x9B, + 0x1E, 0xFD, 0x0F, 0x56, 0xFD, 0x0F, 0xA4, 0x8F, + 0x34, 0xAA, 0x9A, 0x40, 0x84, 0xAB, 0xD0, 0xC4, + 0xAF, 0x8A, 0x9B, 0x3E, 0xFD, 0x0F, 0x56, 0xFD, + 0x0F, 0xA4, 0xD0, 0x8F, 0x30, 0xAA, 0x9A, 0x4C, + 0xD8, 0x9F, 0xFC, 0xC0, 0x0C, 0xD9, 0x8F, 0xA2, + 0xD0, 0xC7, 0x84, 0xAB, 0xD0, 0xC6, 0xAF, 0x8A, + 0x9B, 0x1E, 0xFD, 0x0F, 0x76, 0xFD, 0x0F, 0xA4, + 0xD0, 0x8F, 0x34, 0xAA, 0x9A, 0x40, 0x85, 0xAB, + 0xD0, 0xC0, 0xAF, 0x8A, 0x9B, 0x3E, 0xFD, 0x0F, + 0x76, 0xFD, 0x0F, 0xA5, 0x8F, 0x30, 0xAA, 0x9A, + 0x4C, 0x85, 0xAB, 0xD0, 0xC2, 0xAF, 0x8A, 0x9B, + 0x5E, 0xFD, 0x0F, 0x76, 0xFD, 0x0F, 0xA5, 0x8F, + 0x34, 0xAA, 0xD0, 0x9A, 0x50, 0xD8, 0xAF, 0xF8, + 0xF4, 0x11, 0x99, 0xF1, 0xD8, 0x8B, 0x9C, 0xAF, + 0x2A, 0xFD, 0x0F, 0x8A, 0x9F, 0xB9, 0xAF, 0x02, + 0xFD, 0x0F, 0x26, 0xFD, 0x0F, 0x46, 0xFD, 0x0F, + 0x66, 0xFD, 0x0F, 0x83, 0xB5, 0x9F, 0xBA, 0xA3, + 0x00, 0x2C, 0x54, 0x7C, 0xB6, 0x82, 0x92, 0xA0, + 0x31, 0xD9, 0xAD, 0xC3, 0xDA, 0xAD, 0xC5, 0xD8, + 0x8D, 0xA0, 0x39, 0xDA, 0x82, 0xAD, 0xC7, 0xD8, + 0xF3, 0x9E, 0xFC, 0xC0, 0x04, 0xD9, 0xF4, 0x0E, + 0x15, 0xD8, 0xFC, 0xC0, 0x08, 0xD9, 0xF4, 0x0F, + 0xE4, 0xD8, 0xF1, 0xD8, 0xF1, 0xB9, 0xB1, 0xB5, + 0xA9, 0xDE, 0xF8, 0x89, 0x99, 0xAF, 0x31, 0xD9, + 0xF4, 0x13, 0x3F, 0xD8, 0xF1, 0x85, 0xAF, 0x29, + /* bank 18: 0x1200 */ + 0xD9, 0x84, 0xA9, 0xC2, 0xD8, 0x85, 0xAF, 0x49, + 0xD9, 0x84, 0xA9, 0xC4, 0xD8, 0x85, 0xAF, 0x69, + 0xD9, 0x84, 0xA9, 0xC6, 0xD8, 0x89, 0xAF, 0x39, + 0xDA, 0x8E, 0xA9, 0x50, 0xF4, 0x13, 0x3F, 0xD8, + 0xF1, 0x89, 0xAA, 0x7C, 0xFD, 0x02, 0x9A, 0x68, + 0xD8, 0xF1, 0xAA, 0xFB, 0xDA, 0x89, 0x99, 0xAF, + 0x26, 0xFD, 0x0F, 0x8F, 0x95, 0x25, 0x89, 0x9F, + 0xA9, 0x12, 0xFD, 0x0F, 0xF4, 0x13, 0x28, 0xD8, + 0xF3, 0x9E, 0xFC, 0xC1, 0x04, 0xD9, 0xF4, 0x11, + 0xF0, 0xD8, 0xFC, 0xC1, 0x08, 0xD9, 0xF4, 0x11, + 0x0B, 0xD8, 0xF1, 0xBE, 0xBC, 0xBC, 0xBD, 0xBD, + 0xF7, 0xB8, 0xB4, 0xB0, 0xAC, 0x84, 0x9D, 0x12, + 0xF9, 0xF2, 0xBC, 0xBC, 0x8A, 0xA7, 0xD0, 0xD9, + 0xC3, 0xDA, 0xC5, 0xD8, 0xBC, 0xBD, 0xBD, 0xF3, + 0x8F, 0xA8, 0xC0, 0xF9, 0xAC, 0x84, 0x97, 0xF5, + 0x1A, 0xF1, 0xF8, 0xF9, 0xD1, 0xDA, 0xA8, 0xDE, + 0xD8, 0x95, 0xFC, 0xC1, 0x03, 0xD9, 0xA8, 0xDE, + 0xD8, 0xBC, 0xBC, 0xF1, 0x98, 0xFC, 0xC0, 0x1C, + 0xDB, 0x95, 0xFC, 0xC0, 0x03, 0xA5, 0xDE, 0xA4, + 0xDE, 0xD8, 0xAC, 0x88, 0x95, 0x00, 0xD1, 0xD9, + 0xA5, 0xF8, 0xD8, 0xA4, 0xFC, 0x80, 0x04, 0x88, + 0x95, 0xA4, 0xFC, 0x08, 0x04, 0x20, 0xF7, 0xBC, + 0xBD, 0xB5, 0xAC, 0x84, 0x9F, 0xF6, 0x02, 0xF8, + 0xF9, 0xD1, 0xDB, 0x84, 0x93, 0xF7, 0x6A, 0xF9, + 0xD9, 0xF3, 0xBC, 0xBC, 0xA8, 0x88, 0x92, 0x18, + 0xBC, 0xD8, 0xBC, 0xBC, 0xB4, 0xA8, 0x88, 0x9E, + 0x08, 0xF4, 0xBE, 0xA1, 0xD0, 0xBC, 0xF7, 0xBE, + 0xBE, 0xB5, 0xAC, 0x84, 0x93, 0x6A, 0xF9, 0xBD, + 0xBD, 0xB4, 0xD9, 0xF2, 0xAC, 0x8C, 0x97, 0x18, + 0xF6, 0x84, 0x9C, 0x02, 0xF8, 0xF9, 0xDB, 0xD1, + 0xF1, 0xA5, 0xDF, 0xD8, 0xF7, 0xBE, 0xBD, 0xA7, + 0x9D, 0x88, 0x7A, 0xF9, 0xD9, 0xF4, 0x15, 0x8B, + /* bank 19: 0x1300 */ + 0xD8, 0xF1, 0xBE, 0xBE, 0xAC, 0xDE, 0xDF, 0xAC, + 0x88, 0x9F, 0xF7, 0x5A, 0x56, 0xF1, 0xBC, 0xBC, + 0xBD, 0xBD, 0x95, 0xFC, 0xC0, 0x07, 0xDA, 0xF4, + 0x15, 0x2C, 0xD8, 0xF1, 0xFC, 0xC0, 0x00, 0xDB, + 0x9C, 0xFC, 0xC1, 0x00, 0xF4, 0x15, 0x51, 0xD8, + 0xF1, 0xAC, 0x95, 0xFC, 0xC0, 0x08, 0xDA, 0xF4, + 0x14, 0x72, 0xD8, 0xF1, 0x82, 0x90, 0x79, 0x2D, + 0x55, 0xF5, 0x8C, 0x9C, 0x04, 0xAC, 0x2C, 0x54, + 0xF1, 0xBC, 0xBC, 0x80, 0x5D, 0xDB, 0x49, 0x51, + 0xF4, 0xBC, 0x14, 0x50, 0xDA, 0xBC, 0x15, 0x28, + 0xD8, 0xF5, 0x86, 0x98, 0x38, 0xD9, 0xF1, 0x82, + 0x90, 0x2D, 0xD8, 0xAC, 0xD0, 0x86, 0x98, 0xF5, + 0x5C, 0xD9, 0xF1, 0x82, 0x90, 0x55, 0xD8, 0xAC, + 0x8C, 0x9C, 0x00, 0x00, 0xA5, 0xDF, 0xF8, 0xF4, + 0x14, 0x7D, 0xD8, 0xF1, 0x82, 0x96, 0x2D, 0x55, + 0x7D, 0x8C, 0x9C, 0x34, 0x18, 0xF1, 0xAC, 0x95, + 0xF5, 0x1C, 0xD9, 0xF4, 0x15, 0x28, 0xD8, 0xF1, + 0xAC, 0x83, 0x90, 0x45, 0xD9, 0xA0, 0xF8, 0xAC, + 0x8C, 0x9C, 0x06, 0xD2, 0xA1, 0x91, 0x00, 0x2C, + 0x81, 0xD6, 0xF0, 0xA1, 0xD0, 0x8C, 0x9C, 0x28, + 0xD3, 0x87, 0xD4, 0xA7, 0x8C, 0x20, 0xD3, 0xF1, + 0xA4, 0x84, 0x90, 0x2C, 0x54, 0x7C, 0xD8, 0xAC, + 0x83, 0x90, 0x45, 0xD9, 0xF4, 0x15, 0x51, 0xD8, + 0xF1, 0xAC, 0x81, 0x91, 0x02, 0xFD, 0x18, 0x85, + 0x66, 0xFD, 0x1F, 0x88, 0x4E, 0xFD, 0x1D, 0x87, + 0xD4, 0xFD, 0x56, 0xF0, 0x81, 0x9C, 0xAB, 0xD6, + 0xFD, 0x08, 0x31, 0x8C, 0x10, 0x10, 0x01, 0x01, + 0x01, 0x39, 0xAC, 0x8B, 0x98, 0xF5, 0x08, 0xD9, + 0xF4, 0x15, 0x28, 0xD8, 0xF1, 0xA9, 0x82, 0x96, + 0x01, 0x95, 0xFC, 0xC1, 0x00, 0xDA, 0xF4, 0x15, + 0x00, 0xDB, 0xF1, 0xAC, 0x89, 0x93, 0xF5, 0x18, + 0xF1, 0xA5, 0xDF, 0xF8, 0xD8, 0xF4, 0x15, 0x2C, + /* bank 20: 0x1400 */ + 0xD8, 0xF1, 0xA4, 0x84, 0x95, 0x34, 0xFD, 0x08, + 0x54, 0xFD, 0x08, 0x74, 0xFD, 0x08, 0xA9, 0x94, + 0xF5, 0x2C, 0x54, 0x7C, 0xF1, 0xAC, 0x87, 0x99, + 0x49, 0xDB, 0x51, 0x59, 0x84, 0xAB, 0xC3, 0xC5, + 0xC7, 0x82, 0xA6, 0xC0, 0xF3, 0xAA, 0xDF, 0xF8, + 0xD8, 0xF1, 0xA5, 0xDF, 0xD8, 0xF1, 0xA0, 0xDE, + 0xA1, 0xDE, 0xDF, 0xDF, 0xDF, 0xA7, 0xDE, 0xDF, + 0xA4, 0xDF, 0xDF, 0xDF, 0xA2, 0x95, 0xFC, 0xC0, + 0x01, 0xD9, 0x80, 0xC3, 0xC5, 0xC7, 0xA8, 0x83, + 0xC1, 0xDA, 0x86, 0xC3, 0xC5, 0xC7, 0xA8, 0x83, + 0xC3, 0xD8, 0xF1, 0x9A, 0xFC, 0xC1, 0x04, 0xD9, + 0xAC, 0x82, 0x96, 0x01, 0xF3, 0xAA, 0xDE, 0xF8, + 0xF8, 0xF8, 0xDB, 0xF5, 0xAC, 0x8C, 0x9A, 0x18, + 0xF3, 0xAA, 0xF9, 0xD8, 0xAC, 0x8A, 0x9A, 0x41, + 0xD1, 0xAA, 0xD0, 0xC0, 0xD9, 0xF2, 0xAC, 0x85, + 0x9A, 0x41, 0xDB, 0xD1, 0xBC, 0xBD, 0xBE, 0xF4, + 0x15, 0x8B, 0xD8, 0xF3, 0xBC, 0xBD, 0xBE, 0xA5, + 0x85, 0x9C, 0x10, 0xD8, 0xF1, 0xBB, 0xB2, 0xB6, + 0xF2, 0xBE, 0xA1, 0xF8, 0xF9, 0xD1, 0xBE, 0xBE, + 0xBA, 0xDA, 0xA5, 0xDE, 0xD8, 0xA7, 0x82, 0x95, + 0x65, 0xD1, 0x85, 0xA2, 0xD0, 0xC1, 0xD9, 0xB5, + 0xA7, 0x86, 0x93, 0x31, 0xDB, 0xD1, 0xF4, 0x15, + 0xBA, 0xD8, 0xF3, 0xB8, 0xB0, 0xB4, 0xA5, 0x85, + 0x9C, 0x18, 0xD8, 0xF1, 0xBA, 0xB2, 0xB6, 0x81, + 0x96, 0xA1, 0xF8, 0xF9, 0xB9, 0xA6, 0xDA, 0xC3, + 0xC5, 0xC7, 0xD9, 0x2D, 0x4D, 0x6D, 0xD8, 0xBA, + 0x88, 0xA8, 0xF8, 0xF9, 0xA7, 0xDA, 0xC3, 0xC5, + 0xC7, 0xD9, 0x2D, 0x4D, 0x6D, 0xD8, 0xF2, 0xB0, + 0xB9, 0xA3, 0xFA, 0xF9, 0xD1, 0xDA, 0xB8, 0x8F, + 0xA7, 0xC0, 0xF9, 0xB5, 0x87, 0x93, 0xF6, 0x0A, + 0xF2, 0xB4, 0xA4, 0x84, 0x97, 0x24, 0xA4, 0x84, + 0x9E, 0x3C, 0xD8, 0xF7, 0xB9, 0xB0, 0xB5, 0xA6, + /* bank 21: 0x1500 */ + 0x88, 0x95, 0x5A, 0xF9, 0xDA, 0xF1, 0xAB, 0xF8, + 0xD8, 0xB8, 0xB4, 0xF3, 0x98, 0xFC, 0xC0, 0x04, + 0xDA, 0xF4, 0x16, 0x64, 0xD8, 0xF2, 0xA9, 0xD0, + 0xF8, 0x89, 0x9B, 0xA7, 0x51, 0xD9, 0xA9, 0xD0, + 0xDE, 0xA4, 0x84, 0x9E, 0x2C, 0xD8, 0xA8, 0xFA, + 0x88, 0x9A, 0xA7, 0x29, 0xD9, 0xA8, 0xDF, 0xA4, + 0x84, 0x9D, 0x34, 0xD8, 0xA8, 0xD0, 0xF8, 0x88, + 0x9A, 0xA7, 0x51, 0xD9, 0xA8, 0xD0, 0xDE, 0xA4, + 0x84, 0x9D, 0x2C, 0xD8, 0xA8, 0xD0, 0xFA, 0x88, + 0x9A, 0xA7, 0x79, 0xD9, 0xA8, 0xD0, 0xDF, 0xA4, + 0x84, 0x9D, 0x24, 0xD8, 0xF3, 0xA9, 0xD0, 0xF8, + 0x89, 0x9B, 0xA7, 0x51, 0xD9, 0xA9, 0xD0, 0xDE, + 0xA4, 0x84, 0x9C, 0x2C, 0xD8, 0xF7, 0xA7, 0x88, + 0x9F, 0x52, 0xF9, 0xD9, 0xF4, 0x16, 0xA1, 0xD8, + 0xF1, 0xB9, 0xA2, 0xFA, 0xF3, 0xB8, 0xA9, 0xD0, + 0xFA, 0x89, 0x9B, 0xA7, 0x79, 0xD9, 0xA9, 0xD0, + 0xDF, 0xA4, 0x84, 0x9C, 0x24, 0xD8, 0xA7, 0x84, + 0x9D, 0xF7, 0x12, 0xF9, 0xD9, 0xF4, 0x16, 0xA1, + 0xD8, 0xF2, 0xA8, 0xD0, 0xF8, 0x88, 0x9A, 0xA7, + 0x51, 0xD9, 0xA8, 0xD0, 0xDE, 0xA4, 0x84, 0x9D, + 0x2C, 0xD8, 0xF7, 0xA7, 0x88, 0x9F, 0x42, 0xF9, + 0xD9, 0xF4, 0x16, 0xE8, 0xD8, 0xF3, 0xA9, 0xF8, + 0x89, 0x9B, 0xA7, 0x01, 0xD9, 0xA9, 0xDE, 0xA4, + 0x84, 0x9C, 0x3C, 0xD8, 0xA9, 0xFA, 0x89, 0x9B, + 0xA7, 0x29, 0xD9, 0xA9, 0xDF, 0xA4, 0x84, 0x9C, + 0x34, 0xD8, 0xF2, 0xA9, 0xFA, 0x89, 0x9B, 0xA7, + 0x29, 0xD9, 0xA9, 0xDF, 0xA4, 0x84, 0x9E, 0x34, + 0xD8, 0xA9, 0xD0, 0xFA, 0x89, 0x9B, 0xA7, 0x79, + 0xD9, 0xA9, 0xD0, 0xDF, 0xA4, 0x84, 0x9E, 0x24, + 0xD8, 0xF2, 0xA4, 0x84, 0x9D, 0x3C, 0xF1, 0xA7, + 0xDE, 0xF2, 0x84, 0xCA, 0x97, 0xA4, 0x24, 0xA5, + 0x94, 0xF6, 0x0A, 0xF7, 0x85, 0x02, 0xF8, 0xF9, + /* bank 22: 0x1600 */ + 0xD1, 0xD9, 0xF6, 0x9B, 0x02, 0xD8, 0xA7, 0xB1, + 0x80, 0x95, 0x42, 0xF8, 0xF9, 0xD1, 0xD9, 0xF4, + 0x18, 0x5B, 0xD8, 0xF0, 0xB0, 0x85, 0xA4, 0xD0, + 0xC0, 0xDD, 0xF2, 0xC0, 0xDC, 0xF6, 0xA7, 0x9F, + 0x02, 0xF9, 0xD9, 0xF3, 0xA5, 0xDE, 0xDA, 0xF0, + 0xDD, 0xF2, 0xC8, 0xDC, 0xD8, 0x85, 0x95, 0xA5, + 0x00, 0xD9, 0x86, 0xF0, 0xDD, 0xF2, 0xCA, 0xCC, + 0xCE, 0xDC, 0xD8, 0x85, 0x00, 0xD9, 0x80, 0xF0, + 0xDD, 0xF2, 0xCC, 0xC6, 0xCE, 0xDC, 0xD8, 0x85, + 0x00, 0xD9, 0xB1, 0x89, 0xF0, 0xDD, 0xF2, 0xC2, + 0xCA, 0xC4, 0xDC, 0xD8, 0xB0, 0x85, 0x00, 0xD9, + 0x81, 0xF0, 0xDD, 0xF2, 0xC6, 0xCE, 0x82, 0xC0, + 0xC8, 0xDC, 0xD8, 0x85, 0x00, 0xB1, 0xD9, 0x86, + 0xF0, 0xDD, 0xF1, 0xC2, 0xC4, 0xC6, 0xDC, 0xD8, + 0xB0, 0xF2, 0x85, 0x00, 0xD9, 0xB2, 0x87, 0xF0, + 0xDD, 0xF1, 0xC2, 0xC4, 0xC6, 0xF2, 0xB2, 0x86, + 0xC4, 0xDC, 0xD8, 0xB0, 0x85, 0x00, 0xB1, 0xD9, + 0x8F, 0xF0, 0xDD, 0xF2, 0xC2, 0xC4, 0xC6, 0xDC, + 0xD8, 0xB0, 0x85, 0x00, 0x00, 0xD9, 0x82, 0xF0, + 0xDD, 0xF2, 0xC2, 0xCA, 0xC4, 0xDC, 0xD8, 0x85, + 0x00, 0xD9, 0x85, 0xF0, 0xDD, 0xF1, 0xC2, 0xC4, + 0xC6, 0xDC, 0xD8, 0xF2, 0x85, 0x00, 0xD9, 0xB1, + 0x8A, 0xF0, 0xDD, 0xF1, 0xC2, 0xC4, 0xC6, 0xDC, + 0xD8, 0xB0, 0xF2, 0x85, 0x00, 0xD9, 0xB1, 0xF0, + 0xDD, 0xF1, 0x82, 0xC4, 0xDC, 0xD8, 0xB0, 0xF3, + 0xA5, 0xF8, 0xF9, 0xD1, 0xD9, 0xF4, 0x18, 0x10, + 0xD8, 0xF3, 0x85, 0x95, 0xA5, 0x00, 0x00, 0xD9, + 0xBE, 0xF2, 0xBA, 0xAE, 0xDE, 0xBE, 0xBE, 0xBC, + 0xB2, 0x81, 0xF0, 0xDD, 0xF3, 0xC8, 0xDC, 0xBC, + 0xBC, 0xD8, 0xB0, 0xB8, 0x85, 0xA5, 0x00, 0xD9, + 0xF2, 0xBE, 0xBE, 0xAA, 0xDE, 0xBE, 0xBC, 0xBC, + 0x8A, 0xF0, 0xDD, 0xF3, 0xC0, 0xDC, 0xBC, 0xD8, + /* bank 23: 0x1700 */ + 0x85, 0xA5, 0x00, 0xD9, 0xB9, 0xF2, 0xA3, 0xD0, + 0xDE, 0xB2, 0x85, 0xF0, 0xDD, 0xF3, 0xC8, 0xDC, + 0xD8, 0xF6, 0xB8, 0xB0, 0xA7, 0x84, 0x9D, 0x5A, + 0xF8, 0xF9, 0xD1, 0xDA, 0xB1, 0x80, 0xF0, 0xDD, + 0xF3, 0xC4, 0xDC, 0xD8, 0xF2, 0x86, 0xB9, 0xAF, + 0xC3, 0xC5, 0xC7, 0xF2, 0xB9, 0xA3, 0xDF, 0xB8, + 0xB0, 0xB4, 0xA7, 0x84, 0x9D, 0xF7, 0x1A, 0xF9, + 0xD9, 0xF4, 0x18, 0x49, 0xD8, 0xF1, 0xB9, 0xB1, + 0xB5, 0xA6, 0x83, 0x9B, 0x61, 0xD9, 0xF4, 0x18, + 0x5B, 0xD8, 0xF6, 0xB8, 0xB0, 0xB4, 0xA7, 0x84, + 0x94, 0x5A, 0xF8, 0xF9, 0xD1, 0xDA, 0xFE, 0xF1, + 0xB9, 0xAB, 0xDE, 0xD8, 0xF1, 0xB8, 0xB0, 0xB4, + 0xA7, 0x88, 0x9C, 0xF7, 0x6A, 0xF9, 0xD9, 0xFF, + 0xD8, 0xF1, 0xBB, 0xAA, 0xF9, 0xDA, 0xFF, 0xD8, + 0xB3, 0x8A, 0xC2, 0xB2, 0x8B, 0xB6, 0x94, 0xBA, + 0xA7, 0x22, 0xB7, 0x93, 0xF0, 0x31, 0x31, 0x20, + 0xD3, 0x8F, 0xB6, 0x9C, 0xAB, 0x01, 0x29, 0x51, + 0x79, 0xAF, 0xC2, 0xC5, 0xC7, 0x8B, 0x9B, 0xF1, + 0x04, 0xFD, 0x01, 0x87, 0xD4, 0x8E, 0x9D, 0xAB, + 0xF0, 0x01, 0x29, 0x51, 0x79, 0xAE, 0xC2, 0xC5, + 0xC7, 0x8B, 0x9B, 0xF1, 0x04, 0xFD, 0x01, 0xB3, + 0x81, 0x94, 0xBB, 0xA7, 0x62, 0xB7, 0x93, 0xF0, + 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29, 0x51, + 0x79, 0xA5, 0xC2, 0xC5, 0xC7, 0x87, 0x97, 0xF1, + 0x04, 0xFD, 0x01, 0x81, 0xB6, 0x94, 0xA7, 0x02, + 0xB7, 0x93, 0xF0, 0x11, 0x11, 0x00, 0x8E, 0x9B, + 0x01, 0x29, 0x51, 0x79, 0xAE, 0xC2, 0xC5, 0xC7, + 0x87, 0x97, 0xF1, 0x04, 0xFD, 0x01, 0x83, 0xA3, + 0xC2, 0xC5, 0xC7, 0xB2, 0x84, 0xC1, 0xB0, 0xB4, + 0xB8, 0x88, 0x9D, 0xA7, 0xF7, 0x62, 0xF9, 0xD9, + 0xF4, 0x19, 0x5E, 0xD8, 0xF1, 0xBE, 0xAA, 0xF8, + 0xFA, 0xAB, 0xDE, 0xBC, 0x8B, 0xBD, 0x9B, 0xBE, + /* bank 24: 0x1800 */ + 0xBE, 0xBA, 0xAF, 0xD0, 0xFC, 0x58, 0x00, 0x10, + 0xBE, 0xB8, 0xFC, 0xC0, 0x04, 0xDB, 0xFC, 0xC1, + 0x00, 0xAA, 0xDE, 0xDF, 0xAC, 0xDE, 0xDF, 0xAB, + 0xDF, 0xF8, 0xD8, 0xAC, 0xFC, 0x90, 0x00, 0x8C, + 0xFC, 0x09, 0x04, 0x00, 0x8A, 0x9C, 0xA9, 0x31, + 0xD9, 0xAA, 0xDF, 0xAC, 0xDF, 0xD8, 0x9B, 0xFC, + 0xC0, 0x04, 0xDB, 0x9A, 0xA9, 0x19, 0xAC, 0xF8, + 0xD8, 0x9B, 0xFC, 0xC1, 0x04, 0xDB, 0x9A, 0xA9, + 0x11, 0xAB, 0xDF, 0x8C, 0x9C, 0xA9, 0x19, 0xD9, + 0xF3, 0xBC, 0xBC, 0xBD, 0xBD, 0xBE, 0xBE, 0x8D, + 0x94, 0xA4, 0xD0, 0x1D, 0xF4, 0x42, 0xDA, 0xF1, + 0xBC, 0xBC, 0xBD, 0xBD, 0xBE, 0xBE, 0xD8, 0xF1, + 0xB1, 0x8B, 0xB5, 0x9A, 0xB9, 0xA6, 0x41, 0xD9, + 0xAA, 0xF8, 0xF5, 0xB2, 0x8F, 0xB6, 0x9F, 0xA6, + 0x78, 0x8E, 0x9E, 0x7C, 0xF1, 0xB1, 0x81, 0xB5, + 0x96, 0x05, 0x2D, 0x8E, 0xA6, 0x72, 0x7E, 0x81, + 0xA1, 0x00, 0x2C, 0xF4, 0x19, 0xAA, 0xD8, 0xF1, + 0xAA, 0xDE, 0x81, 0x91, 0xA6, 0x2C, 0xFD, 0x02, + 0x96, 0x29, 0x92, 0xFC, 0xC0, 0x03, 0xD9, 0x96, + 0x29, 0xD8, 0xA2, 0xDE, 0xF8, 0x86, 0x91, 0xA6, + 0x21, 0xDB, 0x8B, 0x61, 0xA2, 0xDE, 0xB3, 0x86, + 0xA4, 0xC0, 0xD8, 0xF3, 0xBB, 0xB3, 0xB7, 0xA2, + 0xF8, 0xF2, 0xF8, 0xF1, 0x80, 0x9D, 0xAD, 0xD0, + 0x7C, 0xF2, 0xA2, 0xFA, 0xF9, 0xD1, 0xF1, 0xB9, + 0xAC, 0xD9, 0xDE, 0xDA, 0xF8, 0xD8, 0xF2, 0xA6, + 0x82, 0x92, 0x49, 0xF9, 0xDB, 0xF1, 0xB1, 0x8C, + 0xB5, 0x9C, 0x21, 0xD9, 0xF5, 0xB3, 0x85, 0xB7, + 0x95, 0x78, 0x8E, 0x9E, 0x7C, 0xF1, 0xB1, 0x8D, + 0xB5, 0x9D, 0xAD, 0x1A, 0xF0, 0x96, 0x40, 0x9D, + 0x3C, 0x96, 0x48, 0xD8, 0xF1, 0xB1, 0x8E, 0xB5, + 0x9D, 0xB9, 0xA6, 0x2A, 0x8D, 0x96, 0x05, 0xD9, + 0xF4, 0x1A, 0x23, 0xD8, 0xF2, 0xB3, 0x82, 0xB7, + /* bank 25: 0x1900 */ + 0x92, 0xBB, 0xAF, 0x49, 0xF9, 0xF9, 0xDB, 0xF1, + 0xB1, 0x8C, 0xB5, 0x9C, 0xB9, 0xA6, 0x21, 0xF4, + 0x1A, 0x23, 0xD8, 0xF1, 0xB3, 0x8E, 0xBB, 0xA8, + 0xD0, 0xC4, 0xC7, 0xF3, 0xB9, 0xAC, 0xD0, 0xDE, + 0xF4, 0x1A, 0x34, 0xD8, 0xF1, 0xB3, 0x85, 0xBB, + 0xA8, 0xD0, 0xC4, 0xC7, 0xF3, 0xB9, 0xAC, 0xD0, + 0xDE, 0xF8, 0xDF, 0xF8, 0xD8, 0xF3, 0xB5, 0x9C, + 0xFC, 0xC3, 0x04, 0xDB, 0xFC, 0xC2, 0x00, 0xD9, + 0xF2, 0xAC, 0xD0, 0xDE, 0xD8, 0xF2, 0xBB, 0xAF, + 0xB7, 0x92, 0xB3, 0x82, 0x19, 0x80, 0xA2, 0xD9, + 0x26, 0xF3, 0xA7, 0xD0, 0xDF, 0xD8, 0xF1, 0xAF, + 0x89, 0x98, 0x19, 0xA9, 0x80, 0xD9, 0x38, 0xD8, + 0xAF, 0x89, 0x39, 0xA9, 0x80, 0xDA, 0x3C, 0xD8, + 0xAF, 0x2E, 0x88, 0xF5, 0x75, 0xDA, 0xFF, 0xD8, + 0x71, 0xDA, 0xF1, 0xFF, 0xD8, 0x82, 0xA7, 0xF3, + 0xC1, 0xF2, 0x80, 0xC2, 0xF1, 0x97, 0x86, 0x49, + 0x2E, 0xA6, 0xD0, 0x50, 0x96, 0x86, 0xAF, 0x75, + 0xD9, 0x88, 0xA2, 0xD0, 0xF3, 0xC0, 0xC3, 0xF1, + 0xDA, 0x8F, 0x96, 0xA2, 0xD0, 0xF3, 0xC2, 0xC3, + 0x82, 0xB6, 0x9B, 0x78, 0x78, 0xF1, 0xD8, 0xB7, + 0xAF, 0xDF, 0xF9, 0x89, 0x99, 0xAF, 0x10, 0x80, + 0x9F, 0x21, 0xDA, 0x2E, 0xD8, 0x89, 0x99, 0xAF, + 0x31, 0xDA, 0xDF, 0xD8, 0xAF, 0x82, 0x92, 0xF3, + 0x41, 0xD9, 0xF1, 0xDF, 0xD8, 0xAF, 0x82, 0xF3, + 0x19, 0xD9, 0xF1, 0xDF, 0xD8, 0xF1, 0x89, 0x90, + 0xAF, 0xD0, 0x09, 0x8F, 0x99, 0xAF, 0x51, 0xDB, + 0x89, 0x31, 0xF3, 0x82, 0x92, 0x19, 0xF2, 0xB1, + 0x8C, 0xB5, 0x9C, 0x71, 0xD9, 0xF1, 0xDF, 0xF9, + 0xF2, 0xB9, 0xAC, 0xD0, 0xF8, 0xF8, 0xF3, 0xDF, + 0xD8, 0xB3, 0xB7, 0xBB, 0x82, 0xAC, 0xF3, 0xC0, + 0xA2, 0x80, 0x22, 0xF1, 0xA9, 0x22, 0x26, 0x9F, + 0xAF, 0x29, 0xDA, 0xAC, 0xDE, 0xFF, 0xD8, 0xA2, + /* bank 26: 0x1A00 */ + 0xF2, 0xDE, 0xF1, 0xA9, 0xDF, 0xB5, 0x92, 0xFC, + 0xC0, 0x00, 0xD9, 0xFF, 0xD8, 0xAD, 0xD0, 0xDE, + 0xF8, 0xB1, 0x84, 0xB6, 0x96, 0xBA, 0xA7, 0xD0, + 0x7E, 0xB7, 0x96, 0xA7, 0x01, 0xB2, 0x87, 0x9D, + 0x05, 0xDB, 0xB3, 0x8D, 0xB6, 0x97, 0x79, 0xF3, + 0xB1, 0x8C, 0x96, 0x49, 0xF1, 0xBB, 0xAD, 0xD0, + 0xF8, 0xD8, 0xF3, 0xB9, 0xAC, 0xD0, 0xF8, 0xF9, + 0xD1, 0xD9, 0xF1, 0xBB, 0xAD, 0xD0, 0xF8, 0xD8, + 0xB3, 0xB7, 0xBB, 0x97, 0x8C, 0xAF, 0xF3, 0x79, + 0xD9, 0xF4, 0x1B, 0x6D, 0xD8, 0xF1, 0xB1, 0x82, + 0xB9, 0xA2, 0xD0, 0xC2, 0xB3, 0xF2, 0xB9, 0xA3, + 0xFA, 0xF1, 0xBB, 0xAA, 0xD0, 0xF8, 0xB8, 0xB0, + 0xB4, 0xA7, 0x88, 0x9C, 0xF7, 0x72, 0xF9, 0xF4, + 0xDA, 0x44, 0xD8, 0x1B, 0x80, 0xD8, 0xF3, 0xB3, + 0xB7, 0xBB, 0xA7, 0xD0, 0xFA, 0x97, 0x8C, 0xAF, + 0x79, 0xDA, 0xF1, 0x87, 0x9A, 0xAA, 0xD0, 0x70, + 0xD8, 0xF2, 0xBB, 0xB3, 0xB7, 0x82, 0x92, 0xAF, + 0x31, 0xDA, 0xF4, 0x1B, 0xBD, 0xD8, 0xF1, 0x8D, + 0x96, 0xA6, 0x40, 0xAC, 0x8C, 0x9C, 0x0C, 0x30, + 0xBA, 0x8D, 0x9D, 0xA7, 0x39, 0xDB, 0xF3, 0xB1, + 0x8C, 0xB6, 0x96, 0x49, 0xD9, 0xF1, 0x84, 0xB5, + 0x94, 0xB9, 0xA4, 0xD0, 0x5E, 0xF0, 0xB7, 0x9D, + 0x38, 0xD8, 0xF1, 0xBB, 0xAC, 0xDE, 0xD0, 0xDE, + 0xAD, 0xD0, 0xDF, 0xF1, 0xFF, 0xD8, 0xF3, 0xB9, + 0xAC, 0xD0, 0xF8, 0xF9, 0xD1, 0xD9, 0xF2, 0xBB, + 0xA2, 0xFA, 0xF8, 0xDA, 0xF2, 0xBB, 0xA2, 0xFA, + 0xD8, 0xF2, 0xBB, 0x82, 0xAF, 0xC2, 0xF9, 0xD1, + 0xD9, 0xF1, 0xB9, 0xAC, 0xDE, 0xAD, 0xDE, 0xDF, + 0xD8, 0xF1, 0x8C, 0x9C, 0xBB, 0xAC, 0xD0, 0x10, + 0xAC, 0xDE, 0xAD, 0xD0, 0xDF, 0x92, 0x82, 0xAF, + 0xF1, 0xCA, 0xF2, 0x35, 0xF1, 0x96, 0x8F, 0xA6, + 0xD9, 0x00, 0xD8, 0xF1, 0xFF, + /* bank 27: 0x1B00 */ +}; #endif /* ICM_DMP_FW_VER */ struct nvi_dmp nvi_dmp_icm = { @@ -2930,6 +4051,7 @@ struct nvi_dmp nvi_dmp_icm = { .fw_mem_addr = 0x90, .fw_start = 0x08D0, .dmp_reset_delay_ms = 25, + .fifo_mode = ICM_DMP_FIFO_MODE, .dev_msk = ICM_DMP_DEV_MSK, .en_msk = MSK_DEV_ALL, .dd_n = ARRAY_SIZE(nvi_dmp_devs), diff --git a/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.h b/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.h index 1cc205d3a67..0dc0329998e 100644 --- a/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.h +++ b/drivers/iio/imu/nvi_mpu/nvi_dmp_icm.h @@ -15,21 +15,28 @@ /* Invensense doesn't label their DMP FW with a version so we use * ICM_DMP_FW_VER sequentially starting at 0. - * Currently a version 0 or 1 is the option here as both are included in this - * driver. Typically version 0 would be used although 1 is the latest. + * Currently a version 0, 1 or 2 is the option here as all are included in + * this driver. Version 2 is recommended that includes timing fixes. */ -#define ICM_DMP_FW_VER (0) +#define ICM_DMP_FW_VER (2) #if ICM_DMP_FW_VER == 0 #define ICM_DMP_FW_CRC32 (0x12F362A6) -#else +#define ICM_DMP_FIFO_MODE (0) +#define ICM_SMD_TIMER_THLD_INIT (0x00000258) +#elif ICM_DMP_FW_VER == 1 #define ICM_DMP_FW_CRC32 (0xFEF1270D) +#define ICM_DMP_FIFO_MODE (0) +#define ICM_SMD_TIMER_THLD_INIT (0x0000015E) +#else /* ICM_DMP_FW_VER == 2 */ +#define ICM_DMP_FW_CRC32 (0xDA126847) +#define ICM_DMP_FIFO_MODE (-1) +#define ICM_SMD_TIMER_THLD_INIT (0x0000015E) #endif /* ICM_DMP_FW_VER */ #define ICM_DMP_FREQ (102) #define ICM_DMP_PERIOD_US (9804) #define ICM_BASE_SAMPLE_RATE (1125) #define ICM_DMP_DIVIDER (ICM_BASE_SAMPLE_RATE / ICM_DMP_FREQ) -#define ICM_SMD_TIMER_THLD_INIT (0x0000015E) #define DATA_OUT_CTL1 (4 * 16) /* 0x0040 */ #define DATA_OUT_CTL2 (4 * 16 + 2) /* 0x0042 */ @@ -138,11 +145,18 @@ #define PEDSTD_DRIVE_STATE (43 * 16 + 10) #define PED_RATE (58 * 16 + 4) /* 0x03A4 */ +/* FW verison 0 */ #define SMD_MOT_THLD (72 * 16 + 12) /* 0x048C */ #define SMD_DELAY_THLD (76 * 16 + 8) /* 0x04C8 */ #define SMD_DELAY2_THLD (76 * 16 + 12) /* 0x04CC */ - +/* FW version 1 */ #define SMD_TIMER_THLD (26 * 16) /* 0x01A0 */ +/* FW version 2 */ +#define SMD_E1_THLD (75 * 16 + 8) /* 0x04B8 */ +#define SMD_CNTR_TH (74 * 16 + 8) /* 0x04A8 */ +#define SMD_CNTR_LO_TH (74 * 16 + 12) /* 0x04AC */ +#define SMD_LOW_ENERGY_TIMER_TH (76 * 16 + 8) /* 0x04C8 */ +#define SMD_E1_COUNTER_TH (76 * 16 + 12) /* 0x04CC */ #define WOM_ENABLE (64 * 16 + 14) /* 0x040E */ #define WOM_STATUS (64 * 16 + 6) /* 0x0406 */ @@ -152,19 +166,8 @@ #define TILT_ENABLE (68 * 16 + 12) #define BAC_STATE (147 * 16) -#define ACCEL_MASK 0x80 -#define GYRO_MASK 0x40 -#define CPASS_MASK 0x20 -#define ALS_MASK 0x10 -#define QUAT6_MASK 0x08 -#define QUAT9_MASK 0x04 -#define PQUAT6_MASK 0x02 -#define PRESSURE_MASK 0x80 -#define GYRO_CALIBR_MASK 0x40 -#define CPASS_CALIBR_MASK 0x20 -#define PED_STEPDET_MASK 0x10 -#define HEADER2_MASK 0x08 -#define PED_STEPIND_MASK 0x07 +#define ACC_SCALE (30 * 16 + 0) /* 0x01E0 */ +#define ACC_SCALE2 (79 * 16 + 4) /* 0x04F4 */ #define ACCEL_SET 0x8000 #define GYRO_SET 0x4000 @@ -180,13 +183,6 @@ #define HEADER2_SET 0x0008 #define PED_STEPIND_SET 0x0007 -#define ACCEL_ACCURACY_MASK 0x4000 -#define GYRO_ACCURACY_MASK 0x2000 -#define CPASS_ACCURACY_MASK 0x1000 -#define GEOMAG_MASK 0x0200 -#define BATCH_MODE_MASK 0x0100 -#define ACT_RECOG_MASK 0x8000 - #define ACCEL_ACCURACY_SET 0x4000 #define GYRO_ACCURACY_SET 0x2000 #define CPASS_ACCURACY_SET 0x1000 diff --git a/drivers/iio/imu/nvi_mpu/nvi_icm.c b/drivers/iio/imu/nvi_mpu/nvi_icm.c index 9aa7f43d9c9..044db1b84e0 100644 --- a/drivers/iio/imu/nvi_mpu/nvi_icm.c +++ b/drivers/iio/imu/nvi_mpu/nvi_icm.c @@ -405,8 +405,8 @@ static int inv_icm_st_acc_do(struct nvi_state *st, } accel_s = 0; ret = inv_icm_st_rd(st, DEV_ACC, accel_result, &accel_s); - if (ret) - return ret; + if (ret || accel_s <= 0) + return -1; for (j = 0; j < AXIS_N; j++) { accel_result[j] = accel_result[j] / accel_s; @@ -422,8 +422,8 @@ static int inv_icm_st_acc_do(struct nvi_state *st, msleep(ICM_ST_STABLE_TIME); accel_s = 0; ret = inv_icm_st_rd(st, DEV_ACC, accel_st_result, &accel_s); - if (ret) - return ret; + if (ret || accel_s <= 0) + return -1; for (j = 0; j < AXIS_N; j++) { accel_st_result[j] = accel_st_result[j] / accel_s; @@ -453,8 +453,8 @@ static int inv_icm_st_gyr_do(struct nvi_state *st, } gyro_s = 0; ret = inv_icm_st_rd(st, DEV_GYR, gyro_result, &gyro_s); - if (ret) - return ret; + if (ret || gyro_s <= 0) + return -1; for (j = 0; j < AXIS_N; j++) { gyro_result[j] = gyro_result[j] / gyro_s; @@ -470,8 +470,8 @@ static int inv_icm_st_gyr_do(struct nvi_state *st, msleep(ICM_ST_STABLE_TIME); gyro_s = 0; ret = inv_icm_st_rd(st, DEV_GYR, gyro_st_result, &gyro_s); - if (ret) - return ret; + if (ret || gyro_s <= 0) + return -1; for (j = 0; j < AXIS_N; j++) { gyro_st_result[j] = gyro_st_result[j] / gyro_s; @@ -628,9 +628,7 @@ static int nvi_init_icm(struct nvi_state *st) int ret; st->snsr[DEV_ACC].cfg.thresh_hi = 0; /* no ACC LP on ICM */ -#if ICM_DMP_FW_VER == 1 st->snsr[DEV_SM].cfg.thresh_hi = ICM_SMD_TIMER_THLD_INIT; -#endif /* ICM_DMP_FW_VER */ ret = nvi_i2c_rd(st, &st->hal->reg->tbc_pll, &val); if (ret) return ret; @@ -650,16 +648,7 @@ static int nvi_init_icm(struct nvi_state *st) return 0; } -static void nvi_por2rc_icm(struct nvi_state *st) -{ - st->rc.lp_config = 0x40; - st->rc.pm1 = 0x41; - st->rc.gyro_config1 = 0x01; - st->rc.accel_config = 0x01; -} - struct nvi_fn nvi_fn_icm = { - .por2rc = nvi_por2rc_icm, .pm = nvi_pm_icm, .init = nvi_init_icm, .st_acc = inv_st_acc_icm,