diff options
author | Tom Cherry <tcherry@nvidia.com> | 2012-05-23 12:06:13 -0700 |
---|---|---|
committer | Tom Cherry <tcherry@nvidia.com> | 2012-05-23 12:06:13 -0700 |
commit | a168c03bd97fd9761218779623db0cec09fa8f4a (patch) | |
tree | 521d2b51904da963d771c24fd9b142cc416f8259 /drivers/media | |
parent | 11fb7d0e35d56230919eb91bee1aa138a10b8416 (diff) | |
parent | c7e3189c1802c2a6552eec960f521a1891529892 (diff) |
Merge commit 'main-ics-2012.05.22-B3' into HEAD
Conflicts:
arch/arm/mach-tegra/pm.c
drivers/media/video/tegra/nvavp/nvavp_dev.c
drivers/power/smb349-charger.c
include/linux/smb349-charger.h
include/trace/events/power.h
Change-Id: Ia8c82e2acfe3463ae6778bdd03aac8da104f7ad3
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/tegra/Kconfig | 7 | ||||
-rw-r--r-- | drivers/media/video/tegra/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/video/tegra/ad5820.c | 2 | ||||
-rw-r--r-- | drivers/media/video/tegra/ar0832_main.c | 9 | ||||
-rw-r--r-- | drivers/media/video/tegra/avp/avp.c | 2 | ||||
-rw-r--r-- | drivers/media/video/tegra/avp/avp_svc.c | 2 | ||||
-rw-r--r-- | drivers/media/video/tegra/nvavp/nvavp_dev.c | 48 | ||||
-rw-r--r-- | drivers/media/video/tegra/ov14810.c | 2 | ||||
-rw-r--r-- | drivers/media/video/tegra/ov2710.c | 2 | ||||
-rw-r--r-- | drivers/media/video/tegra/ov5640.c | 491 | ||||
-rw-r--r-- | drivers/media/video/tegra/ov5640_tables.h | 4582 | ||||
-rw-r--r-- | drivers/media/video/tegra/ov5650.c | 98 | ||||
-rw-r--r-- | drivers/media/video/tegra/ov9726.c | 1 | ||||
-rw-r--r-- | drivers/media/video/tegra/sh532u.c | 871 | ||||
-rw-r--r-- | drivers/media/video/tegra/soc380.c | 1 | ||||
-rw-r--r-- | drivers/media/video/tegra/tegra_camera.c | 306 |
16 files changed, 5872 insertions, 553 deletions
diff --git a/drivers/media/video/tegra/Kconfig b/drivers/media/video/tegra/Kconfig index 404d771a717e..f5aea996e2d6 100644 --- a/drivers/media/video/tegra/Kconfig +++ b/drivers/media/video/tegra/Kconfig @@ -27,6 +27,13 @@ config VIDEO_OV5650 This is a driver for the Omnivision OV5650 5MP camera sensor for use with the tegra isp. +config VIDEO_OV5640 + tristate "OV5640 camera sensor support" + depends on I2C && ARCH_TEGRA + ---help--- + This is a driver for the Omnivision OV5640 5MP camera sensor + for use with the tegra isp. + config VIDEO_OV14810 tristate "OV14810 camera sensor support" depends on I2C && ARCH_TEGRA diff --git a/drivers/media/video/tegra/Makefile b/drivers/media/video/tegra/Makefile index 5d404e44fd20..08b81e261611 100644 --- a/drivers/media/video/tegra/Makefile +++ b/drivers/media/video/tegra/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_TEGRA_DTV) += tegra_dtv.o obj-$(CONFIG_TEGRA_CAMERA) += tegra_camera.o obj-$(CONFIG_VIDEO_AR0832) += ar0832_main.o obj-$(CONFIG_VIDEO_OV5650) += ov5650.o +obj-$(CONFIG_VIDEO_OV5640) += ov5640.o obj-$(CONFIG_VIDEO_OV14810) += ov14810.o obj-$(CONFIG_VIDEO_OV9726) += ov9726.o obj-$(CONFIG_VIDEO_OV2710) += ov2710.o diff --git a/drivers/media/video/tegra/ad5820.c b/drivers/media/video/tegra/ad5820.c index 19d35bca5b0b..adfda3e712dc 100644 --- a/drivers/media/video/tegra/ad5820.c +++ b/drivers/media/video/tegra/ad5820.c @@ -228,4 +228,4 @@ static void __exit ad5820_exit(void) module_init(ad5820_init); module_exit(ad5820_exit); - +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/ar0832_main.c b/drivers/media/video/tegra/ar0832_main.c index 129825cd5f83..f3b56bbf847e 100644 --- a/drivers/media/video/tegra/ar0832_main.c +++ b/drivers/media/video/tegra/ar0832_main.c @@ -738,7 +738,7 @@ static struct ar0832_reg mode_1920X1080_8140[] = { {0x3178, 0x0000}, /* RESERVED_MFR_3178 */ {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */ - {0x0342, 0x103B}, /* LINE_LENGTH_PCK */ + {0x0342, 0x1139}, /* LINE_LENGTH_PCK */ {0x0340, 0x05C4}, /* FRAME_LENGTH_LINES */ {0x0202, 0x05C4}, /* COARSE_INTEGRATION_TIME */ {0x3014, 0x0702}, /* FINE_INTEGRATION_TIME */ @@ -863,7 +863,7 @@ static struct ar0832_reg mode_1920X1080_8141[] = { {0x3178, 0x0000}, /* RESERVED_MFR_3178 */ {0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */ - {0x0342, 0x103B}, /* LINE_LENGTH_PCK */ + {0x0342, 0x1139}, /* LINE_LENGTH_PCK */ {0x0340, 0x05C4}, /* FRAME_LENGTH_LINES */ {0x0202, 0x05C4}, /* COARSE_INTEGRATION_TIME */ {0x3014, 0x0702}, /* FINE_INTEGRATION_TIME */ @@ -1977,7 +1977,7 @@ static int ar0832_focuser_set_position(struct ar0832_dev *dev, return ret; } - +#ifdef AR0832_FOCUSER_DYNAMIC_STEP_TIME /* * This function is not currently called as we have the hardcoded * step time in ar0832_focuser_set_config function. If we need to @@ -2033,6 +2033,7 @@ static u16 ar0832_get_focuser_vcm_step_time(struct ar0832_dev *dev) return vt_pix_clk_freq_mhz; } +#endif static inline int ar0832_get_sensorid(struct ar0832_dev *dev, u16 *sensor_id) @@ -2148,7 +2149,6 @@ static long ar0832_ioctl(struct file *file, } case AR0832_IOCTL_SET_SENSOR_REGION: { - struct ar0832_stereo_region region; dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_SENSOR_REGION\n"); /* Right now, it doesn't do anything */ @@ -2547,3 +2547,4 @@ static void __exit ar0832_exit(void) module_init(ar0832_init); module_exit(ar0832_exit); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/avp/avp.c b/drivers/media/video/tegra/avp/avp.c index 074a42f125be..fc965e4f5b53 100644 --- a/drivers/media/video/tegra/avp/avp.c +++ b/drivers/media/video/tegra/avp/avp.c @@ -42,7 +42,7 @@ #include <mach/clk.h> #include <mach/io.h> #include <mach/iomap.h> -#include <mach/nvmap.h> +#include <linux/nvmap.h> #include <mach/legacy_irq.h> #include <mach/hardware.h> diff --git a/drivers/media/video/tegra/avp/avp_svc.c b/drivers/media/video/tegra/avp/avp_svc.c index 17c8b8535a62..1e8219943b4a 100644 --- a/drivers/media/video/tegra/avp/avp_svc.c +++ b/drivers/media/video/tegra/avp/avp_svc.c @@ -29,7 +29,7 @@ #include <linux/types.h> #include <mach/clk.h> -#include <mach/nvmap.h> +#include <linux/nvmap.h> #include "../../../../video/tegra/nvmap/nvmap.h" diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c index 4627c514622a..012f50b7a5f4 100644 --- a/drivers/media/video/tegra/nvavp/nvavp_dev.c +++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c @@ -40,9 +40,8 @@ #include <mach/io.h> #include <mach/iomap.h> #include <mach/legacy_irq.h> -#include <mach/nvmap.h> +#include <linux/nvmap.h> -#include "../../../../video/tegra/nvmap/nvmap.h" #include "../../../../video/tegra/host/host1x/host1x_syncpt.h" #include "../../../../video/tegra/host/dev.h" #include "../../../../video/tegra/host/nvhost_acm.h" @@ -118,6 +117,7 @@ struct nvavp_info { struct nvhost_device *nvhost_dev; struct miscdevice misc_dev; + atomic_t clock_stay_on_refcount; }; struct nvavp_clientctx { @@ -127,7 +127,7 @@ struct nvavp_clientctx { struct nvmap_handle_ref *gather_mem; int num_relocs; struct nvavp_info *nvavp; - u32 clk_reqs; + int clock_stay_on; }; static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id) @@ -176,7 +176,8 @@ static void nvavp_clks_disable(struct nvavp_info *nvavp) static u32 nvavp_check_idle(struct nvavp_info *nvavp) { struct nv_e276_control *control = nvavp->os_control; - return (control->put == control->get) ? 1 : 0; + return ((control->put == control->get) + && (!atomic_read(&nvavp->clock_stay_on_refcount))) ? 1 : 0; } static void clock_disable_handler(struct work_struct *work) @@ -1061,15 +1062,16 @@ static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd, return -EINVAL; } - mutex_lock(&nvavp->open_lock); - if (clock.state) { - if (clientctx->clk_reqs++ == 0) - nvavp_clks_enable(nvavp); - } else { - if (--clientctx->clk_reqs == 0) - nvavp_clks_disable(nvavp); - } - mutex_unlock(&nvavp->open_lock); + if (clientctx->clock_stay_on == clock.state) + return 0; + + clientctx->clock_stay_on = clock.state; + + if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED) + atomic_inc(&nvavp->clock_stay_on_refcount); + else if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_DISABLED) + atomic_dec(&nvavp->clock_stay_on_refcount); + return 0; } @@ -1098,6 +1100,7 @@ static int tegra_nvavp_open(struct inode *inode, struct file *filp) clientctx->nvmap = nvavp->nvmap; clientctx->nvavp = nvavp; + clientctx->clock_stay_on = NVAVP_CLOCK_STAY_ON_DISABLED; filp->private_data = clientctx; @@ -1125,10 +1128,8 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp) goto out; } - /* if this client had any requests, drop our clk ref */ - if (clientctx->clk_reqs) - nvavp_clks_disable(nvavp); - + if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED) + atomic_dec(&nvavp->clock_stay_on_refcount); if (nvavp->refcount > 0) nvavp->refcount--; if (!nvavp->refcount) @@ -1187,7 +1188,8 @@ static const struct file_operations tegra_nvavp_fops = { .unlocked_ioctl = tegra_nvavp_ioctl, }; -static int tegra_nvavp_probe(struct nvhost_device *ndev) +static int tegra_nvavp_probe(struct nvhost_device *ndev, + struct nvhost_device_id *id_table) { struct nvavp_info *nvavp; int irq; @@ -1234,17 +1236,7 @@ static int tegra_nvavp_probe(struct nvhost_device *ndev) switch (heap_mask) { case NVMAP_HEAP_IOVMM: -#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000 - iovmm_addr = 0xeff00000; -#else iovmm_addr = 0x0ff00000; -#endif - - /* Tegra3 A01 has different SMMU address */ - if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 - && tegra_get_revision() == TEGRA_REVISION_A01) { - iovmm_addr = 0xeff00000; - } nvavp->os_info.handle = nvmap_alloc_iovm(nvavp->nvmap, SZ_1M, L1_CACHE_BYTES, diff --git a/drivers/media/video/tegra/ov14810.c b/drivers/media/video/tegra/ov14810.c index 2efd283b32b5..8a72cd7aae89 100644 --- a/drivers/media/video/tegra/ov14810.c +++ b/drivers/media/video/tegra/ov14810.c @@ -1387,4 +1387,4 @@ static void __exit ov14810_exit(void) module_init(ov14810_init); module_exit(ov14810_exit); - +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/ov2710.c b/drivers/media/video/tegra/ov2710.c index a2e02369d8e3..5e8eaa123124 100644 --- a/drivers/media/video/tegra/ov2710.c +++ b/drivers/media/video/tegra/ov2710.c @@ -687,4 +687,4 @@ static void __exit ov2710_exit(void) module_init(ov2710_init); module_exit(ov2710_exit); - +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/ov5640.c b/drivers/media/video/tegra/ov5640.c new file mode 100644 index 000000000000..b20c036bb06c --- /dev/null +++ b/drivers/media/video/tegra/ov5640.c @@ -0,0 +1,491 @@ +/* + * ov5640.c - ov5640 sensor driver + * + * Copyright (c) 2011 - 2012, NVIDIA, All Rights Reserved. + * + * Contributors: + * Abhinav Sinha <absinha@nvidia.com> + * + * Leverage soc380.c + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/** + * SetMode Sequence for 640x480. Phase 0. Sensor Dependent. + * This sequence should put sensor in streaming mode for 640x480 + * This is usually given by the FAE or the sensor vendor. + */ + +#include <linux/delay.h> +#include <linux/fs.h> +#include <linux/i2c.h> +#include <linux/miscdevice.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include <media/ov5640.h> + +#include "ov5640_tables.h" + +/* Focuser single step & full scale transition time truth table + * in the format of: + * index mode single step transition full scale transition + * 0 0 0 0 + * 1 1 50uS 51.2mS + * 2 1 100uS 102.3mS + * 3 1 200uS 204.6mS + * 4 1 400uS 409.2mS + * 5 1 800uS 818.4mS + * 6 1 1600uS 1637.0mS + * 7 1 3200uS 3274.0mS + * 8 0 0 0 + * 9 2 50uS 1.1mS + * A 2 100uS 2.2mS + * B 2 200uS 4.4mS + * C 2 400uS 8.8mS + * D 2 800uS 17.6mS + * E 2 1600uS 35.2mS + * F 2 3200uS 70.4mS + */ + +/* pick up the mode index setting and its settle time from the above table */ +#define OV5640_VCM_DACMODE 0x3602 +#define OV5640_TRANSITION_MODE 0x0B +#define SETTLETIME_MS 5 + +#define POS_LOW (0) +#define POS_HIGH (1023) +#define FPOS_COUNT 1024 +#define FOCAL_LENGTH (10.0f) +#define FNUMBER (2.8f) + +#define SIZEOF_I2C_TRANSBUF 64 + +struct ov5640_info { + int mode; + struct miscdevice miscdev_info; + struct i2c_client *i2c_client; + struct ov5640_platform_data *pdata; + struct ov5640_config focuser; + int af_fw_loaded; + struct kobject *kobj; + struct device *dev; + u8 i2c_trans_buf[SIZEOF_I2C_TRANSBUF]; +}; + +static int ov5640_read_reg(struct i2c_client *client, u16 addr, u8 *val) +{ + int err; + struct i2c_msg msg[2]; + unsigned char data[3]; + + if (!client->adapter) + return -ENODEV; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].len = 2; + msg[0].buf = data; + + /* high byte goes out first */ + data[0] = (u8) (addr >> 8); + data[1] = (u8) (addr & 0xff); + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = 1; + msg[1].buf = data + 2; + + err = i2c_transfer(client->adapter, msg, 2); + + if (err != 2) + return -EINVAL; + + *val = data[2]; + + return 0; +} + +static int ov5640_write_reg(struct i2c_client *client, u8 addr, u8 value) +{ + int count; + struct i2c_msg msg[1]; + unsigned char data[4]; + + if (!client->adapter) + return -ENODEV; + + data[0] = addr; + data[1] = (u8) (addr & 0xff); + data[2] = value; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].len = 3; + msg[0].buf = data; + + count = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (count == ARRAY_SIZE(msg)) + return 0; + dev_err(&client->dev, + "ov5840: i2c transfer failed, addr: %x, value: %02x\n", + addr, (u32)value); + return -EIO; +} + +static int ov5640_write_bulk_reg(struct i2c_client *client, u8 *data, int len) +{ + int err; + struct i2c_msg msg; + + if (!client->adapter) + return -ENODEV; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = len; + msg.buf = data; + + err = i2c_transfer(client->adapter, &msg, 1); + if (err == 1) + return 0; + + dev_err(&client->dev, "ov5640: i2c transfer failed at %x\n", + (int)data[0] << 8 | data[1]); + + return err; +} + +static int ov5640_write_table(struct ov5640_info *info, + struct ov5640_reg table[], + struct ov5640_reg override_list[], + int num_override_regs) +{ + int err; + struct ov5640_reg *next, *n_next; + u8 *b_ptr = info->i2c_trans_buf; + unsigned int buf_filled = 0; + int i; + u16 val; + + for (next = table; next->addr != OV5640_TABLE_END; next++) { + if (next->addr == OV5640_TABLE_WAIT_MS) { + msleep(next->val); + continue; + } + + val = next->val; + + /* When an override list is passed in, replace the reg */ + /* value to write if the reg is in the list */ + if (override_list) { + for (i = 0; i < num_override_regs; i++) { + if (next->addr == override_list[i].addr) { + val = override_list[i].val; + break; + } + } + } + + if (!buf_filled) { + b_ptr = info->i2c_trans_buf; + *b_ptr++ = next->addr >> 8; + *b_ptr++ = next->addr & 0xff; + buf_filled = 2; + } + *b_ptr++ = val; + buf_filled++; + + n_next = next + 1; + if (n_next->addr != OV5640_TABLE_END && + n_next->addr != OV5640_TABLE_WAIT_MS && + buf_filled < SIZEOF_I2C_TRANSBUF && + n_next->addr == next->addr + 1) { + continue; + } + + err = ov5640_write_bulk_reg(info->i2c_client, + info->i2c_trans_buf, buf_filled); + if (err) + return err; + + buf_filled = 0; + } + return 0; +} + +static int ov5640_set_mode(struct ov5640_info *info, struct ov5640_mode *mode) +{ + int sensor_mode; + int err; + + dev_info(info->dev, "%s: xres %u yres %u\n", + __func__, mode->xres, mode->yres); + if (!info->af_fw_loaded) { + err = ov5640_write_table(info, tbl_af_firmware, NULL, 0); + if (err) + return err; + info->af_fw_loaded = 1; + } + + if (mode->xres == 2592 && mode->yres == 1944) + sensor_mode = OV5640_MODE_2592x1944; + else if (mode->xres == 1920 && mode->yres == 1080) + sensor_mode = OV5640_MODE_1920x1080; + else if (mode->xres == 1296 && mode->yres == 964) + sensor_mode = OV5640_MODE_1296x972; + else { + dev_info(info->dev, "%s: invalid resolution: %d %d\n", + __func__, mode->xres, mode->yres); + return -EINVAL; + } + + err = ov5640_write_table(info, mode_table[sensor_mode], + NULL, 0); + if (err) + return err; + + info->mode = sensor_mode; + return 0; +} + +static int ov5640_set_af_mode(struct ov5640_info *info, u8 mode) +{ + dev_info(info->dev, "%s: mode %d\n", __func__, mode); + if (mode == OV5640_AF_INIFINITY) + return ov5640_write_table(info, tbl_release_focus, NULL, 0); + + if (mode == OV5640_AF_TRIGGER) + return ov5640_write_table(info, tbl_single_focus, NULL, 0); + + return -EINVAL; +} + +static int ov5640_get_af_status(struct ov5640_info *info, u8 *val) +{ + int err; + + err = ov5640_read_reg(info->i2c_client, 0x3023, val); + if (err) + return -EINVAL; + + dev_info(info->dev, "%s: value %02x\n", __func__, (u32)val); + return 0; +} + +static int ov5640_set_position(struct ov5640_info *info, u32 position) +{ + u8 data[4]; + + if (position < info->focuser.pos_low || + position > info->focuser.pos_high) + return -EINVAL; + + data[0] = (OV5640_VCM_DACMODE >> 8) & 0xff; + data[1] = OV5640_VCM_DACMODE & 0xff; + data[2] = ((position & 0xf) << 4) | OV5640_TRANSITION_MODE; + data[3] = (position * 0x3f0) >> 4; + return ov5640_write_bulk_reg(info->i2c_client, data, 4); +} + +static int ov5640_set_power(struct ov5640_info *info, u32 level) +{ + switch (level) { + case OV5640_POWER_LEVEL_OFF: + case OV5640_POWER_LEVEL_SUS: + if (info->pdata && info->pdata->power_off) + info->pdata->power_off(); + info->af_fw_loaded = 0; + info->mode = 0; + break; + case OV5640_POWER_LEVEL_ON: + if (info->pdata && info->pdata->power_on) + info->pdata->power_on(); + break; + default: + dev_err(info->dev, "unknown power level %d.\n", level); + return -EINVAL; + } + + return 0; +} + +static long ov5640_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct ov5640_info *info = file->private_data; + + switch (cmd) { + case OV5640_IOCTL_SET_SENSOR_MODE: + { + struct ov5640_mode mode; + if (copy_from_user(&mode, + (const void __user *)arg, + sizeof(struct ov5640_mode))) { + return -EFAULT; + } + + return ov5640_set_mode(info, &mode); + } + case OV5640_IOCTL_GET_CONFIG: + { + if (copy_to_user((void __user *) arg, + &info->focuser, + sizeof(info->focuser))) { + dev_err(info->dev, "%s: 0x%x\n", __func__, __LINE__); + return -EFAULT; + } + + break; + } + case OV5640_IOCTL_GET_AF_STATUS: + { + int err; + u8 val; + + if (!info->af_fw_loaded) { + dev_err(info->dev, "OV5640 AF fw not loaded!\n"); + break; + } + + err = ov5640_get_af_status(info, &val); + if (err) + return err; + + if (copy_to_user((void __user *) arg, + &val, sizeof(val))) { + dev_err(info->dev, "%s: 0x%x\n", __func__, __LINE__); + return -EFAULT; + } + break; + } + case OV5640_IOCTL_SET_AF_MODE: + if (!info->af_fw_loaded) { + dev_err(info->dev, "OV5640 AF fw not loaded!\n"); + break; + } + return ov5640_set_af_mode(info, (u8)arg); + case OV5640_IOCTL_POWER_LEVEL: + return ov5640_set_power(info, (u32)arg); + case OV5640_IOCTL_SET_FPOSITION: + return ov5640_set_position(info, (u32)arg); + case OV5640_IOCTL_GET_SENSOR_STATUS: + { + u8 status = 0; + if (copy_to_user((void __user *)arg, &status, + 1)) { + dev_info(info->dev, "%s %d\n", __func__, __LINE__); + return -EFAULT; + } + return 0; + } + default: + return -EINVAL; + } + return 0; +} + +static int ov5640_open(struct inode *inode, struct file *file) +{ + struct miscdevice *miscdev = file->private_data; + struct ov5640_info *info; + + pr_info("%s\n", __func__); + if (!miscdev) { + pr_err("miscdev == NULL\n"); + return -1; + } + info = container_of(miscdev, struct ov5640_info, miscdev_info); + file->private_data = info; + + return 0; +} + +int ov5640_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + pr_info("%s\n", __func__); + return 0; +} + +static const struct file_operations ov5640_fileops = { + .owner = THIS_MODULE, + .open = ov5640_open, + .unlocked_ioctl = ov5640_ioctl, + .release = ov5640_release, +}; + +static struct miscdevice ov5640_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "ov5640", + .fops = &ov5640_fileops, +}; + +static int ov5640_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ov5640_info *info; + int err; + + dev_info(&client->dev, "ov5640: probing sensor.\n"); + + info = devm_kzalloc(&client->dev, + sizeof(struct ov5640_info), GFP_KERNEL); + if (!info) { + dev_err(&client->dev, "ov5640: Unable to allocate memory!\n"); + return -ENOMEM; + } + + memcpy(&(info->miscdev_info), + &ov5640_device, + sizeof(struct miscdevice)); + + err = misc_register(&(info->miscdev_info)); + if (err) { + dev_err(&client->dev, + "ov5640: Unable to register misc device!\n"); + devm_kfree(&client->dev, info); + return err; + } + + info->dev = &client->dev; + info->pdata = client->dev.platform_data; + info->i2c_client = client; + info->focuser.settle_time = SETTLETIME_MS; + info->focuser.focal_length = FOCAL_LENGTH; + info->focuser.fnumber = FNUMBER; + info->focuser.pos_low = POS_LOW; + info->focuser.pos_high = POS_HIGH; + + i2c_set_clientdata(client, info); + return 0; +} + +static int ov5640_remove(struct i2c_client *client) +{ + struct ov5640_info *info; + info = i2c_get_clientdata(client); + misc_deregister(&ov5640_device); + return 0; +} + +static const struct i2c_device_id ov5640_id[] = { + { "ov5640", 0 }, + { }, +}; + +MODULE_DEVICE_TABLE(i2c, ov5640_id); + +static struct i2c_driver ov5640_i2c_driver = { + .driver = { + .name = "ov5640", + .owner = THIS_MODULE, + }, + .probe = ov5640_probe, + .remove = ov5640_remove, + .id_table = ov5640_id, +}; + +module_i2c_driver(ov5640_i2c_driver); diff --git a/drivers/media/video/tegra/ov5640_tables.h b/drivers/media/video/tegra/ov5640_tables.h new file mode 100644 index 000000000000..94cf1da31ec2 --- /dev/null +++ b/drivers/media/video/tegra/ov5640_tables.h @@ -0,0 +1,4582 @@ +/* + * ov5640_tables.h - table header for YUV camera sensor OV5640 driver. + * + * Copyright (C) 2012 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#ifndef OV5640_I2C_TABLES +#define OV5640_I2C_TABLES + +struct ov5640_reg { + u16 addr; + u16 val; +}; + +#define OV5640_TABLE_WAIT_MS 0 +#define OV5640_TABLE_END 1 + +static struct ov5640_reg mode_2592x1944[] = { + /* PLL Control MIPI bit rate/lane = 672MHz, 16-bit mode. + * Output size: 2608x1948 (0, 0) - (2623, 1951), + * Line Length = 2844, Frame Length = 1968 + */ + {0x3103, 0x11}, + {0x3008, 0x82}, + {OV5640_TABLE_WAIT_MS, 5}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0x00}, + {0x3018, 0x00}, + {0x3034, 0x18}, + {0x3035, 0x11}, + {0x3036, 0x54}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x07}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9f}, + {0x3808, 0x0a}, + {0x3809, 0x30}, + {0x380a, 0x07}, + {0x380b, 0x9c}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3810, 0x00}, + {0x3811, 0x08}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3708, 0x64}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4001, 0x02}, + {0x4004, 0x06}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x45}, + {0x302e, 0x08}, + {0x4300, 0x32}, + {0x4800, 0x24}, + {0x4837, 0x0a}, + {0x501f, 0x00}, + {0x440e, 0x00}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {OV5640_TABLE_END, 0x0000} +}; + +static struct ov5640_reg mode_1920x1080[] = { + /* PLL Control MIPI bit rate/lane = 672MHz, 16-bit mode. + * Output size: 1936x1096 (336, 426) - (2287, 1529), + * Line Length = 2500, Frame Length = 1120. + */ + {0x3103, 0x11}, + {0x3008, 0x82}, + {OV5640_TABLE_WAIT_MS, 5}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0x00}, + {0x3018, 0x00}, + {0x3034, 0x18}, + {0x3035, 0x11}, + {0x3036, 0x54}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x07}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3800, 0x01}, + {0x3801, 0x50}, + {0x3802, 0x01}, + {0x3803, 0xaa}, + {0x3804, 0x08}, + {0x3805, 0xef}, + {0x3806, 0x05}, + {0x3807, 0xf9}, + {0x3808, 0x07}, + {0x3809, 0x90}, + {0x380a, 0x04}, + {0x380b, 0x48}, + {0x380c, 0x09}, + {0x380d, 0xc4}, + {0x380e, 0x04}, + {0x380f, 0x60}, + {0x3810, 0x00}, + {0x3811, 0x08}, + {0x3812, 0x00}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3708, 0x64}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x04}, + {0x3a03, 0x60}, + {0x3a08, 0x01}, + {0x3a09, 0x50}, + {0x3a0a, 0x01}, + {0x3a0b, 0x18}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x04}, + {0x3a15, 0x60}, + {0x4001, 0x02}, + {0x4004, 0x06}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x45}, + {0x302e, 0x08}, + {0x4300, 0x32}, + {0x501f, 0x00}, + {0x4713, 0x02}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x37}, + {0x460c, 0x20}, + {0x4800, 0x24}, + {0x4837, 0x0a}, + {0x3824, 0x04}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {OV5640_TABLE_END, 0x0000} +}; + +static struct ov5640_reg mode_1296x972[] = { + /* PLL Control MIPI bit rate/lane = 448MHz, 16-bit mode. + * Output size: 1304x972 (0, 0) - (2623, 1951), + * Line Length = 1886, Frame Length = 990. + */ + {0x3103, 0x11}, + {0x3008, 0x82}, + {OV5640_TABLE_WAIT_MS, 5}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0x00}, + {0x3018, 0x00}, + {0x3034, 0x18}, + {0x3035, 0x21}, + {0x3036, 0x70}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x07}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9f}, + {0x3808, 0x05}, + {0x3809, 0x18}, + {0x380a, 0x03}, + {0x380b, 0xcc}, + {0x380c, 0x07}, + {0x380d, 0x5e}, + {0x380e, 0x03}, + {0x380f, 0xde}, + {0x3810, 0x00}, + {0x3811, 0x06}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3708, 0x62}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x45}, + {0x302e, 0x08}, + {0x4300, 0x32}, + {0x501f, 0x00}, + {0x4713, 0x02}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x37}, + {0x460c, 0x20}, + {0x4800, 0x24}, + {0x4837, 0x10}, + {0x3824, 0x04}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {OV5640_TABLE_END, 0x0000} +}; + +enum { + OV5640_MODE_2592x1944 = 1, + OV5640_MODE_1920x1080, + OV5640_MODE_1296x972, +}; + +static struct ov5640_reg *mode_table[] = { + [OV5640_MODE_2592x1944] = mode_2592x1944, + [OV5640_MODE_1920x1080] = mode_1920x1080, + [OV5640_MODE_1296x972] = mode_1296x972, +}; + +static struct ov5640_reg tbl_af_firmware[] = { + {0x3000, 0x20}, + {0x8000, 0x02}, + {0x8001, 0x0b}, + {0x8002, 0x1f}, + {0x8003, 0x02}, + {0x8004, 0x07}, + {0x8005, 0x89}, + {0x8006, 0xc2}, + {0x8007, 0x01}, + {0x8008, 0x22}, + {0x8009, 0x22}, + {0x800a, 0x00}, + {0x800b, 0x02}, + {0x800c, 0x0b}, + {0x800d, 0x09}, + {0x800e, 0xe5}, + {0x800f, 0x40}, + {0x8010, 0x60}, + {0x8011, 0x03}, + {0x8012, 0x02}, + {0x8013, 0x00}, + {0x8014, 0x97}, + {0x8015, 0xf5}, + {0x8016, 0x3f}, + {0x8017, 0xd2}, + {0x8018, 0x34}, + {0x8019, 0x75}, + {0x801a, 0x29}, + {0x801b, 0xff}, + {0x801c, 0x75}, + {0x801d, 0x2a}, + {0x801e, 0x0e}, + {0x801f, 0x75}, + {0x8020, 0x2b}, + {0x8021, 0x55}, + {0x8022, 0x75}, + {0x8023, 0x2c}, + {0x8024, 0x01}, + {0x8025, 0x12}, + {0x8026, 0x0a}, + {0x8027, 0x0e}, + {0x8028, 0xe4}, + {0x8029, 0xff}, + {0x802a, 0xef}, + {0x802b, 0x25}, + {0x802c, 0xe0}, + {0x802d, 0x24}, + {0x802e, 0x41}, + {0x802f, 0xf8}, + {0x8030, 0xe4}, + {0x8031, 0xf6}, + {0x8032, 0x08}, + {0x8033, 0xf6}, + {0x8034, 0x0f}, + {0x8035, 0xbf}, + {0x8036, 0x34}, + {0x8037, 0xf2}, + {0x8038, 0x90}, + {0x8039, 0x0e}, + {0x803a, 0x88}, + {0x803b, 0xe4}, + {0x803c, 0x93}, + {0x803d, 0xff}, + {0x803e, 0xe5}, + {0x803f, 0x3e}, + {0x8040, 0xc3}, + {0x8041, 0x9f}, + {0x8042, 0x50}, + {0x8043, 0x04}, + {0x8044, 0x7f}, + {0x8045, 0x05}, + {0x8046, 0x80}, + {0x8047, 0x02}, + {0x8048, 0x7f}, + {0x8049, 0xfb}, + {0x804a, 0x78}, + {0x804b, 0xb0}, + {0x804c, 0xa6}, + {0x804d, 0x07}, + {0x804e, 0x12}, + {0x804f, 0x0a}, + {0x8050, 0x78}, + {0x8051, 0x40}, + {0x8052, 0x04}, + {0x8053, 0x7f}, + {0x8054, 0x03}, + {0x8055, 0x80}, + {0x8056, 0x02}, + {0x8057, 0x7f}, + {0x8058, 0x30}, + {0x8059, 0x78}, + {0x805a, 0xaf}, + {0x805b, 0xa6}, + {0x805c, 0x07}, + {0x805d, 0xe6}, + {0x805e, 0x18}, + {0x805f, 0xf6}, + {0x8060, 0x08}, + {0x8061, 0xe6}, + {0x8062, 0x78}, + {0x8063, 0xac}, + {0x8064, 0xf6}, + {0x8065, 0x78}, + {0x8066, 0xaf}, + {0x8067, 0xe6}, + {0x8068, 0x78}, + {0x8069, 0xad}, + {0x806a, 0xf6}, + {0x806b, 0x78}, + {0x806c, 0xb2}, + {0x806d, 0x76}, + {0x806e, 0x33}, + {0x806f, 0xe4}, + {0x8070, 0x08}, + {0x8071, 0xf6}, + {0x8072, 0x78}, + {0x8073, 0xab}, + {0x8074, 0x76}, + {0x8075, 0x01}, + {0x8076, 0x75}, + {0x8077, 0x3d}, + {0x8078, 0x02}, + {0x8079, 0x78}, + {0x807a, 0xa9}, + {0x807b, 0xf6}, + {0x807c, 0x08}, + {0x807d, 0xf6}, + {0x807e, 0x74}, + {0x807f, 0xff}, + {0x8080, 0x78}, + {0x8081, 0xb4}, + {0x8082, 0xf6}, + {0x8083, 0x08}, + {0x8084, 0xf6}, + {0x8085, 0x75}, + {0x8086, 0x40}, + {0x8087, 0x01}, + {0x8088, 0x78}, + {0x8089, 0xaf}, + {0x808a, 0xe6}, + {0x808b, 0x75}, + {0x808c, 0xf0}, + {0x808d, 0x05}, + {0x808e, 0xa4}, + {0x808f, 0xf5}, + {0x8090, 0x3e}, + {0x8091, 0x12}, + {0x8092, 0x08}, + {0x8093, 0x1d}, + {0x8094, 0xc2}, + {0x8095, 0x36}, + {0x8096, 0x22}, + {0x8097, 0x78}, + {0x8098, 0xab}, + {0x8099, 0xe6}, + {0x809a, 0xd3}, + {0x809b, 0x94}, + {0x809c, 0x00}, + {0x809d, 0x40}, + {0x809e, 0x02}, + {0x809f, 0x16}, + {0x80a0, 0x22}, + {0x80a1, 0xe5}, + {0x80a2, 0x40}, + {0x80a3, 0x64}, + {0x80a4, 0x05}, + {0x80a5, 0x70}, + {0x80a6, 0x28}, + {0x80a7, 0xf5}, + {0x80a8, 0x40}, + {0x80a9, 0xc2}, + {0x80aa, 0x01}, + {0x80ab, 0x78}, + {0x80ac, 0xac}, + {0x80ad, 0xe6}, + {0x80ae, 0x25}, + {0x80af, 0xe0}, + {0x80b0, 0x24}, + {0x80b1, 0x41}, + {0x80b2, 0xf8}, + {0x80b3, 0xe6}, + {0x80b4, 0xfe}, + {0x80b5, 0x08}, + {0x80b6, 0xe6}, + {0x80b7, 0xff}, + {0x80b8, 0x78}, + {0x80b9, 0x41}, + {0x80ba, 0xa6}, + {0x80bb, 0x06}, + {0x80bc, 0x08}, + {0x80bd, 0xa6}, + {0x80be, 0x07}, + {0x80bf, 0xa2}, + {0x80c0, 0x36}, + {0x80c1, 0xe4}, + {0x80c2, 0x33}, + {0x80c3, 0xf5}, + {0x80c4, 0x31}, + {0x80c5, 0x90}, + {0x80c6, 0x30}, + {0x80c7, 0x28}, + {0x80c8, 0xf0}, + {0x80c9, 0x75}, + {0x80ca, 0x3f}, + {0x80cb, 0x10}, + {0x80cc, 0xd2}, + {0x80cd, 0x34}, + {0x80ce, 0x22}, + {0x80cf, 0xe5}, + {0x80d0, 0x3e}, + {0x80d1, 0x75}, + {0x80d2, 0xf0}, + {0x80d3, 0x05}, + {0x80d4, 0x84}, + {0x80d5, 0x78}, + {0x80d6, 0xaf}, + {0x80d7, 0xf6}, + {0x80d8, 0x90}, + {0x80d9, 0x0e}, + {0x80da, 0x85}, + {0x80db, 0xe4}, + {0x80dc, 0x93}, + {0x80dd, 0xff}, + {0x80de, 0x25}, + {0x80df, 0xe0}, + {0x80e0, 0x24}, + {0x80e1, 0x0a}, + {0x80e2, 0xf8}, + {0x80e3, 0xe6}, + {0x80e4, 0xfc}, + {0x80e5, 0x08}, + {0x80e6, 0xe6}, + {0x80e7, 0xfd}, + {0x80e8, 0x78}, + {0x80e9, 0xaf}, + {0x80ea, 0xe6}, + {0x80eb, 0x25}, + {0x80ec, 0xe0}, + {0x80ed, 0x24}, + {0x80ee, 0x41}, + {0x80ef, 0xf8}, + {0x80f0, 0xa6}, + {0x80f1, 0x04}, + {0x80f2, 0x08}, + {0x80f3, 0xa6}, + {0x80f4, 0x05}, + {0x80f5, 0xef}, + {0x80f6, 0x12}, + {0x80f7, 0x0a}, + {0x80f8, 0x7f}, + {0x80f9, 0xd3}, + {0x80fa, 0x78}, + {0x80fb, 0xaa}, + {0x80fc, 0x96}, + {0x80fd, 0xee}, + {0x80fe, 0x18}, + {0x80ff, 0x96}, + {0x8100, 0x40}, + {0x8101, 0x0d}, + {0x8102, 0x78}, + {0x8103, 0xaf}, + {0x8104, 0xe6}, + {0x8105, 0x78}, + {0x8106, 0xac}, + {0x8107, 0xf6}, + {0x8108, 0x78}, + {0x8109, 0xa9}, + {0x810a, 0xa6}, + {0x810b, 0x06}, + {0x810c, 0x08}, + {0x810d, 0xa6}, + {0x810e, 0x07}, + {0x810f, 0x90}, + {0x8110, 0x0e}, + {0x8111, 0x85}, + {0x8112, 0xe4}, + {0x8113, 0x93}, + {0x8114, 0x12}, + {0x8115, 0x0a}, + {0x8116, 0x7f}, + {0x8117, 0xc3}, + {0x8118, 0x78}, + {0x8119, 0xb5}, + {0x811a, 0x96}, + {0x811b, 0xee}, + {0x811c, 0x18}, + {0x811d, 0x96}, + {0x811e, 0x50}, + {0x811f, 0x0d}, + {0x8120, 0x78}, + {0x8121, 0xaf}, + {0x8122, 0xe6}, + {0x8123, 0x78}, + {0x8124, 0xad}, + {0x8125, 0xf6}, + {0x8126, 0x78}, + {0x8127, 0xb4}, + {0x8128, 0xa6}, + {0x8129, 0x06}, + {0x812a, 0x08}, + {0x812b, 0xa6}, + {0x812c, 0x07}, + {0x812d, 0x78}, + {0x812e, 0xa9}, + {0x812f, 0xe6}, + {0x8130, 0xfe}, + {0x8131, 0x08}, + {0x8132, 0xe6}, + {0x8133, 0xc3}, + {0x8134, 0x78}, + {0x8135, 0xb5}, + {0x8136, 0x96}, + {0x8137, 0xff}, + {0x8138, 0xee}, + {0x8139, 0x18}, + {0x813a, 0x96}, + {0x813b, 0x78}, + {0x813c, 0xb6}, + {0x813d, 0xf6}, + {0x813e, 0x08}, + {0x813f, 0xa6}, + {0x8140, 0x07}, + {0x8141, 0x90}, + {0x8142, 0x0e}, + {0x8143, 0x8a}, + {0x8144, 0xe4}, + {0x8145, 0x18}, + {0x8146, 0x12}, + {0x8147, 0x0a}, + {0x8148, 0x5d}, + {0x8149, 0x40}, + {0x814a, 0x02}, + {0x814b, 0xd2}, + {0x814c, 0x36}, + {0x814d, 0x78}, + {0x814e, 0xaf}, + {0x814f, 0xe6}, + {0x8150, 0x08}, + {0x8151, 0x26}, + {0x8152, 0x08}, + {0x8153, 0xf6}, + {0x8154, 0xe5}, + {0x8155, 0x40}, + {0x8156, 0x64}, + {0x8157, 0x01}, + {0x8158, 0x70}, + {0x8159, 0x55}, + {0x815a, 0xe6}, + {0x815b, 0xc3}, + {0x815c, 0x78}, + {0x815d, 0xb3}, + {0x815e, 0x12}, + {0x815f, 0x0a}, + {0x8160, 0x53}, + {0x8161, 0x40}, + {0x8162, 0x10}, + {0x8163, 0x12}, + {0x8164, 0x0a}, + {0x8165, 0x4e}, + {0x8166, 0x50}, + {0x8167, 0x0b}, + {0x8168, 0x30}, + {0x8169, 0x36}, + {0x816a, 0x41}, + {0x816b, 0x78}, + {0x816c, 0xaf}, + {0x816d, 0xe6}, + {0x816e, 0x78}, + {0x816f, 0xac}, + {0x8170, 0x66}, + {0x8171, 0x60}, + {0x8172, 0x39}, + {0x8173, 0x12}, + {0x8174, 0x0a}, + {0x8175, 0x76}, + {0x8176, 0x40}, + {0x8177, 0x04}, + {0x8178, 0x7f}, + {0x8179, 0xfe}, + {0x817a, 0x80}, + {0x817b, 0x02}, + {0x817c, 0x7f}, + {0x817d, 0x02}, + {0x817e, 0x78}, + {0x817f, 0xb0}, + {0x8180, 0xa6}, + {0x8181, 0x07}, + {0x8182, 0x78}, + {0x8183, 0xac}, + {0x8184, 0xe6}, + {0x8185, 0x24}, + {0x8186, 0x03}, + {0x8187, 0x78}, + {0x8188, 0xb2}, + {0x8189, 0xf6}, + {0x818a, 0x78}, + {0x818b, 0xac}, + {0x818c, 0xe6}, + {0x818d, 0x24}, + {0x818e, 0xfd}, + {0x818f, 0x78}, + {0x8190, 0xb3}, + {0x8191, 0xf6}, + {0x8192, 0x12}, + {0x8193, 0x0a}, + {0x8194, 0x76}, + {0x8195, 0x40}, + {0x8196, 0x06}, + {0x8197, 0x78}, + {0x8198, 0xb3}, + {0x8199, 0xe6}, + {0x819a, 0xff}, + {0x819b, 0x80}, + {0x819c, 0x04}, + {0x819d, 0x78}, + {0x819e, 0xb2}, + {0x819f, 0xe6}, + {0x81a0, 0xff}, + {0x81a1, 0x78}, + {0x81a2, 0xb1}, + {0x81a3, 0xa6}, + {0x81a4, 0x07}, + {0x81a5, 0x75}, + {0x81a6, 0x40}, + {0x81a7, 0x02}, + {0x81a8, 0x78}, + {0x81a9, 0xab}, + {0x81aa, 0x76}, + {0x81ab, 0x01}, + {0x81ac, 0x02}, + {0x81ad, 0x02}, + {0x81ae, 0x6e}, + {0x81af, 0xe5}, + {0x81b0, 0x40}, + {0x81b1, 0x64}, + {0x81b2, 0x02}, + {0x81b3, 0x60}, + {0x81b4, 0x03}, + {0x81b5, 0x02}, + {0x81b6, 0x02}, + {0x81b7, 0x4e}, + {0x81b8, 0x78}, + {0x81b9, 0xb1}, + {0x81ba, 0xe6}, + {0x81bb, 0xff}, + {0x81bc, 0xc3}, + {0x81bd, 0x78}, + {0x81be, 0xb3}, + {0x81bf, 0x12}, + {0x81c0, 0x0a}, + {0x81c1, 0x54}, + {0x81c2, 0x40}, + {0x81c3, 0x08}, + {0x81c4, 0x12}, + {0x81c5, 0x0a}, + {0x81c6, 0x4e}, + {0x81c7, 0x50}, + {0x81c8, 0x03}, + {0x81c9, 0x02}, + {0x81ca, 0x02}, + {0x81cb, 0x4c}, + {0x81cc, 0x12}, + {0x81cd, 0x0a}, + {0x81ce, 0x76}, + {0x81cf, 0x40}, + {0x81d0, 0x04}, + {0x81d1, 0x7f}, + {0x81d2, 0xff}, + {0x81d3, 0x80}, + {0x81d4, 0x02}, + {0x81d5, 0x7f}, + {0x81d6, 0x01}, + {0x81d7, 0x78}, + {0x81d8, 0xb0}, + {0x81d9, 0xa6}, + {0x81da, 0x07}, + {0x81db, 0x78}, + {0x81dc, 0xac}, + {0x81dd, 0xe6}, + {0x81de, 0x04}, + {0x81df, 0x78}, + {0x81e0, 0xb2}, + {0x81e1, 0xf6}, + {0x81e2, 0x78}, + {0x81e3, 0xac}, + {0x81e4, 0xe6}, + {0x81e5, 0x14}, + {0x81e6, 0x78}, + {0x81e7, 0xb3}, + {0x81e8, 0xf6}, + {0x81e9, 0x18}, + {0x81ea, 0x12}, + {0x81eb, 0x0a}, + {0x81ec, 0x78}, + {0x81ed, 0x40}, + {0x81ee, 0x04}, + {0x81ef, 0xe6}, + {0x81f0, 0xff}, + {0x81f1, 0x80}, + {0x81f2, 0x02}, + {0x81f3, 0x7f}, + {0x81f4, 0x00}, + {0x81f5, 0x78}, + {0x81f6, 0xb2}, + {0x81f7, 0xa6}, + {0x81f8, 0x07}, + {0x81f9, 0xd3}, + {0x81fa, 0x08}, + {0x81fb, 0xe6}, + {0x81fc, 0x64}, + {0x81fd, 0x80}, + {0x81fe, 0x94}, + {0x81ff, 0x80}, + {0x8200, 0x40}, + {0x8201, 0x04}, + {0x8202, 0xe6}, + {0x8203, 0xff}, + {0x8204, 0x80}, + {0x8205, 0x02}, + {0x8206, 0x7f}, + {0x8207, 0x00}, + {0x8208, 0x78}, + {0x8209, 0xb3}, + {0x820a, 0xa6}, + {0x820b, 0x07}, + {0x820c, 0xc3}, + {0x820d, 0x18}, + {0x820e, 0xe6}, + {0x820f, 0x64}, + {0x8210, 0x80}, + {0x8211, 0x94}, + {0x8212, 0xb3}, + {0x8213, 0x50}, + {0x8214, 0x04}, + {0x8215, 0xe6}, + {0x8216, 0xff}, + {0x8217, 0x80}, + {0x8218, 0x02}, + {0x8219, 0x7f}, + {0x821a, 0x33}, + {0x821b, 0x78}, + {0x821c, 0xb2}, + {0x821d, 0xa6}, + {0x821e, 0x07}, + {0x821f, 0xc3}, + {0x8220, 0x08}, + {0x8221, 0xe6}, + {0x8222, 0x64}, + {0x8223, 0x80}, + {0x8224, 0x94}, + {0x8225, 0xb3}, + {0x8226, 0x50}, + {0x8227, 0x04}, + {0x8228, 0xe6}, + {0x8229, 0xff}, + {0x822a, 0x80}, + {0x822b, 0x02}, + {0x822c, 0x7f}, + {0x822d, 0x33}, + {0x822e, 0x78}, + {0x822f, 0xb3}, + {0x8230, 0xa6}, + {0x8231, 0x07}, + {0x8232, 0x12}, + {0x8233, 0x0a}, + {0x8234, 0x76}, + {0x8235, 0x40}, + {0x8236, 0x06}, + {0x8237, 0x78}, + {0x8238, 0xb3}, + {0x8239, 0xe6}, + {0x823a, 0xff}, + {0x823b, 0x80}, + {0x823c, 0x04}, + {0x823d, 0x78}, + {0x823e, 0xb2}, + {0x823f, 0xe6}, + {0x8240, 0xff}, + {0x8241, 0x78}, + {0x8242, 0xb1}, + {0x8243, 0xa6}, + {0x8244, 0x07}, + {0x8245, 0x75}, + {0x8246, 0x40}, + {0x8247, 0x03}, + {0x8248, 0x78}, + {0x8249, 0xab}, + {0x824a, 0x76}, + {0x824b, 0x01}, + {0x824c, 0x80}, + {0x824d, 0x20}, + {0x824e, 0xe5}, + {0x824f, 0x40}, + {0x8250, 0x64}, + {0x8251, 0x03}, + {0x8252, 0x70}, + {0x8253, 0x26}, + {0x8254, 0x78}, + {0x8255, 0xb1}, + {0x8256, 0xe6}, + {0x8257, 0xff}, + {0x8258, 0xc3}, + {0x8259, 0x78}, + {0x825a, 0xb3}, + {0x825b, 0x12}, + {0x825c, 0x0a}, + {0x825d, 0x54}, + {0x825e, 0x40}, + {0x825f, 0x05}, + {0x8260, 0x12}, + {0x8261, 0x0a}, + {0x8262, 0x4e}, + {0x8263, 0x40}, + {0x8264, 0x09}, + {0x8265, 0x78}, + {0x8266, 0xac}, + {0x8267, 0xe6}, + {0x8268, 0x78}, + {0x8269, 0xb1}, + {0x826a, 0xf6}, + {0x826b, 0x75}, + {0x826c, 0x40}, + {0x826d, 0x04}, + {0x826e, 0x78}, + {0x826f, 0xb1}, + {0x8270, 0xe6}, + {0x8271, 0x75}, + {0x8272, 0xf0}, + {0x8273, 0x05}, + {0x8274, 0xa4}, + {0x8275, 0xf5}, + {0x8276, 0x3e}, + {0x8277, 0x02}, + {0x8278, 0x08}, + {0x8279, 0x1d}, + {0x827a, 0xe5}, + {0x827b, 0x40}, + {0x827c, 0xb4}, + {0x827d, 0x04}, + {0x827e, 0x1f}, + {0x827f, 0x90}, + {0x8280, 0x0e}, + {0x8281, 0x89}, + {0x8282, 0xe4}, + {0x8283, 0x78}, + {0x8284, 0xb6}, + {0x8285, 0x12}, + {0x8286, 0x0a}, + {0x8287, 0x5d}, + {0x8288, 0x40}, + {0x8289, 0x02}, + {0x828a, 0xd2}, + {0x828b, 0x36}, + {0x828c, 0x75}, + {0x828d, 0x40}, + {0x828e, 0x05}, + {0x828f, 0x75}, + {0x8290, 0x29}, + {0x8291, 0xff}, + {0x8292, 0x75}, + {0x8293, 0x2a}, + {0x8294, 0x0e}, + {0x8295, 0x75}, + {0x8296, 0x2b}, + {0x8297, 0x59}, + {0x8298, 0x75}, + {0x8299, 0x2c}, + {0x829a, 0x01}, + {0x829b, 0x12}, + {0x829c, 0x0a}, + {0x829d, 0x0e}, + {0x829e, 0x22}, + {0x829f, 0xef}, + {0x82a0, 0x8d}, + {0x82a1, 0xf0}, + {0x82a2, 0xa4}, + {0x82a3, 0xa8}, + {0x82a4, 0xf0}, + {0x82a5, 0xcf}, + {0x82a6, 0x8c}, + {0x82a7, 0xf0}, + {0x82a8, 0xa4}, + {0x82a9, 0x28}, + {0x82aa, 0xce}, + {0x82ab, 0x8d}, + {0x82ac, 0xf0}, + {0x82ad, 0xa4}, + {0x82ae, 0x2e}, + {0x82af, 0xfe}, + {0x82b0, 0x22}, + {0x82b1, 0xbc}, + {0x82b2, 0x00}, + {0x82b3, 0x0b}, + {0x82b4, 0xbe}, + {0x82b5, 0x00}, + {0x82b6, 0x29}, + {0x82b7, 0xef}, + {0x82b8, 0x8d}, + {0x82b9, 0xf0}, + {0x82ba, 0x84}, + {0x82bb, 0xff}, + {0x82bc, 0xad}, + {0x82bd, 0xf0}, + {0x82be, 0x22}, + {0x82bf, 0xe4}, + {0x82c0, 0xcc}, + {0x82c1, 0xf8}, + {0x82c2, 0x75}, + {0x82c3, 0xf0}, + {0x82c4, 0x08}, + {0x82c5, 0xef}, + {0x82c6, 0x2f}, + {0x82c7, 0xff}, + {0x82c8, 0xee}, + {0x82c9, 0x33}, + {0x82ca, 0xfe}, + {0x82cb, 0xec}, + {0x82cc, 0x33}, + {0x82cd, 0xfc}, + {0x82ce, 0xee}, + {0x82cf, 0x9d}, + {0x82d0, 0xec}, + {0x82d1, 0x98}, + {0x82d2, 0x40}, + {0x82d3, 0x05}, + {0x82d4, 0xfc}, + {0x82d5, 0xee}, + {0x82d6, 0x9d}, + {0x82d7, 0xfe}, + {0x82d8, 0x0f}, + {0x82d9, 0xd5}, + {0x82da, 0xf0}, + {0x82db, 0xe9}, + {0x82dc, 0xe4}, + {0x82dd, 0xce}, + {0x82de, 0xfd}, + {0x82df, 0x22}, + {0x82e0, 0xed}, + {0x82e1, 0xf8}, + {0x82e2, 0xf5}, + {0x82e3, 0xf0}, + {0x82e4, 0xee}, + {0x82e5, 0x84}, + {0x82e6, 0x20}, + {0x82e7, 0xd2}, + {0x82e8, 0x1c}, + {0x82e9, 0xfe}, + {0x82ea, 0xad}, + {0x82eb, 0xf0}, + {0x82ec, 0x75}, + {0x82ed, 0xf0}, + {0x82ee, 0x08}, + {0x82ef, 0xef}, + {0x82f0, 0x2f}, + {0x82f1, 0xff}, + {0x82f2, 0xed}, + {0x82f3, 0x33}, + {0x82f4, 0xfd}, + {0x82f5, 0x40}, + {0x82f6, 0x07}, + {0x82f7, 0x98}, + {0x82f8, 0x50}, + {0x82f9, 0x06}, + {0x82fa, 0xd5}, + {0x82fb, 0xf0}, + {0x82fc, 0xf2}, + {0x82fd, 0x22}, + {0x82fe, 0xc3}, + {0x82ff, 0x98}, + {0x8300, 0xfd}, + {0x8301, 0x0f}, + {0x8302, 0xd5}, + {0x8303, 0xf0}, + {0x8304, 0xea}, + {0x8305, 0x22}, + {0x8306, 0xe8}, + {0x8307, 0x8f}, + {0x8308, 0xf0}, + {0x8309, 0xa4}, + {0x830a, 0xcc}, + {0x830b, 0x8b}, + {0x830c, 0xf0}, + {0x830d, 0xa4}, + {0x830e, 0x2c}, + {0x830f, 0xfc}, + {0x8310, 0xe9}, + {0x8311, 0x8e}, + {0x8312, 0xf0}, + {0x8313, 0xa4}, + {0x8314, 0x2c}, + {0x8315, 0xfc}, + {0x8316, 0x8a}, + {0x8317, 0xf0}, + {0x8318, 0xed}, + {0x8319, 0xa4}, + {0x831a, 0x2c}, + {0x831b, 0xfc}, + {0x831c, 0xea}, + {0x831d, 0x8e}, + {0x831e, 0xf0}, + {0x831f, 0xa4}, + {0x8320, 0xcd}, + {0x8321, 0xa8}, + {0x8322, 0xf0}, + {0x8323, 0x8b}, + {0x8324, 0xf0}, + {0x8325, 0xa4}, + {0x8326, 0x2d}, + {0x8327, 0xcc}, + {0x8328, 0x38}, + {0x8329, 0x25}, + {0x832a, 0xf0}, + {0x832b, 0xfd}, + {0x832c, 0xe9}, + {0x832d, 0x8f}, + {0x832e, 0xf0}, + {0x832f, 0xa4}, + {0x8330, 0x2c}, + {0x8331, 0xcd}, + {0x8332, 0x35}, + {0x8333, 0xf0}, + {0x8334, 0xfc}, + {0x8335, 0xeb}, + {0x8336, 0x8e}, + {0x8337, 0xf0}, + {0x8338, 0xa4}, + {0x8339, 0xfe}, + {0x833a, 0xa9}, + {0x833b, 0xf0}, + {0x833c, 0xeb}, + {0x833d, 0x8f}, + {0x833e, 0xf0}, + {0x833f, 0xa4}, + {0x8340, 0xcf}, + {0x8341, 0xc5}, + {0x8342, 0xf0}, + {0x8343, 0x2e}, + {0x8344, 0xcd}, + {0x8345, 0x39}, + {0x8346, 0xfe}, + {0x8347, 0xe4}, + {0x8348, 0x3c}, + {0x8349, 0xfc}, + {0x834a, 0xea}, + {0x834b, 0xa4}, + {0x834c, 0x2d}, + {0x834d, 0xce}, + {0x834e, 0x35}, + {0x834f, 0xf0}, + {0x8350, 0xfd}, + {0x8351, 0xe4}, + {0x8352, 0x3c}, + {0x8353, 0xfc}, + {0x8354, 0x22}, + {0x8355, 0x75}, + {0x8356, 0xf0}, + {0x8357, 0x08}, + {0x8358, 0x75}, + {0x8359, 0x82}, + {0x835a, 0x00}, + {0x835b, 0xef}, + {0x835c, 0x2f}, + {0x835d, 0xff}, + {0x835e, 0xee}, + {0x835f, 0x33}, + {0x8360, 0xfe}, + {0x8361, 0xcd}, + {0x8362, 0x33}, + {0x8363, 0xcd}, + {0x8364, 0xcc}, + {0x8365, 0x33}, + {0x8366, 0xcc}, + {0x8367, 0xc5}, + {0x8368, 0x82}, + {0x8369, 0x33}, + {0x836a, 0xc5}, + {0x836b, 0x82}, + {0x836c, 0x9b}, + {0x836d, 0xed}, + {0x836e, 0x9a}, + {0x836f, 0xec}, + {0x8370, 0x99}, + {0x8371, 0xe5}, + {0x8372, 0x82}, + {0x8373, 0x98}, + {0x8374, 0x40}, + {0x8375, 0x0c}, + {0x8376, 0xf5}, + {0x8377, 0x82}, + {0x8378, 0xee}, + {0x8379, 0x9b}, + {0x837a, 0xfe}, + {0x837b, 0xed}, + {0x837c, 0x9a}, + {0x837d, 0xfd}, + {0x837e, 0xec}, + {0x837f, 0x99}, + {0x8380, 0xfc}, + {0x8381, 0x0f}, + {0x8382, 0xd5}, + {0x8383, 0xf0}, + {0x8384, 0xd6}, + {0x8385, 0xe4}, + {0x8386, 0xce}, + {0x8387, 0xfb}, + {0x8388, 0xe4}, + {0x8389, 0xcd}, + {0x838a, 0xfa}, + {0x838b, 0xe4}, + {0x838c, 0xcc}, + {0x838d, 0xf9}, + {0x838e, 0xa8}, + {0x838f, 0x82}, + {0x8390, 0x22}, + {0x8391, 0xb8}, + {0x8392, 0x00}, + {0x8393, 0xc1}, + {0x8394, 0xb9}, + {0x8395, 0x00}, + {0x8396, 0x59}, + {0x8397, 0xba}, + {0x8398, 0x00}, + {0x8399, 0x2d}, + {0x839a, 0xec}, + {0x839b, 0x8b}, + {0x839c, 0xf0}, + {0x839d, 0x84}, + {0x839e, 0xcf}, + {0x839f, 0xce}, + {0x83a0, 0xcd}, + {0x83a1, 0xfc}, + {0x83a2, 0xe5}, + {0x83a3, 0xf0}, + {0x83a4, 0xcb}, + {0x83a5, 0xf9}, + {0x83a6, 0x78}, + {0x83a7, 0x18}, + {0x83a8, 0xef}, + {0x83a9, 0x2f}, + {0x83aa, 0xff}, + {0x83ab, 0xee}, + {0x83ac, 0x33}, + {0x83ad, 0xfe}, + {0x83ae, 0xed}, + {0x83af, 0x33}, + {0x83b0, 0xfd}, + {0x83b1, 0xec}, + {0x83b2, 0x33}, + {0x83b3, 0xfc}, + {0x83b4, 0xeb}, + {0x83b5, 0x33}, + {0x83b6, 0xfb}, + {0x83b7, 0x10}, + {0x83b8, 0xd7}, + {0x83b9, 0x03}, + {0x83ba, 0x99}, + {0x83bb, 0x40}, + {0x83bc, 0x04}, + {0x83bd, 0xeb}, + {0x83be, 0x99}, + {0x83bf, 0xfb}, + {0x83c0, 0x0f}, + {0x83c1, 0xd8}, + {0x83c2, 0xe5}, + {0x83c3, 0xe4}, + {0x83c4, 0xf9}, + {0x83c5, 0xfa}, + {0x83c6, 0x22}, + {0x83c7, 0x78}, + {0x83c8, 0x18}, + {0x83c9, 0xef}, + {0x83ca, 0x2f}, + {0x83cb, 0xff}, + {0x83cc, 0xee}, + {0x83cd, 0x33}, + {0x83ce, 0xfe}, + {0x83cf, 0xed}, + {0x83d0, 0x33}, + {0x83d1, 0xfd}, + {0x83d2, 0xec}, + {0x83d3, 0x33}, + {0x83d4, 0xfc}, + {0x83d5, 0xc9}, + {0x83d6, 0x33}, + {0x83d7, 0xc9}, + {0x83d8, 0x10}, + {0x83d9, 0xd7}, + {0x83da, 0x05}, + {0x83db, 0x9b}, + {0x83dc, 0xe9}, + {0x83dd, 0x9a}, + {0x83de, 0x40}, + + {0x83df, 0x07}, + {0x83e0, 0xec}, + {0x83e1, 0x9b}, + {0x83e2, 0xfc}, + {0x83e3, 0xe9}, + {0x83e4, 0x9a}, + {0x83e5, 0xf9}, + {0x83e6, 0x0f}, + {0x83e7, 0xd8}, + {0x83e8, 0xe0}, + {0x83e9, 0xe4}, + {0x83ea, 0xc9}, + {0x83eb, 0xfa}, + {0x83ec, 0xe4}, + {0x83ed, 0xcc}, + {0x83ee, 0xfb}, + {0x83ef, 0x22}, + {0x83f0, 0x75}, + {0x83f1, 0xf0}, + {0x83f2, 0x10}, + {0x83f3, 0xef}, + {0x83f4, 0x2f}, + {0x83f5, 0xff}, + {0x83f6, 0xee}, + {0x83f7, 0x33}, + {0x83f8, 0xfe}, + {0x83f9, 0xed}, + {0x83fa, 0x33}, + {0x83fb, 0xfd}, + {0x83fc, 0xcc}, + {0x83fd, 0x33}, + {0x83fe, 0xcc}, + {0x83ff, 0xc8}, + {0x8400, 0x33}, + {0x8401, 0xc8}, + {0x8402, 0x10}, + {0x8403, 0xd7}, + {0x8404, 0x07}, + {0x8405, 0x9b}, + {0x8406, 0xec}, + {0x8407, 0x9a}, + {0x8408, 0xe8}, + {0x8409, 0x99}, + {0x840a, 0x40}, + {0x840b, 0x0a}, + {0x840c, 0xed}, + {0x840d, 0x9b}, + {0x840e, 0xfd}, + {0x840f, 0xec}, + {0x8410, 0x9a}, + {0x8411, 0xfc}, + {0x8412, 0xe8}, + {0x8413, 0x99}, + {0x8414, 0xf8}, + {0x8415, 0x0f}, + {0x8416, 0xd5}, + {0x8417, 0xf0}, + {0x8418, 0xda}, + {0x8419, 0xe4}, + {0x841a, 0xcd}, + {0x841b, 0xfb}, + {0x841c, 0xe4}, + {0x841d, 0xcc}, + {0x841e, 0xfa}, + {0x841f, 0xe4}, + {0x8420, 0xc8}, + {0x8421, 0xf9}, + {0x8422, 0x22}, + {0x8423, 0xeb}, + {0x8424, 0x9f}, + {0x8425, 0xf5}, + {0x8426, 0xf0}, + {0x8427, 0xea}, + {0x8428, 0x9e}, + {0x8429, 0x42}, + {0x842a, 0xf0}, + {0x842b, 0xe9}, + {0x842c, 0x9d}, + {0x842d, 0x42}, + {0x842e, 0xf0}, + {0x842f, 0xe8}, + {0x8430, 0x9c}, + {0x8431, 0x45}, + {0x8432, 0xf0}, + {0x8433, 0x22}, + {0x8434, 0xe8}, + {0x8435, 0x60}, + {0x8436, 0x0f}, + {0x8437, 0xef}, + {0x8438, 0xc3}, + {0x8439, 0x33}, + {0x843a, 0xff}, + {0x843b, 0xee}, + {0x843c, 0x33}, + {0x843d, 0xfe}, + {0x843e, 0xed}, + {0x843f, 0x33}, + {0x8440, 0xfd}, + {0x8441, 0xec}, + {0x8442, 0x33}, + {0x8443, 0xfc}, + {0x8444, 0xd8}, + {0x8445, 0xf1}, + {0x8446, 0x22}, + {0x8447, 0xe4}, + {0x8448, 0x93}, + {0x8449, 0xfc}, + {0x844a, 0x74}, + {0x844b, 0x01}, + {0x844c, 0x93}, + {0x844d, 0xfd}, + {0x844e, 0x74}, + {0x844f, 0x02}, + {0x8450, 0x93}, + {0x8451, 0xfe}, + {0x8452, 0x74}, + {0x8453, 0x03}, + {0x8454, 0x93}, + {0x8455, 0xff}, + {0x8456, 0x22}, + {0x8457, 0xe6}, + {0x8458, 0xfb}, + {0x8459, 0x08}, + {0x845a, 0xe6}, + {0x845b, 0xf9}, + {0x845c, 0x08}, + {0x845d, 0xe6}, + {0x845e, 0xfa}, + {0x845f, 0x08}, + {0x8460, 0xe6}, + {0x8461, 0xcb}, + {0x8462, 0xf8}, + {0x8463, 0x22}, + {0x8464, 0xec}, + {0x8465, 0xf6}, + {0x8466, 0x08}, + {0x8467, 0xed}, + {0x8468, 0xf6}, + {0x8469, 0x08}, + {0x846a, 0xee}, + {0x846b, 0xf6}, + {0x846c, 0x08}, + {0x846d, 0xef}, + {0x846e, 0xf6}, + {0x846f, 0x22}, + {0x8470, 0xd0}, + {0x8471, 0x83}, + {0x8472, 0xd0}, + {0x8473, 0x82}, + {0x8474, 0xe4}, + {0x8475, 0x93}, + {0x8476, 0xf6}, + {0x8477, 0x08}, + {0x8478, 0x74}, + {0x8479, 0x01}, + {0x847a, 0x93}, + {0x847b, 0xf6}, + {0x847c, 0x08}, + {0x847d, 0x74}, + {0x847e, 0x02}, + {0x847f, 0x93}, + {0x8480, 0xf6}, + {0x8481, 0x08}, + {0x8482, 0x74}, + {0x8483, 0x03}, + {0x8484, 0x93}, + {0x8485, 0xf6}, + {0x8486, 0x74}, + {0x8487, 0x04}, + {0x8488, 0x73}, + {0x8489, 0xa4}, + {0x848a, 0x25}, + {0x848b, 0x82}, + {0x848c, 0xf5}, + {0x848d, 0x82}, + {0x848e, 0xe5}, + {0x848f, 0xf0}, + {0x8490, 0x35}, + {0x8491, 0x83}, + {0x8492, 0xf5}, + {0x8493, 0x83}, + {0x8494, 0x22}, + {0x8495, 0xd0}, + {0x8496, 0x83}, + {0x8497, 0xd0}, + {0x8498, 0x82}, + {0x8499, 0xf8}, + {0x849a, 0xe4}, + {0x849b, 0x93}, + {0x849c, 0x70}, + {0x849d, 0x12}, + {0x849e, 0x74}, + {0x849f, 0x01}, + {0x84a0, 0x93}, + {0x84a1, 0x70}, + {0x84a2, 0x0d}, + {0x84a3, 0xa3}, + {0x84a4, 0xa3}, + {0x84a5, 0x93}, + {0x84a6, 0xf8}, + {0x84a7, 0x74}, + {0x84a8, 0x01}, + {0x84a9, 0x93}, + {0x84aa, 0xf5}, + {0x84ab, 0x82}, + {0x84ac, 0x88}, + {0x84ad, 0x83}, + {0x84ae, 0xe4}, + {0x84af, 0x73}, + {0x84b0, 0x74}, + {0x84b1, 0x02}, + {0x84b2, 0x93}, + {0x84b3, 0x68}, + {0x84b4, 0x60}, + {0x84b5, 0xef}, + {0x84b6, 0xa3}, + {0x84b7, 0xa3}, + {0x84b8, 0xa3}, + {0x84b9, 0x80}, + {0x84ba, 0xdf}, + {0x84bb, 0x90}, + {0x84bc, 0x38}, + {0x84bd, 0x04}, + {0x84be, 0x78}, + {0x84bf, 0x45}, + {0x84c0, 0x12}, + {0x84c1, 0x09}, + {0x84c2, 0x1f}, + {0x84c3, 0x90}, + {0x84c4, 0x38}, + {0x84c5, 0x00}, + {0x84c6, 0xe0}, + {0x84c7, 0xfe}, + {0x84c8, 0xa3}, + {0x84c9, 0xe0}, + {0x84ca, 0xfd}, + {0x84cb, 0xed}, + {0x84cc, 0xff}, + {0x84cd, 0xc3}, + {0x84ce, 0x12}, + {0x84cf, 0x08}, + {0x84d0, 0xcb}, + {0x84d1, 0x90}, + {0x84d2, 0x38}, + {0x84d3, 0x10}, + {0x84d4, 0x12}, + {0x84d5, 0x08}, + {0x84d6, 0xbf}, + {0x84d7, 0x90}, + {0x84d8, 0x38}, + {0x84d9, 0x06}, + {0x84da, 0x78}, + {0x84db, 0x47}, + {0x84dc, 0x12}, + {0x84dd, 0x09}, + {0x84de, 0x1f}, + {0x84df, 0x90}, + {0x84e0, 0x38}, + {0x84e1, 0x02}, + {0x84e2, 0xe0}, + {0x84e3, 0xfe}, + {0x84e4, 0xa3}, + {0x84e5, 0xe0}, + {0x84e6, 0xfd}, + {0x84e7, 0xed}, + {0x84e8, 0xff}, + {0x84e9, 0xc3}, + {0x84ea, 0x12}, + {0x84eb, 0x08}, + {0x84ec, 0xcb}, + {0x84ed, 0x90}, + {0x84ee, 0x38}, + {0x84ef, 0x12}, + {0x84f0, 0x12}, + {0x84f1, 0x08}, + {0x84f2, 0xbf}, + {0x84f3, 0xa3}, + {0x84f4, 0xe0}, + {0x84f5, 0xb4}, + {0x84f6, 0x31}, + {0x84f7, 0x07}, + {0x84f8, 0x78}, + {0x84f9, 0x45}, + {0x84fa, 0x79}, + {0x84fb, 0x45}, + {0x84fc, 0x12}, + {0x84fd, 0x09}, + {0x84fe, 0x2a}, + {0x84ff, 0x90}, + {0x8500, 0x38}, + {0x8501, 0x14}, + {0x8502, 0xe0}, + {0x8503, 0xb4}, + {0x8504, 0x71}, + {0x8505, 0x15}, + {0x8506, 0x78}, + {0x8507, 0x45}, + {0x8508, 0xe6}, + {0x8509, 0xfe}, + {0x850a, 0x08}, + {0x850b, 0xe6}, + {0x850c, 0x78}, + {0x850d, 0x02}, + {0x850e, 0xce}, + {0x850f, 0xc3}, + {0x8510, 0x13}, + {0x8511, 0xce}, + {0x8512, 0x13}, + {0x8513, 0xd8}, + {0x8514, 0xf9}, + {0x8515, 0x79}, + {0x8516, 0x46}, + {0x8517, 0xf7}, + {0x8518, 0xee}, + {0x8519, 0x19}, + {0x851a, 0xf7}, + {0x851b, 0x90}, + {0x851c, 0x38}, + {0x851d, 0x15}, + {0x851e, 0xe0}, + {0x851f, 0xb4}, + {0x8520, 0x31}, + {0x8521, 0x07}, + {0x8522, 0x78}, + {0x8523, 0x47}, + {0x8524, 0x79}, + {0x8525, 0x47}, + {0x8526, 0x12}, + {0x8527, 0x09}, + {0x8528, 0x2a}, + {0x8529, 0x90}, + {0x852a, 0x38}, + {0x852b, 0x15}, + {0x852c, 0xe0}, + {0x852d, 0xb4}, + {0x852e, 0x71}, + {0x852f, 0x15}, + {0x8530, 0x78}, + {0x8531, 0x47}, + {0x8532, 0xe6}, + {0x8533, 0xfe}, + {0x8534, 0x08}, + {0x8535, 0xe6}, + {0x8536, 0x78}, + {0x8537, 0x02}, + {0x8538, 0xce}, + {0x8539, 0xc3}, + {0x853a, 0x13}, + {0x853b, 0xce}, + {0x853c, 0x13}, + {0x853d, 0xd8}, + {0x853e, 0xf9}, + {0x853f, 0x79}, + {0x8540, 0x48}, + {0x8541, 0xf7}, + {0x8542, 0xee}, + {0x8543, 0x19}, + {0x8544, 0xf7}, + {0x8545, 0x79}, + {0x8546, 0x45}, + {0x8547, 0x12}, + {0x8548, 0x08}, + {0x8549, 0xfb}, + {0x854a, 0x09}, + {0x854b, 0x12}, + {0x854c, 0x08}, + {0x854d, 0xfb}, + {0x854e, 0xaf}, + {0x854f, 0x3a}, + {0x8550, 0x12}, + {0x8551, 0x08}, + {0x8552, 0xb0}, + {0x8553, 0x7d}, + {0x8554, 0x50}, + {0x8555, 0x12}, + {0x8556, 0x02}, + {0x8557, 0xb1}, + {0x8558, 0x78}, + {0x8559, 0x4d}, + {0x855a, 0xa6}, + {0x855b, 0x06}, + {0x855c, 0x08}, + {0x855d, 0xa6}, + {0x855e, 0x07}, + {0x855f, 0xaf}, + {0x8560, 0x38}, + {0x8561, 0x12}, + {0x8562, 0x08}, + {0x8563, 0xb0}, + {0x8564, 0x7d}, + {0x8565, 0x50}, + {0x8566, 0x12}, + {0x8567, 0x02}, + {0x8568, 0xb1}, + {0x8569, 0x78}, + {0x856a, 0x49}, + {0x856b, 0xa6}, + {0x856c, 0x06}, + {0x856d, 0x08}, + {0x856e, 0xa6}, + {0x856f, 0x07}, + {0x8570, 0xaf}, + {0x8571, 0x3b}, + {0x8572, 0x78}, + {0x8573, 0x47}, + {0x8574, 0x12}, + {0x8575, 0x08}, + {0x8576, 0xb2}, + {0x8577, 0x7d}, + {0x8578, 0x3c}, + {0x8579, 0x12}, + {0x857a, 0x02}, + {0x857b, 0xb1}, + {0x857c, 0x78}, + {0x857d, 0x4f}, + {0x857e, 0xa6}, + {0x857f, 0x06}, + {0x8580, 0x08}, + {0x8581, 0xa6}, + {0x8582, 0x07}, + {0x8583, 0xaf}, + {0x8584, 0x39}, + {0x8585, 0x7e}, + {0x8586, 0x00}, + {0x8587, 0x78}, + {0x8588, 0x47}, + {0x8589, 0x12}, + {0x858a, 0x08}, + {0x858b, 0xb4}, + {0x858c, 0x7d}, + {0x858d, 0x3c}, + {0x858e, 0x12}, + {0x858f, 0x02}, + {0x8590, 0xb1}, + {0x8591, 0x78}, + {0x8592, 0x4b}, + {0x8593, 0xa6}, + {0x8594, 0x06}, + {0x8595, 0x08}, + {0x8596, 0xa6}, + {0x8597, 0x07}, + {0x8598, 0xc3}, + {0x8599, 0x78}, + {0x859a, 0x4e}, + {0x859b, 0xe6}, + {0x859c, 0x94}, + {0x859d, 0x08}, + {0x859e, 0x18}, + {0x859f, 0xe6}, + {0x85a0, 0x94}, + {0x85a1, 0x00}, + {0x85a2, 0x50}, + {0x85a3, 0x05}, + {0x85a4, 0x76}, + {0x85a5, 0x00}, + {0x85a6, 0x08}, + {0x85a7, 0x76}, + {0x85a8, 0x08}, + {0x85a9, 0xc3}, + {0x85aa, 0x78}, + {0x85ab, 0x50}, + {0x85ac, 0xe6}, + {0x85ad, 0x94}, + {0x85ae, 0x08}, + {0x85af, 0x18}, + {0x85b0, 0xe6}, + {0x85b1, 0x94}, + {0x85b2, 0x00}, + {0x85b3, 0x50}, + {0x85b4, 0x05}, + {0x85b5, 0x76}, + {0x85b6, 0x00}, + {0x85b7, 0x08}, + {0x85b8, 0x76}, + {0x85b9, 0x08}, + {0x85ba, 0x78}, + {0x85bb, 0x4d}, + {0x85bc, 0x12}, + {0x85bd, 0x08}, + {0x85be, 0xe8}, + {0x85bf, 0xff}, + {0x85c0, 0xc3}, + {0x85c1, 0x78}, + {0x85c2, 0x4a}, + {0x85c3, 0xe6}, + {0x85c4, 0x9f}, + {0x85c5, 0xff}, + {0x85c6, 0x18}, + {0x85c7, 0xe6}, + {0x85c8, 0x9e}, + {0x85c9, 0x78}, + {0x85ca, 0x51}, + {0x85cb, 0x12}, + {0x85cc, 0x08}, + {0x85cd, 0xdf}, + {0x85ce, 0xff}, + {0x85cf, 0xc3}, + {0x85d0, 0x78}, + {0x85d1, 0x4c}, + {0x85d2, 0xe6}, + {0x85d3, 0x9f}, + {0x85d4, 0xff}, + {0x85d5, 0x18}, + {0x85d6, 0xe6}, + {0x85d7, 0x9e}, + {0x85d8, 0xfe}, + {0x85d9, 0xe4}, + {0x85da, 0xfc}, + {0x85db, 0xfd}, + {0x85dc, 0x78}, + {0x85dd, 0x55}, + {0x85de, 0x12}, + {0x85df, 0x04}, + {0x85e0, 0x64}, + {0x85e1, 0x78}, + {0x85e2, 0x4d}, + {0x85e3, 0x12}, + {0x85e4, 0x08}, + {0x85e5, 0xe8}, + {0x85e6, 0x78}, + {0x85e7, 0x4a}, + {0x85e8, 0x26}, + {0x85e9, 0xff}, + {0x85ea, 0xee}, + {0x85eb, 0x18}, + {0x85ec, 0x36}, + {0x85ed, 0x78}, + {0x85ee, 0x59}, + {0x85ef, 0x12}, + {0x85f0, 0x08}, + {0x85f1, 0xdf}, + {0x85f2, 0x78}, + {0x85f3, 0x4c}, + {0x85f4, 0x26}, + {0x85f5, 0xff}, + {0x85f6, 0xee}, + {0x85f7, 0x18}, + {0x85f8, 0x36}, + {0x85f9, 0xfe}, + {0x85fa, 0xe4}, + {0x85fb, 0xfc}, + {0x85fc, 0xfd}, + {0x85fd, 0x78}, + {0x85fe, 0x5d}, + {0x85ff, 0x12}, + {0x8600, 0x04}, + {0x8601, 0x64}, + {0x8602, 0x78}, + {0x8603, 0x51}, + {0x8604, 0x12}, + {0x8605, 0x09}, + {0x8606, 0x13}, + {0x8607, 0x50}, + {0x8608, 0x09}, + {0x8609, 0x78}, + {0x860a, 0x51}, + {0x860b, 0x12}, + {0x860c, 0x04}, + {0x860d, 0x70}, + {0x860e, 0x00}, + {0x860f, 0x00}, + {0x8610, 0x00}, + {0x8611, 0x00}, + {0x8612, 0x78}, + {0x8613, 0x55}, + {0x8614, 0x12}, + {0x8615, 0x09}, + {0x8616, 0x13}, + {0x8617, 0x50}, + {0x8618, 0x09}, + {0x8619, 0x78}, + {0x861a, 0x55}, + {0x861b, 0x12}, + {0x861c, 0x04}, + {0x861d, 0x70}, + {0x861e, 0x00}, + {0x861f, 0x00}, + {0x8620, 0x00}, + {0x8621, 0x00}, + {0x8622, 0x12}, + {0x8623, 0x08}, + {0x8624, 0xf0}, + {0x8625, 0x78}, + {0x8626, 0x59}, + {0x8627, 0x12}, + {0x8628, 0x04}, + {0x8629, 0x57}, + {0x862a, 0xd3}, + {0x862b, 0x12}, + {0x862c, 0x04}, + {0x862d, 0x23}, + {0x862e, 0x40}, + {0x862f, 0x08}, + {0x8630, 0x12}, + {0x8631, 0x08}, + {0x8632, 0xf0}, + {0x8633, 0x78}, + {0x8634, 0x59}, + {0x8635, 0x12}, + {0x8636, 0x04}, + {0x8637, 0x64}, + {0x8638, 0x78}, + {0x8639, 0x47}, + {0x863a, 0x12}, + {0x863b, 0x08}, + {0x863c, 0xf2}, + {0x863d, 0x78}, + {0x863e, 0x5d}, + {0x863f, 0x12}, + {0x8640, 0x04}, + {0x8641, 0x57}, + {0x8642, 0xd3}, + {0x8643, 0x12}, + {0x8644, 0x04}, + {0x8645, 0x23}, + {0x8646, 0x40}, + {0x8647, 0x0a}, + {0x8648, 0x78}, + {0x8649, 0x47}, + {0x864a, 0x12}, + {0x864b, 0x08}, + {0x864c, 0xf2}, + {0x864d, 0x78}, + {0x864e, 0x5d}, + {0x864f, 0x12}, + {0x8650, 0x04}, + {0x8651, 0x64}, + {0x8652, 0xe4}, + {0x8653, 0xfd}, + {0x8654, 0x78}, + {0x8655, 0x54}, + {0x8656, 0x12}, + {0x8657, 0x09}, + {0x8658, 0x0b}, + {0x8659, 0x24}, + {0x865a, 0x01}, + {0x865b, 0x12}, + {0x865c, 0x08}, + {0x865d, 0xd3}, + {0x865e, 0x78}, + {0x865f, 0x58}, + {0x8660, 0x12}, + {0x8661, 0x09}, + {0x8662, 0x0b}, + {0x8663, 0x24}, + {0x8664, 0x02}, + {0x8665, 0x12}, + {0x8666, 0x08}, + {0x8667, 0xd3}, + {0x8668, 0x78}, + {0x8669, 0x5c}, + {0x866a, 0x12}, + {0x866b, 0x09}, + {0x866c, 0x0b}, + {0x866d, 0x24}, + {0x866e, 0x03}, + {0x866f, 0x12}, + {0x8670, 0x08}, + {0x8671, 0xd3}, + {0x8672, 0x78}, + {0x8673, 0x60}, + {0x8674, 0x12}, + {0x8675, 0x09}, + {0x8676, 0x0b}, + {0x8677, 0x24}, + {0x8678, 0x04}, + {0x8679, 0x12}, + {0x867a, 0x08}, + {0x867b, 0xd3}, + {0x867c, 0x0d}, + {0x867d, 0xbd}, + {0x867e, 0x05}, + {0x867f, 0xd4}, + {0x8680, 0xc2}, + {0x8681, 0x0e}, + {0x8682, 0xc2}, + {0x8683, 0x06}, + {0x8684, 0x22}, + {0x8685, 0x85}, + {0x8686, 0x08}, + {0x8687, 0x36}, + {0x8688, 0x90}, + {0x8689, 0x30}, + {0x868a, 0x24}, + {0x868b, 0xe0}, + {0x868c, 0xf5}, + {0x868d, 0x32}, + {0x868e, 0xa3}, + {0x868f, 0xe0}, + {0x8690, 0xf5}, + {0x8691, 0x33}, + {0x8692, 0xa3}, + {0x8693, 0xe0}, + {0x8694, 0xf5}, + {0x8695, 0x34}, + {0x8696, 0xa3}, + {0x8697, 0xe0}, + {0x8698, 0xf5}, + {0x8699, 0x35}, + {0x869a, 0xa3}, + {0x869b, 0xe0}, + {0x869c, 0xf5}, + {0x869d, 0x31}, + {0x869e, 0xd2}, + {0x869f, 0x33}, + {0x86a0, 0xe5}, + {0x86a1, 0x36}, + {0x86a2, 0x12}, + {0x86a3, 0x04}, + {0x86a4, 0x95}, + {0x86a5, 0x06}, + {0x86a6, 0xdf}, + {0x86a7, 0x03}, + {0x86a8, 0x06}, + {0x86a9, 0xe3}, + {0x86aa, 0x04}, + {0x86ab, 0x06}, + {0x86ac, 0xe9}, + {0x86ad, 0x07}, + {0x86ae, 0x06}, + {0x86af, 0xf1}, + {0x86b0, 0x08}, + {0x86b1, 0x07}, + {0x86b2, 0x14}, + {0x86b3, 0x18}, + {0x86b4, 0x07}, + {0x86b5, 0x2a}, + {0x86b6, 0x19}, + {0x86b7, 0x07}, + {0x86b8, 0x01}, + {0x86b9, 0x1a}, + {0x86ba, 0x07}, + {0x86bb, 0x0c}, + {0x86bc, 0x1b}, + {0x86bd, 0x07}, + {0x86be, 0x4e}, + {0x86bf, 0x80}, + {0x86c0, 0x07}, + {0x86c1, 0x51}, + {0x86c2, 0x81}, + {0x86c3, 0x07}, + {0x86c4, 0x6d}, + {0x86c5, 0x8f}, + {0x86c6, 0x07}, + {0x86c7, 0x5c}, + {0x86c8, 0x90}, + {0x86c9, 0x07}, + {0x86ca, 0x6d}, + {0x86cb, 0x91}, + {0x86cc, 0x07}, + {0x86cd, 0x6d}, + {0x86ce, 0x92}, + {0x86cf, 0x07}, + {0x86d0, 0x6d}, + {0x86d1, 0x93}, + {0x86d2, 0x07}, + {0x86d3, 0x6d}, + {0x86d4, 0x94}, + {0x86d5, 0x07}, + {0x86d6, 0x6d}, + {0x86d7, 0x98}, + {0x86d8, 0x07}, + {0x86d9, 0x6a}, + {0x86da, 0x9f}, + {0x86db, 0x00}, + {0x86dc, 0x00}, + {0x86dd, 0x07}, + {0x86de, 0x88}, + {0x86df, 0x12}, + {0x86e0, 0x0a}, + {0x86e1, 0xb8}, + {0x86e2, 0x22}, + {0x86e3, 0x12}, + {0x86e4, 0x0a}, + {0x86e5, 0xb8}, + {0x86e6, 0xd2}, + {0x86e7, 0x03}, + {0x86e8, 0x22}, + {0x86e9, 0xa2}, + {0x86ea, 0x36}, + {0x86eb, 0xe4}, + {0x86ec, 0x33}, + {0x86ed, 0xf5}, + {0x86ee, 0x31}, + {0x86ef, 0x80}, + {0x86f0, 0x7c}, + {0x86f1, 0xc2}, + {0x86f2, 0x01}, + {0x86f3, 0xc2}, + {0x86f4, 0x02}, + {0x86f5, 0xc2}, + {0x86f6, 0x03}, + {0x86f7, 0x12}, + {0x86f8, 0x09}, + {0x86f9, 0x34}, + {0x86fa, 0x75}, + {0x86fb, 0x3f}, + {0x86fc, 0x70}, + {0x86fd, 0xd2}, + {0x86fe, 0x34}, + {0x86ff, 0x80}, + {0x8700, 0x6c}, + {0x8701, 0x85}, + {0x8702, 0x35}, + {0x8703, 0x3d}, + {0x8704, 0x85}, + {0x8705, 0x31}, + {0x8706, 0x3e}, + {0x8707, 0x12}, + {0x8708, 0x08}, + {0x8709, 0x1d}, + {0x870a, 0x80}, + {0x870b, 0x61}, + {0x870c, 0x85}, + {0x870d, 0x3d}, + {0x870e, 0x35}, + {0x870f, 0x85}, + {0x8710, 0x3e}, + {0x8711, 0x31}, + {0x8712, 0x80}, + {0x8713, 0x59}, + {0x8714, 0xe4}, + {0x8715, 0xf5}, + {0x8716, 0x22}, + {0x8717, 0xf5}, + {0x8718, 0x23}, + {0x8719, 0x85}, + {0x871a, 0x35}, + {0x871b, 0x1e}, + {0x871c, 0x85}, + {0x871d, 0x34}, + {0x871e, 0x1d}, + {0x871f, 0x85}, + {0x8720, 0x33}, + {0x8721, 0x1c}, + {0x8722, 0x85}, + {0x8723, 0x32}, + {0x8724, 0x1b}, + {0x8725, 0x12}, + {0x8726, 0x0a}, + {0x8727, 0x8a}, + {0x8728, 0x80}, + {0x8729, 0x1f}, + {0x872a, 0x75}, + {0x872b, 0x22}, + {0x872c, 0x00}, + {0x872d, 0x75}, + {0x872e, 0x23}, + {0x872f, 0x01}, + {0x8730, 0x74}, + {0x8731, 0xff}, + {0x8732, 0xf5}, + {0x8733, 0x1a}, + {0x8734, 0xf5}, + {0x8735, 0x19}, + {0x8736, 0xf5}, + {0x8737, 0x18}, + {0x8738, 0xf5}, + {0x8739, 0x17}, + {0x873a, 0x12}, + {0x873b, 0x0a}, + {0x873c, 0x8a}, + {0x873d, 0x85}, + {0x873e, 0x1a}, + {0x873f, 0x35}, + {0x8740, 0x85}, + {0x8741, 0x19}, + {0x8742, 0x34}, + {0x8743, 0x85}, + {0x8744, 0x18}, + {0x8745, 0x33}, + {0x8746, 0x85}, + {0x8747, 0x17}, + {0x8748, 0x32}, + {0x8749, 0xe4}, + {0x874a, 0xf5}, + {0x874b, 0x31}, + {0x874c, 0x80}, + {0x874d, 0x1f}, + {0x874e, 0x02}, + {0x874f, 0x0a}, + {0x8750, 0xef}, + {0x8751, 0x85}, + {0x8752, 0x32}, + {0x8753, 0x38}, + {0x8754, 0x85}, + {0x8755, 0x33}, + {0x8756, 0x39}, + {0x8757, 0x12}, + {0x8758, 0x04}, + {0x8759, 0xbb}, + {0x875a, 0x80}, + {0x875b, 0x11}, + {0x875c, 0x85}, + {0x875d, 0x35}, + {0x875e, 0x3b}, + {0x875f, 0x85}, + {0x8760, 0x34}, + {0x8761, 0x3a}, + {0x8762, 0x85}, + {0x8763, 0x33}, + {0x8764, 0x39}, + {0x8765, 0x85}, + {0x8766, 0x32}, + {0x8767, 0x38}, + {0x8768, 0x80}, + {0x8769, 0x03}, + {0x876a, 0x02}, + {0x876b, 0x04}, + {0x876c, 0xbb}, + {0x876d, 0x90}, + {0x876e, 0x30}, + {0x876f, 0x24}, + {0x8770, 0xe5}, + {0x8771, 0x32}, + {0x8772, 0xf0}, + {0x8773, 0xa3}, + {0x8774, 0xe5}, + {0x8775, 0x33}, + {0x8776, 0xf0}, + {0x8777, 0xa3}, + {0x8778, 0xe5}, + {0x8779, 0x34}, + {0x877a, 0xf0}, + {0x877b, 0xa3}, + {0x877c, 0xe5}, + {0x877d, 0x35}, + {0x877e, 0xf0}, + {0x877f, 0xa3}, + {0x8780, 0xe5}, + {0x8781, 0x31}, + {0x8782, 0xf0}, + {0x8783, 0x90}, + {0x8784, 0x30}, + {0x8785, 0x23}, + {0x8786, 0xe4}, + {0x8787, 0xf0}, + {0x8788, 0x22}, + {0x8789, 0xc0}, + {0x878a, 0xe0}, + {0x878b, 0xc0}, + {0x878c, 0x83}, + {0x878d, 0xc0}, + {0x878e, 0x82}, + {0x878f, 0xc0}, + {0x8790, 0xd0}, + {0x8791, 0x90}, + {0x8792, 0x3f}, + {0x8793, 0x0c}, + {0x8794, 0xe0}, + {0x8795, 0xf5}, + {0x8796, 0x27}, + {0x8797, 0xe5}, + {0x8798, 0x27}, + {0x8799, 0x30}, + {0x879a, 0xe3}, + {0x879b, 0x42}, + {0x879c, 0x30}, + {0x879d, 0x35}, + {0x879e, 0x34}, + {0x879f, 0x90}, + {0x87a0, 0x60}, + {0x87a1, 0x19}, + {0x87a2, 0xe0}, + {0x87a3, 0xf5}, + {0x87a4, 0x0a}, + {0x87a5, 0xa3}, + {0x87a6, 0xe0}, + {0x87a7, 0xf5}, + {0x87a8, 0x0b}, + {0x87a9, 0x30}, + {0x87aa, 0x01}, + {0x87ab, 0x06}, + {0x87ac, 0x30}, + {0x87ad, 0x32}, + {0x87ae, 0x03}, + {0x87af, 0xd3}, + {0x87b0, 0x80}, + {0x87b1, 0x01}, + {0x87b2, 0xc3}, + {0x87b3, 0x92}, + {0x87b4, 0x09}, + {0x87b5, 0x30}, + {0x87b6, 0x02}, + {0x87b7, 0x06}, + {0x87b8, 0x30}, + {0x87b9, 0x32}, + {0x87ba, 0x03}, + {0x87bb, 0xd3}, + {0x87bc, 0x80}, + {0x87bd, 0x01}, + {0x87be, 0xc3}, + {0x87bf, 0x92}, + {0x87c0, 0x0a}, + {0x87c1, 0x30}, + {0x87c2, 0x32}, + {0x87c3, 0x0c}, + {0x87c4, 0x30}, + {0x87c5, 0x03}, + {0x87c6, 0x09}, + {0x87c7, 0x20}, + {0x87c8, 0x02}, + {0x87c9, 0x06}, + {0x87ca, 0x20}, + {0x87cb, 0x01}, + {0x87cc, 0x03}, + {0x87cd, 0xd3}, + {0x87ce, 0x80}, + {0x87cf, 0x01}, + {0x87d0, 0xc3}, + {0x87d1, 0x92}, + {0x87d2, 0x0b}, + {0x87d3, 0x90}, + {0x87d4, 0x30}, + {0x87d5, 0x01}, + {0x87d6, 0xe0}, + {0x87d7, 0x44}, + {0x87d8, 0x40}, + {0x87d9, 0xf0}, + {0x87da, 0xe0}, + {0x87db, 0x54}, + {0x87dc, 0xbf}, + {0x87dd, 0xf0}, + {0x87de, 0xe5}, + {0x87df, 0x27}, + {0x87e0, 0x30}, + {0x87e1, 0xe1}, + {0x87e2, 0x14}, + {0x87e3, 0x30}, + {0x87e4, 0x33}, + {0x87e5, 0x11}, + {0x87e6, 0x90}, + {0x87e7, 0x30}, + {0x87e8, 0x22}, + {0x87e9, 0xe0}, + {0x87ea, 0xf5}, + {0x87eb, 0x08}, + {0x87ec, 0xe4}, + {0x87ed, 0xf0}, + {0x87ee, 0x30}, + {0x87ef, 0x00}, + {0x87f0, 0x03}, + {0x87f1, 0xd3}, + {0x87f2, 0x80}, + {0x87f3, 0x01}, + {0x87f4, 0xc3}, + {0x87f5, 0x92}, + {0x87f6, 0x08}, + {0x87f7, 0xe5}, + {0x87f8, 0x27}, + {0x87f9, 0x30}, + {0x87fa, 0xe5}, + {0x87fb, 0x12}, + {0x87fc, 0x90}, + {0x87fd, 0x56}, + {0x87fe, 0x90}, + {0x87ff, 0xe0}, + {0x8800, 0xf5}, + {0x8801, 0x09}, + {0x8802, 0x30}, + {0x8803, 0x30}, + {0x8804, 0x09}, + {0x8805, 0x30}, + {0x8806, 0x05}, + {0x8807, 0x03}, + {0x8808, 0xd3}, + {0x8809, 0x80}, + {0x880a, 0x01}, + {0x880b, 0xc3}, + {0x880c, 0x92}, + {0x880d, 0x0d}, + {0x880e, 0x90}, + {0x880f, 0x3f}, + {0x8810, 0x0c}, + {0x8811, 0xe5}, + {0x8812, 0x27}, + {0x8813, 0xf0}, + {0x8814, 0xd0}, + {0x8815, 0xd0}, + {0x8816, 0xd0}, + {0x8817, 0x82}, + {0x8818, 0xd0}, + {0x8819, 0x83}, + {0x881a, 0xd0}, + {0x881b, 0xe0}, + {0x881c, 0x32}, + {0x881d, 0x90}, + {0x881e, 0x0e}, + {0x881f, 0x7d}, + {0x8820, 0xe4}, + {0x8821, 0x93}, + {0x8822, 0xfe}, + {0x8823, 0x74}, + {0x8824, 0x01}, + {0x8825, 0x93}, + {0x8826, 0xff}, + {0x8827, 0xc3}, + {0x8828, 0x90}, + {0x8829, 0x0e}, + {0x882a, 0x7b}, + {0x882b, 0x74}, + {0x882c, 0x01}, + {0x882d, 0x93}, + {0x882e, 0x9f}, + {0x882f, 0xff}, + {0x8830, 0xe4}, + {0x8831, 0x93}, + {0x8832, 0x9e}, + {0x8833, 0xfe}, + {0x8834, 0xe4}, + {0x8835, 0x8f}, + {0x8836, 0x30}, + {0x8837, 0x8e}, + {0x8838, 0x2f}, + {0x8839, 0xf5}, + {0x883a, 0x2e}, + {0x883b, 0xf5}, + {0x883c, 0x2d}, + {0x883d, 0xab}, + {0x883e, 0x30}, + {0x883f, 0xaa}, + {0x8840, 0x2f}, + {0x8841, 0xa9}, + {0x8842, 0x2e}, + {0x8843, 0xa8}, + {0x8844, 0x2d}, + {0x8845, 0xaf}, + {0x8846, 0x3e}, + {0x8847, 0xfc}, + {0x8848, 0xfd}, + {0x8849, 0xfe}, + {0x884a, 0x12}, + {0x884b, 0x03}, + {0x884c, 0x06}, + {0x884d, 0x12}, + {0x884e, 0x0a}, + {0x884f, 0xd4}, + {0x8850, 0xe4}, + {0x8851, 0x7b}, + {0x8852, 0xff}, + {0x8853, 0xfa}, + {0x8854, 0xf9}, + {0x8855, 0xf8}, + {0x8856, 0x12}, + {0x8857, 0x03}, + {0x8858, 0x91}, + {0x8859, 0x12}, + {0x885a, 0x0a}, + {0x885b, 0xd4}, + {0x885c, 0x90}, + {0x885d, 0x0e}, + {0x885e, 0x69}, + {0x885f, 0xe4}, + {0x8860, 0x12}, + {0x8861, 0x0a}, + {0x8862, 0xe9}, + {0x8863, 0x12}, + {0x8864, 0x0a}, + {0x8865, 0xd4}, + {0x8866, 0xe4}, + {0x8867, 0x85}, + {0x8868, 0x3d}, + {0x8869, 0x2c}, + {0x886a, 0xf5}, + {0x886b, 0x2b}, + {0x886c, 0xf5}, + {0x886d, 0x2a}, + {0x886e, 0xf5}, + {0x886f, 0x29}, + {0x8870, 0xaf}, + {0x8871, 0x2c}, + {0x8872, 0xae}, + {0x8873, 0x2b}, + {0x8874, 0xad}, + {0x8875, 0x2a}, + {0x8876, 0xac}, + {0x8877, 0x29}, + {0x8878, 0xa3}, + {0x8879, 0x12}, + {0x887a, 0x0a}, + {0x887b, 0xe9}, + {0x887c, 0x8f}, + {0x887d, 0x2c}, + {0x887e, 0x8e}, + {0x887f, 0x2b}, + {0x8880, 0x8d}, + {0x8881, 0x2a}, + {0x8882, 0x8c}, + {0x8883, 0x29}, + {0x8884, 0xe5}, + {0x8885, 0x30}, + {0x8886, 0x45}, + {0x8887, 0x2c}, + {0x8888, 0xf5}, + {0x8889, 0x30}, + {0x888a, 0xe5}, + {0x888b, 0x2f}, + {0x888c, 0x45}, + {0x888d, 0x2b}, + {0x888e, 0xf5}, + {0x888f, 0x2f}, + {0x8890, 0xe5}, + {0x8891, 0x2e}, + {0x8892, 0x45}, + {0x8893, 0x2a}, + {0x8894, 0xf5}, + {0x8895, 0x2e}, + {0x8896, 0xe5}, + {0x8897, 0x2d}, + {0x8898, 0x45}, + {0x8899, 0x29}, + {0x889a, 0xf5}, + {0x889b, 0x2d}, + {0x889c, 0xe4}, + {0x889d, 0xf5}, + {0x889e, 0x22}, + {0x889f, 0xf5}, + {0x88a0, 0x23}, + {0x88a1, 0x85}, + {0x88a2, 0x30}, + {0x88a3, 0x1e}, + {0x88a4, 0x85}, + {0x88a5, 0x2f}, + {0x88a6, 0x1d}, + {0x88a7, 0x85}, + {0x88a8, 0x2e}, + {0x88a9, 0x1c}, + {0x88aa, 0x85}, + {0x88ab, 0x2d}, + {0x88ac, 0x1b}, + {0x88ad, 0x02}, + {0x88ae, 0x0a}, + {0x88af, 0x8a}, + {0x88b0, 0x78}, + {0x88b1, 0x45}, + {0x88b2, 0x7e}, + {0x88b3, 0x00}, + {0x88b4, 0xe6}, + {0x88b5, 0xfc}, + {0x88b6, 0x08}, + {0x88b7, 0xe6}, + {0x88b8, 0xfd}, + {0x88b9, 0x12}, + {0x88ba, 0x02}, + {0x88bb, 0x9f}, + {0x88bc, 0x7c}, + {0x88bd, 0x00}, + {0x88be, 0x22}, + {0x88bf, 0xe0}, + {0x88c0, 0xa3}, + {0x88c1, 0xe0}, + {0x88c2, 0x75}, + {0x88c3, 0xf0}, + {0x88c4, 0x02}, + {0x88c5, 0xa4}, + {0x88c6, 0xff}, + {0x88c7, 0xae}, + {0x88c8, 0xf0}, + {0x88c9, 0xc3}, + {0x88ca, 0x08}, + {0x88cb, 0xe6}, + {0x88cc, 0x9f}, + {0x88cd, 0xf6}, + {0x88ce, 0x18}, + {0x88cf, 0xe6}, + {0x88d0, 0x9e}, + {0x88d1, 0xf6}, + {0x88d2, 0x22}, + {0x88d3, 0xff}, + {0x88d4, 0xe5}, + {0x88d5, 0xf0}, + {0x88d6, 0x34}, + {0x88d7, 0x60}, + {0x88d8, 0x8f}, + {0x88d9, 0x82}, + {0x88da, 0xf5}, + {0x88db, 0x83}, + {0x88dc, 0xec}, + {0x88dd, 0xf0}, + {0x88de, 0x22}, + {0x88df, 0xfe}, + {0x88e0, 0xe4}, + {0x88e1, 0xfc}, + {0x88e2, 0xfd}, + {0x88e3, 0x12}, + {0x88e4, 0x04}, + {0x88e5, 0x64}, + {0x88e6, 0x78}, + {0x88e7, 0x4f}, + {0x88e8, 0xe6}, + {0x88e9, 0xc3}, + {0x88ea, 0x13}, + {0x88eb, 0xfe}, + {0x88ec, 0x08}, + {0x88ed, 0xe6}, + {0x88ee, 0x13}, + {0x88ef, 0x22}, + {0x88f0, 0x78}, + {0x88f1, 0x45}, + {0x88f2, 0xe6}, + {0x88f3, 0xfe}, + {0x88f4, 0x08}, + {0x88f5, 0xe6}, + {0x88f6, 0xff}, + {0x88f7, 0xe4}, + {0x88f8, 0xfc}, + {0x88f9, 0xfd}, + {0x88fa, 0x22}, + {0x88fb, 0xe7}, + {0x88fc, 0xc4}, + {0x88fd, 0xf8}, + {0x88fe, 0x54}, + {0x88ff, 0xf0}, + {0x8900, 0xc8}, + {0x8901, 0x68}, + {0x8902, 0xf7}, + {0x8903, 0x09}, + {0x8904, 0xe7}, + {0x8905, 0xc4}, + {0x8906, 0x54}, + {0x8907, 0x0f}, + {0x8908, 0x48}, + {0x8909, 0xf7}, + {0x890a, 0x22}, + {0x890b, 0xe6}, + {0x890c, 0xfc}, + {0x890d, 0xed}, + {0x890e, 0x75}, + {0x890f, 0xf0}, + {0x8910, 0x04}, + {0x8911, 0xa4}, + {0x8912, 0x22}, + {0x8913, 0xe4}, + {0x8914, 0xff}, + {0x8915, 0xfe}, + {0x8916, 0xfd}, + {0x8917, 0xfc}, + {0x8918, 0x12}, + {0x8919, 0x04}, + {0x891a, 0x57}, + {0x891b, 0xc3}, + {0x891c, 0x02}, + {0x891d, 0x04}, + {0x891e, 0x23}, + {0x891f, 0xe0}, + {0x8920, 0xfe}, + {0x8921, 0xa3}, + {0x8922, 0xe0}, + {0x8923, 0xfd}, + {0x8924, 0xee}, + {0x8925, 0xf6}, + {0x8926, 0xed}, + {0x8927, 0x08}, + {0x8928, 0xf6}, + {0x8929, 0x22}, + {0x892a, 0xe6}, + {0x892b, 0xc3}, + {0x892c, 0x13}, + {0x892d, 0xf7}, + {0x892e, 0x08}, + {0x892f, 0xe6}, + {0x8930, 0x13}, + {0x8931, 0x09}, + {0x8932, 0xf7}, + {0x8933, 0x22}, + {0x8934, 0xe4}, + {0x8935, 0xf5}, + {0x8936, 0x3e}, + {0x8937, 0x90}, + {0x8938, 0x0e}, + {0x8939, 0x77}, + {0x893a, 0x93}, + {0x893b, 0xff}, + {0x893c, 0xe4}, + {0x893d, 0x8f}, + {0x893e, 0x2c}, + {0x893f, 0xf5}, + {0x8940, 0x2b}, + {0x8941, 0xf5}, + {0x8942, 0x2a}, + {0x8943, 0xf5}, + {0x8944, 0x29}, + {0x8945, 0xaf}, + {0x8946, 0x2c}, + {0x8947, 0xae}, + {0x8948, 0x2b}, + {0x8949, 0xad}, + {0x894a, 0x2a}, + {0x894b, 0xac}, + {0x894c, 0x29}, + {0x894d, 0x90}, + {0x894e, 0x0e}, + {0x894f, 0x6a}, + {0x8950, 0x12}, + {0x8951, 0x0a}, + {0x8952, 0xe9}, + {0x8953, 0x8f}, + {0x8954, 0x2c}, + {0x8955, 0x8e}, + {0x8956, 0x2b}, + {0x8957, 0x8d}, + {0x8958, 0x2a}, + {0x8959, 0x8c}, + {0x895a, 0x29}, + {0x895b, 0x90}, + {0x895c, 0x0e}, + {0x895d, 0x72}, + {0x895e, 0x12}, + {0x895f, 0x04}, + {0x8960, 0x47}, + {0x8961, 0xef}, + {0x8962, 0x45}, + {0x8963, 0x2c}, + {0x8964, 0xf5}, + {0x8965, 0x2c}, + {0x8966, 0xee}, + {0x8967, 0x45}, + {0x8968, 0x2b}, + {0x8969, 0xf5}, + {0x896a, 0x2b}, + {0x896b, 0xed}, + {0x896c, 0x45}, + {0x896d, 0x2a}, + {0x896e, 0xf5}, + {0x896f, 0x2a}, + {0x8970, 0xec}, + {0x8971, 0x45}, + {0x8972, 0x29}, + {0x8973, 0xf5}, + {0x8974, 0x29}, + {0x8975, 0xe4}, + {0x8976, 0xf5}, + {0x8977, 0x22}, + {0x8978, 0xf5}, + {0x8979, 0x23}, + {0x897a, 0x85}, + {0x897b, 0x2c}, + {0x897c, 0x1e}, + {0x897d, 0x85}, + {0x897e, 0x2b}, + {0x897f, 0x1d}, + {0x8980, 0x85}, + {0x8981, 0x2a}, + {0x8982, 0x1c}, + {0x8983, 0x85}, + {0x8984, 0x29}, + {0x8985, 0x1b}, + {0x8986, 0x12}, + {0x8987, 0x0a}, + {0x8988, 0x8a}, + {0x8989, 0xe4}, + {0x898a, 0xf5}, + {0x898b, 0x22}, + {0x898c, 0xf5}, + {0x898d, 0x23}, + {0x898e, 0x90}, + {0x898f, 0x0e}, + {0x8990, 0x72}, + {0x8991, 0x12}, + {0x8992, 0x0a}, + {0x8993, 0xdd}, + {0x8994, 0x12}, + {0x8995, 0x0a}, + {0x8996, 0x8a}, + {0x8997, 0xe4}, + {0x8998, 0xf5}, + {0x8999, 0x22}, + {0x899a, 0xf5}, + {0x899b, 0x23}, + {0x899c, 0x90}, + {0x899d, 0x0e}, + {0x899e, 0x6e}, + {0x899f, 0x12}, + {0x89a0, 0x0a}, + {0x89a1, 0xdd}, + {0x89a2, 0x02}, + {0x89a3, 0x0a}, + {0x89a4, 0x8a}, + {0x89a5, 0x75}, + {0x89a6, 0x89}, + {0x89a7, 0x03}, + {0x89a8, 0x75}, + {0x89a9, 0xa8}, + {0x89aa, 0x01}, + {0x89ab, 0x75}, + {0x89ac, 0xb8}, + {0x89ad, 0x04}, + {0x89ae, 0x75}, + {0x89af, 0x29}, + {0x89b0, 0xff}, + {0x89b1, 0x75}, + {0x89b2, 0x2a}, + {0x89b3, 0x0e}, + {0x89b4, 0x75}, + {0x89b5, 0x2b}, + {0x89b6, 0x15}, + {0x89b7, 0x75}, + {0x89b8, 0x2c}, + {0x89b9, 0x0d}, + {0x89ba, 0x12}, + {0x89bb, 0x0a}, + {0x89bc, 0x0e}, + {0x89bd, 0x12}, + {0x89be, 0x00}, + {0x89bf, 0x09}, + {0x89c0, 0x12}, + {0x89c1, 0x0a}, + {0x89c2, 0xef}, + {0x89c3, 0x12}, + {0x89c4, 0x00}, + {0x89c5, 0x06}, + {0x89c6, 0xd2}, + {0x89c7, 0x00}, + {0x89c8, 0xd2}, + {0x89c9, 0x33}, + {0x89ca, 0xd2}, + {0x89cb, 0xaf}, + {0x89cc, 0x75}, + {0x89cd, 0x29}, + {0x89ce, 0xff}, + {0x89cf, 0x75}, + {0x89d0, 0x2a}, + {0x89d1, 0x0e}, + {0x89d2, 0x75}, + {0x89d3, 0x2b}, + {0x89d4, 0x49}, + {0x89d5, 0x75}, + {0x89d6, 0x2c}, + {0x89d7, 0x03}, + {0x89d8, 0x12}, + {0x89d9, 0x0a}, + {0x89da, 0x0e}, + {0x89db, 0x30}, + {0x89dc, 0x08}, + {0x89dd, 0x09}, + {0x89de, 0xc2}, + {0x89df, 0x33}, + {0x89e0, 0x12}, + {0x89e1, 0x06}, + {0x89e2, 0x85}, + {0x89e3, 0xc2}, + {0x89e4, 0x08}, + {0x89e5, 0xd2}, + {0x89e6, 0x33}, + {0x89e7, 0x30}, + {0x89e8, 0x09}, + {0x89e9, 0x09}, + {0x89ea, 0xc2}, + {0x89eb, 0x35}, + {0x89ec, 0x12}, + {0x89ed, 0x00}, + {0x89ee, 0x0e}, + {0x89ef, 0xc2}, + {0x89f0, 0x09}, + {0x89f1, 0xd2}, + {0x89f2, 0x35}, + {0x89f3, 0x30}, + {0x89f4, 0x0e}, + {0x89f5, 0x03}, + {0x89f6, 0x12}, + {0x89f7, 0x04}, + {0x89f8, 0xbb}, + {0x89f9, 0x30}, + {0x89fa, 0x34}, + {0x89fb, 0xdf}, + {0x89fc, 0x90}, + {0x89fd, 0x30}, + {0x89fe, 0x29}, + {0x89ff, 0xe5}, + {0x8a00, 0x3f}, + {0x8a01, 0xf0}, + {0x8a02, 0xb4}, + {0x8a03, 0x10}, + {0x8a04, 0x05}, + {0x8a05, 0x90}, + {0x8a06, 0x30}, + {0x8a07, 0x23}, + {0x8a08, 0xe4}, + {0x8a09, 0xf0}, + {0x8a0a, 0xc2}, + {0x8a0b, 0x34}, + {0x8a0c, 0x80}, + {0x8a0d, 0xcd}, + {0x8a0e, 0xae}, + {0x8a0f, 0x2a}, + {0x8a10, 0xaf}, + {0x8a11, 0x2b}, + {0x8a12, 0xe4}, + {0x8a13, 0xfd}, + {0x8a14, 0xed}, + {0x8a15, 0xc3}, + {0x8a16, 0x95}, + {0x8a17, 0x2c}, + {0x8a18, 0x50}, + {0x8a19, 0x33}, + {0x8a1a, 0x12}, + {0x8a1b, 0x0b}, + {0x8a1c, 0x36}, + {0x8a1d, 0xe4}, + {0x8a1e, 0x93}, + {0x8a1f, 0xf5}, + {0x8a20, 0x2d}, + {0x8a21, 0x74}, + {0x8a22, 0x01}, + {0x8a23, 0x93}, + {0x8a24, 0xf5}, + {0x8a25, 0x2e}, + {0x8a26, 0x45}, + {0x8a27, 0x2d}, + {0x8a28, 0x60}, + {0x8a29, 0x23}, + {0x8a2a, 0x85}, + {0x8a2b, 0x2e}, + {0x8a2c, 0x82}, + {0x8a2d, 0x85}, + {0x8a2e, 0x2d}, + {0x8a2f, 0x83}, + {0x8a30, 0xe0}, + {0x8a31, 0xfc}, + {0x8a32, 0x12}, + {0x8a33, 0x0b}, + {0x8a34, 0x36}, + {0x8a35, 0x74}, + {0x8a36, 0x03}, + {0x8a37, 0x93}, + {0x8a38, 0x52}, + {0x8a39, 0x04}, + {0x8a3a, 0x12}, + {0x8a3b, 0x0b}, + {0x8a3c, 0x36}, + {0x8a3d, 0x74}, + {0x8a3e, 0x02}, + {0x8a3f, 0x93}, + {0x8a40, 0x42}, + {0x8a41, 0x04}, + {0x8a42, 0x85}, + {0x8a43, 0x2e}, + {0x8a44, 0x82}, + {0x8a45, 0x85}, + {0x8a46, 0x2d}, + {0x8a47, 0x83}, + {0x8a48, 0xec}, + {0x8a49, 0xf0}, + {0x8a4a, 0x0d}, + {0x8a4b, 0x80}, + {0x8a4c, 0xc7}, + {0x8a4d, 0x22}, + {0x8a4e, 0x78}, + {0x8a4f, 0xb1}, + {0x8a50, 0xe6}, + {0x8a51, 0xd3}, + {0x8a52, 0x08}, + {0x8a53, 0xff}, + {0x8a54, 0xe6}, + {0x8a55, 0x64}, + {0x8a56, 0x80}, + {0x8a57, 0xf8}, + {0x8a58, 0xef}, + {0x8a59, 0x64}, + {0x8a5a, 0x80}, + {0x8a5b, 0x98}, + {0x8a5c, 0x22}, + {0x8a5d, 0x93}, + {0x8a5e, 0xff}, + {0x8a5f, 0x7e}, + {0x8a60, 0x00}, + {0x8a61, 0xe6}, + {0x8a62, 0xfc}, + {0x8a63, 0x08}, + {0x8a64, 0xe6}, + {0x8a65, 0xfd}, + {0x8a66, 0x12}, + {0x8a67, 0x02}, + {0x8a68, 0x9f}, + {0x8a69, 0x78}, + {0x8a6a, 0xb4}, + {0x8a6b, 0xe6}, + {0x8a6c, 0xfc}, + {0x8a6d, 0x08}, + {0x8a6e, 0xe6}, + {0x8a6f, 0xfd}, + {0x8a70, 0xd3}, + {0x8a71, 0xef}, + {0x8a72, 0x9d}, + {0x8a73, 0xee}, + {0x8a74, 0x9c}, + {0x8a75, 0x22}, + {0x8a76, 0x78}, + {0x8a77, 0xb0}, + {0x8a78, 0xd3}, + {0x8a79, 0xe6}, + {0x8a7a, 0x64}, + {0x8a7b, 0x80}, + {0x8a7c, 0x94}, + {0x8a7d, 0x80}, + {0x8a7e, 0x22}, + {0x8a7f, 0x25}, + {0x8a80, 0xe0}, + {0x8a81, 0x24}, + {0x8a82, 0x0a}, + {0x8a83, 0xf8}, + {0x8a84, 0xe6}, + {0x8a85, 0xfe}, + {0x8a86, 0x08}, + {0x8a87, 0xe6}, + {0x8a88, 0xff}, + {0x8a89, 0x22}, + {0x8a8a, 0xa2}, + {0x8a8b, 0xaf}, + {0x8a8c, 0x92}, + {0x8a8d, 0x31}, + {0x8a8e, 0xc2}, + {0x8a8f, 0xaf}, + {0x8a90, 0xe5}, + {0x8a91, 0x23}, + {0x8a92, 0x45}, + {0x8a93, 0x22}, + {0x8a94, 0x90}, + {0x8a95, 0x0e}, + {0x8a96, 0x5d}, + {0x8a97, 0x60}, + {0x8a98, 0x0b}, + {0x8a99, 0x12}, + {0x8a9a, 0x0b}, + {0x8a9b, 0x2b}, + {0x8a9c, 0xe0}, + {0x8a9d, 0xf5}, + {0x8a9e, 0x19}, + {0x8a9f, 0xe0}, + {0x8aa0, 0xf5}, + {0x8aa1, 0x1a}, + {0x8aa2, 0x80}, + {0x8aa3, 0x0f}, + {0x8aa4, 0x12}, + {0x8aa5, 0x0b}, + {0x8aa6, 0x2b}, + {0x8aa7, 0xe5}, + {0x8aa8, 0x1d}, + {0x8aa9, 0xf0}, + {0x8aaa, 0x90}, + {0x8aab, 0x0e}, + {0x8aac, 0x5f}, + {0x8aad, 0x12}, + {0x8aae, 0x0b}, + {0x8aaf, 0x2b}, + {0x8ab0, 0xe5}, + {0x8ab1, 0x1e}, + {0x8ab2, 0xf0}, + {0x8ab3, 0xa2}, + {0x8ab4, 0x31}, + {0x8ab5, 0x92}, + {0x8ab6, 0xaf}, + {0x8ab7, 0x22}, + {0x8ab8, 0xd2}, + {0x8ab9, 0x01}, + {0x8aba, 0xc2}, + {0x8abb, 0x02}, + {0x8abc, 0xe4}, + {0x8abd, 0xf5}, + {0x8abe, 0x40}, + {0x8abf, 0xf5}, + {0x8ac0, 0x3f}, + {0x8ac1, 0xd2}, + {0x8ac2, 0x34}, + {0x8ac3, 0xd2}, + {0x8ac4, 0x32}, + {0x8ac5, 0xd2}, + {0x8ac6, 0x35}, + {0x8ac7, 0xd2}, + {0x8ac8, 0x01}, + {0x8ac9, 0xc2}, + {0x8aca, 0x02}, + {0x8acb, 0xf5}, + {0x8acc, 0x40}, + {0x8acd, 0xf5}, + {0x8ace, 0x3f}, + {0x8acf, 0xd2}, + {0x8ad0, 0x34}, + {0x8ad1, 0xd2}, + {0x8ad2, 0x32}, + {0x8ad3, 0x22}, + {0x8ad4, 0x8f}, + {0x8ad5, 0x30}, + {0x8ad6, 0x8e}, + {0x8ad7, 0x2f}, + {0x8ad8, 0x8d}, + {0x8ad9, 0x2e}, + {0x8ada, 0x8c}, + {0x8adb, 0x2d}, + {0x8adc, 0x22}, + {0x8add, 0x12}, + {0x8ade, 0x04}, + {0x8adf, 0x47}, + {0x8ae0, 0x8f}, + {0x8ae1, 0x1e}, + {0x8ae2, 0x8e}, + {0x8ae3, 0x1d}, + {0x8ae4, 0x8d}, + {0x8ae5, 0x1c}, + {0x8ae6, 0x8c}, + {0x8ae7, 0x1b}, + {0x8ae8, 0x22}, + {0x8ae9, 0x93}, + {0x8aea, 0xf9}, + {0x8aeb, 0xf8}, + {0x8aec, 0x02}, + {0x8aed, 0x04}, + {0x8aee, 0x34}, + {0x8aef, 0x90}, + {0x8af0, 0x0e}, + {0x8af1, 0x81}, + {0x8af2, 0x12}, + {0x8af3, 0x04}, + {0x8af4, 0x47}, + {0x8af5, 0x8f}, + {0x8af6, 0x3b}, + {0x8af7, 0x8e}, + {0x8af8, 0x3a}, + {0x8af9, 0x8d}, + {0x8afa, 0x39}, + {0x8afb, 0x8c}, + {0x8afc, 0x38}, + {0x8afd, 0xd2}, + {0x8afe, 0x06}, + {0x8aff, 0x30}, + {0x8b00, 0x06}, + {0x8b01, 0x03}, + {0x8b02, 0xd3}, + {0x8b03, 0x80}, + {0x8b04, 0x01}, + {0x8b05, 0xc3}, + {0x8b06, 0x92}, + {0x8b07, 0x0e}, + {0x8b08, 0x22}, + {0x8b09, 0xc0}, + {0x8b0a, 0xe0}, + {0x8b0b, 0xc0}, + {0x8b0c, 0x83}, + {0x8b0d, 0xc0}, + {0x8b0e, 0x82}, + {0x8b0f, 0x90}, + {0x8b10, 0x3f}, + {0x8b11, 0x0d}, + {0x8b12, 0xe0}, + {0x8b13, 0xf5}, + {0x8b14, 0x28}, + {0x8b15, 0xe5}, + {0x8b16, 0x28}, + {0x8b17, 0xf0}, + {0x8b18, 0xd0}, + {0x8b19, 0x82}, + {0x8b1a, 0xd0}, + {0x8b1b, 0x83}, + {0x8b1c, 0xd0}, + {0x8b1d, 0xe0}, + {0x8b1e, 0x32}, + {0x8b1f, 0x78}, + {0x8b20, 0x7f}, + {0x8b21, 0xe4}, + {0x8b22, 0xf6}, + {0x8b23, 0xd8}, + {0x8b24, 0xfd}, + {0x8b25, 0x75}, + {0x8b26, 0x81}, + {0x8b27, 0xc0}, + {0x8b28, 0x02}, + {0x8b29, 0x09}, + {0x8b2a, 0xa5}, + {0x8b2b, 0xe4}, + {0x8b2c, 0x93}, + {0x8b2d, 0xfe}, + {0x8b2e, 0x74}, + {0x8b2f, 0x01}, + {0x8b30, 0x93}, + {0x8b31, 0xf5}, + {0x8b32, 0x82}, + {0x8b33, 0x8e}, + {0x8b34, 0x83}, + {0x8b35, 0x22}, + {0x8b36, 0x8f}, + {0x8b37, 0x82}, + {0x8b38, 0x8e}, + {0x8b39, 0x83}, + {0x8b3a, 0x75}, + {0x8b3b, 0xf0}, + {0x8b3c, 0x04}, + {0x8b3d, 0xed}, + {0x8b3e, 0x02}, + {0x8b3f, 0x04}, + {0x8b40, 0x89}, + {0x8b41, 0x00}, + {0x8b42, 0x00}, + {0x8b43, 0x00}, + {0x8b44, 0x00}, + {0x8b45, 0x00}, + {0x8b46, 0x00}, + {0x8b47, 0x00}, + {0x8b48, 0x00}, + {0x8b49, 0x00}, + {0x8b4a, 0x00}, + {0x8b4b, 0x00}, + {0x8b4c, 0x00}, + {0x8b4d, 0x00}, + {0x8b4e, 0x00}, + {0x8b4f, 0x00}, + {0x8b50, 0x00}, + {0x8b51, 0x00}, + {0x8b52, 0x00}, + {0x8b53, 0x00}, + {0x8b54, 0x00}, + {0x8b55, 0x00}, + {0x8b56, 0x00}, + {0x8b57, 0x00}, + {0x8b58, 0x00}, + {0x8b59, 0x00}, + {0x8b5a, 0x00}, + {0x8b5b, 0x00}, + {0x8b5c, 0x00}, + {0x8b5d, 0x00}, + {0x8b5e, 0x00}, + {0x8b5f, 0x00}, + {0x8b60, 0x00}, + {0x8b61, 0x00}, + {0x8b62, 0x00}, + {0x8b63, 0x00}, + {0x8b64, 0x00}, + {0x8b65, 0x00}, + {0x8b66, 0x00}, + {0x8b67, 0x00}, + {0x8b68, 0x00}, + {0x8b69, 0x00}, + {0x8b6a, 0x00}, + {0x8b6b, 0x00}, + {0x8b6c, 0x00}, + {0x8b6d, 0x00}, + {0x8b6e, 0x00}, + {0x8b6f, 0x00}, + {0x8b70, 0x00}, + {0x8b71, 0x00}, + {0x8b72, 0x00}, + {0x8b73, 0x00}, + {0x8b74, 0x00}, + {0x8b75, 0x00}, + {0x8b76, 0x00}, + {0x8b77, 0x00}, + {0x8b78, 0x00}, + {0x8b79, 0x00}, + {0x8b7a, 0x00}, + {0x8b7b, 0x00}, + {0x8b7c, 0x00}, + {0x8b7d, 0x00}, + {0x8b7e, 0x00}, + {0x8b7f, 0x00}, + {0x8b80, 0x00}, + {0x8b81, 0x00}, + {0x8b82, 0x00}, + {0x8b83, 0x00}, + {0x8b84, 0x00}, + {0x8b85, 0x00}, + {0x8b86, 0x00}, + {0x8b87, 0x00}, + {0x8b88, 0x00}, + {0x8b89, 0x00}, + {0x8b8a, 0x00}, + {0x8b8b, 0x00}, + {0x8b8c, 0x00}, + {0x8b8d, 0x00}, + {0x8b8e, 0x00}, + {0x8b8f, 0x00}, + {0x8b90, 0x00}, + {0x8b91, 0x00}, + {0x8b92, 0x00}, + {0x8b93, 0x00}, + {0x8b94, 0x00}, + {0x8b95, 0x00}, + {0x8b96, 0x00}, + {0x8b97, 0x00}, + {0x8b98, 0x00}, + {0x8b99, 0x00}, + {0x8b9a, 0x00}, + {0x8b9b, 0x00}, + {0x8b9c, 0x00}, + {0x8b9d, 0x00}, + {0x8b9e, 0x00}, + {0x8b9f, 0x00}, + {0x8ba0, 0x00}, + {0x8ba1, 0x00}, + {0x8ba2, 0x00}, + {0x8ba3, 0x00}, + {0x8ba4, 0x00}, + {0x8ba5, 0x00}, + {0x8ba6, 0x00}, + {0x8ba7, 0x00}, + {0x8ba8, 0x00}, + {0x8ba9, 0x00}, + {0x8baa, 0x00}, + {0x8bab, 0x00}, + {0x8bac, 0x00}, + {0x8bad, 0x00}, + {0x8bae, 0x00}, + {0x8baf, 0x00}, + {0x8bb0, 0x00}, + {0x8bb1, 0x00}, + {0x8bb2, 0x00}, + {0x8bb3, 0x00}, + {0x8bb4, 0x00}, + {0x8bb5, 0x00}, + {0x8bb6, 0x00}, + {0x8bb7, 0x00}, + {0x8bb8, 0x00}, + {0x8bb9, 0x00}, + {0x8bba, 0x00}, + {0x8bbb, 0x00}, + {0x8bbc, 0x00}, + {0x8bbd, 0x00}, + {0x8bbe, 0x00}, + {0x8bbf, 0x00}, + {0x8bc0, 0x00}, + {0x8bc1, 0x00}, + {0x8bc2, 0x00}, + {0x8bc3, 0x00}, + {0x8bc4, 0x00}, + {0x8bc5, 0x00}, + {0x8bc6, 0x00}, + {0x8bc7, 0x00}, + {0x8bc8, 0x00}, + {0x8bc9, 0x00}, + {0x8bca, 0x00}, + {0x8bcb, 0x00}, + {0x8bcc, 0x00}, + {0x8bcd, 0x00}, + {0x8bce, 0x00}, + {0x8bcf, 0x00}, + {0x8bd0, 0x00}, + {0x8bd1, 0x00}, + {0x8bd2, 0x00}, + {0x8bd3, 0x00}, + {0x8bd4, 0x00}, + {0x8bd5, 0x00}, + {0x8bd6, 0x00}, + {0x8bd7, 0x00}, + {0x8bd8, 0x00}, + {0x8bd9, 0x00}, + {0x8bda, 0x00}, + {0x8bdb, 0x00}, + {0x8bdc, 0x00}, + {0x8bdd, 0x00}, + {0x8bde, 0x00}, + {0x8bdf, 0x00}, + {0x8be0, 0x00}, + {0x8be1, 0x00}, + {0x8be2, 0x00}, + {0x8be3, 0x00}, + {0x8be4, 0x00}, + {0x8be5, 0x00}, + {0x8be6, 0x00}, + {0x8be7, 0x00}, + {0x8be8, 0x00}, + {0x8be9, 0x00}, + {0x8bea, 0x00}, + {0x8beb, 0x00}, + {0x8bec, 0x00}, + {0x8bed, 0x00}, + {0x8bee, 0x00}, + {0x8bef, 0x00}, + {0x8bf0, 0x00}, + {0x8bf1, 0x00}, + {0x8bf2, 0x00}, + {0x8bf3, 0x00}, + {0x8bf4, 0x00}, + {0x8bf5, 0x00}, + {0x8bf6, 0x00}, + {0x8bf7, 0x00}, + {0x8bf8, 0x00}, + {0x8bf9, 0x00}, + {0x8bfa, 0x00}, + {0x8bfb, 0x00}, + {0x8bfc, 0x00}, + {0x8bfd, 0x00}, + {0x8bfe, 0x00}, + {0x8bff, 0x00}, + {0x8c00, 0x00}, + {0x8c01, 0x00}, + {0x8c02, 0x00}, + {0x8c03, 0x00}, + {0x8c04, 0x00}, + {0x8c05, 0x00}, + {0x8c06, 0x00}, + {0x8c07, 0x00}, + {0x8c08, 0x00}, + {0x8c09, 0x00}, + {0x8c0a, 0x00}, + {0x8c0b, 0x00}, + {0x8c0c, 0x00}, + {0x8c0d, 0x00}, + {0x8c0e, 0x00}, + {0x8c0f, 0x00}, + {0x8c10, 0x00}, + {0x8c11, 0x00}, + {0x8c12, 0x00}, + {0x8c13, 0x00}, + {0x8c14, 0x00}, + {0x8c15, 0x00}, + {0x8c16, 0x00}, + {0x8c17, 0x00}, + {0x8c18, 0x00}, + {0x8c19, 0x00}, + {0x8c1a, 0x00}, + {0x8c1b, 0x00}, + {0x8c1c, 0x00}, + {0x8c1d, 0x00}, + {0x8c1e, 0x00}, + {0x8c1f, 0x00}, + {0x8c20, 0x00}, + {0x8c21, 0x00}, + {0x8c22, 0x00}, + {0x8c23, 0x00}, + {0x8c24, 0x00}, + {0x8c25, 0x00}, + {0x8c26, 0x00}, + {0x8c27, 0x00}, + {0x8c28, 0x00}, + {0x8c29, 0x00}, + {0x8c2a, 0x00}, + {0x8c2b, 0x00}, + {0x8c2c, 0x00}, + {0x8c2d, 0x00}, + {0x8c2e, 0x00}, + {0x8c2f, 0x00}, + {0x8c30, 0x00}, + {0x8c31, 0x00}, + {0x8c32, 0x00}, + {0x8c33, 0x00}, + {0x8c34, 0x00}, + {0x8c35, 0x00}, + {0x8c36, 0x00}, + {0x8c37, 0x00}, + {0x8c38, 0x00}, + {0x8c39, 0x00}, + {0x8c3a, 0x00}, + {0x8c3b, 0x00}, + {0x8c3c, 0x00}, + {0x8c3d, 0x00}, + {0x8c3e, 0x00}, + {0x8c3f, 0x00}, + {0x8c40, 0x00}, + {0x8c41, 0x00}, + {0x8c42, 0x00}, + {0x8c43, 0x00}, + {0x8c44, 0x00}, + {0x8c45, 0x00}, + {0x8c46, 0x00}, + {0x8c47, 0x00}, + {0x8c48, 0x00}, + {0x8c49, 0x00}, + {0x8c4a, 0x00}, + {0x8c4b, 0x00}, + {0x8c4c, 0x00}, + {0x8c4d, 0x00}, + {0x8c4e, 0x00}, + {0x8c4f, 0x00}, + {0x8c50, 0x00}, + {0x8c51, 0x00}, + {0x8c52, 0x00}, + {0x8c53, 0x00}, + {0x8c54, 0x00}, + {0x8c55, 0x00}, + {0x8c56, 0x00}, + {0x8c57, 0x00}, + {0x8c58, 0x00}, + {0x8c59, 0x00}, + {0x8c5a, 0x00}, + {0x8c5b, 0x00}, + {0x8c5c, 0x00}, + {0x8c5d, 0x00}, + {0x8c5e, 0x00}, + {0x8c5f, 0x00}, + {0x8c60, 0x00}, + {0x8c61, 0x00}, + {0x8c62, 0x00}, + {0x8c63, 0x00}, + {0x8c64, 0x00}, + {0x8c65, 0x00}, + {0x8c66, 0x00}, + {0x8c67, 0x00}, + {0x8c68, 0x00}, + {0x8c69, 0x00}, + {0x8c6a, 0x00}, + {0x8c6b, 0x00}, + {0x8c6c, 0x00}, + {0x8c6d, 0x00}, + {0x8c6e, 0x00}, + {0x8c6f, 0x00}, + {0x8c70, 0x00}, + {0x8c71, 0x00}, + {0x8c72, 0x00}, + {0x8c73, 0x00}, + {0x8c74, 0x00}, + {0x8c75, 0x00}, + {0x8c76, 0x00}, + {0x8c77, 0x00}, + {0x8c78, 0x00}, + {0x8c79, 0x00}, + {0x8c7a, 0x00}, + {0x8c7b, 0x00}, + {0x8c7c, 0x00}, + {0x8c7d, 0x00}, + {0x8c7e, 0x00}, + {0x8c7f, 0x00}, + {0x8c80, 0x00}, + {0x8c81, 0x00}, + {0x8c82, 0x00}, + {0x8c83, 0x00}, + {0x8c84, 0x00}, + {0x8c85, 0x00}, + {0x8c86, 0x00}, + {0x8c87, 0x00}, + {0x8c88, 0x00}, + {0x8c89, 0x00}, + {0x8c8a, 0x00}, + {0x8c8b, 0x00}, + {0x8c8c, 0x00}, + {0x8c8d, 0x00}, + {0x8c8e, 0x00}, + {0x8c8f, 0x00}, + {0x8c90, 0x00}, + {0x8c91, 0x00}, + {0x8c92, 0x00}, + {0x8c93, 0x00}, + {0x8c94, 0x00}, + {0x8c95, 0x00}, + {0x8c96, 0x00}, + {0x8c97, 0x00}, + {0x8c98, 0x00}, + {0x8c99, 0x00}, + {0x8c9a, 0x00}, + {0x8c9b, 0x00}, + {0x8c9c, 0x00}, + {0x8c9d, 0x00}, + {0x8c9e, 0x00}, + {0x8c9f, 0x00}, + {0x8ca0, 0x00}, + {0x8ca1, 0x00}, + {0x8ca2, 0x00}, + {0x8ca3, 0x00}, + {0x8ca4, 0x00}, + {0x8ca5, 0x00}, + {0x8ca6, 0x00}, + {0x8ca7, 0x00}, + {0x8ca8, 0x00}, + {0x8ca9, 0x00}, + {0x8caa, 0x00}, + {0x8cab, 0x00}, + {0x8cac, 0x00}, + {0x8cad, 0x00}, + {0x8cae, 0x00}, + {0x8caf, 0x00}, + {0x8cb0, 0x00}, + {0x8cb1, 0x00}, + {0x8cb2, 0x00}, + {0x8cb3, 0x00}, + {0x8cb4, 0x00}, + {0x8cb5, 0x00}, + {0x8cb6, 0x00}, + {0x8cb7, 0x00}, + {0x8cb8, 0x00}, + {0x8cb9, 0x00}, + {0x8cba, 0x00}, + {0x8cbb, 0x00}, + {0x8cbc, 0x00}, + {0x8cbd, 0x00}, + {0x8cbe, 0x00}, + {0x8cbf, 0x00}, + {0x8cc0, 0x00}, + {0x8cc1, 0x00}, + {0x8cc2, 0x00}, + {0x8cc3, 0x00}, + {0x8cc4, 0x00}, + {0x8cc5, 0x00}, + {0x8cc6, 0x00}, + {0x8cc7, 0x00}, + {0x8cc8, 0x00}, + {0x8cc9, 0x00}, + {0x8cca, 0x00}, + {0x8ccb, 0x00}, + {0x8ccc, 0x00}, + {0x8ccd, 0x00}, + {0x8cce, 0x00}, + {0x8ccf, 0x00}, + {0x8cd0, 0x00}, + {0x8cd1, 0x00}, + {0x8cd2, 0x00}, + {0x8cd3, 0x00}, + {0x8cd4, 0x00}, + {0x8cd5, 0x00}, + {0x8cd6, 0x00}, + {0x8cd7, 0x00}, + {0x8cd8, 0x00}, + {0x8cd9, 0x00}, + {0x8cda, 0x00}, + {0x8cdb, 0x00}, + {0x8cdc, 0x00}, + {0x8cdd, 0x00}, + {0x8cde, 0x00}, + {0x8cdf, 0x00}, + {0x8ce0, 0x00}, + {0x8ce1, 0x00}, + {0x8ce2, 0x00}, + {0x8ce3, 0x00}, + {0x8ce4, 0x00}, + {0x8ce5, 0x00}, + {0x8ce6, 0x00}, + {0x8ce7, 0x00}, + {0x8ce8, 0x00}, + {0x8ce9, 0x00}, + {0x8cea, 0x00}, + {0x8ceb, 0x00}, + {0x8cec, 0x00}, + {0x8ced, 0x00}, + {0x8cee, 0x00}, + {0x8cef, 0x00}, + {0x8cf0, 0x00}, + {0x8cf1, 0x00}, + {0x8cf2, 0x00}, + {0x8cf3, 0x00}, + {0x8cf4, 0x00}, + {0x8cf5, 0x00}, + {0x8cf6, 0x00}, + {0x8cf7, 0x00}, + {0x8cf8, 0x00}, + {0x8cf9, 0x00}, + {0x8cfa, 0x00}, + {0x8cfb, 0x00}, + {0x8cfc, 0x00}, + {0x8cfd, 0x00}, + {0x8cfe, 0x00}, + {0x8cff, 0x00}, + {0x8d00, 0x00}, + {0x8d01, 0x00}, + {0x8d02, 0x00}, + {0x8d03, 0x00}, + {0x8d04, 0x00}, + {0x8d05, 0x00}, + {0x8d06, 0x00}, + {0x8d07, 0x00}, + {0x8d08, 0x00}, + {0x8d09, 0x00}, + {0x8d0a, 0x00}, + {0x8d0b, 0x00}, + {0x8d0c, 0x00}, + {0x8d0d, 0x00}, + {0x8d0e, 0x00}, + {0x8d0f, 0x00}, + {0x8d10, 0x00}, + {0x8d11, 0x00}, + {0x8d12, 0x00}, + {0x8d13, 0x00}, + {0x8d14, 0x00}, + {0x8d15, 0x00}, + {0x8d16, 0x00}, + {0x8d17, 0x00}, + {0x8d18, 0x00}, + {0x8d19, 0x00}, + {0x8d1a, 0x00}, + {0x8d1b, 0x00}, + {0x8d1c, 0x00}, + {0x8d1d, 0x00}, + {0x8d1e, 0x00}, + {0x8d1f, 0x00}, + {0x8d20, 0x00}, + {0x8d21, 0x00}, + {0x8d22, 0x00}, + {0x8d23, 0x00}, + {0x8d24, 0x00}, + {0x8d25, 0x00}, + {0x8d26, 0x00}, + {0x8d27, 0x00}, + {0x8d28, 0x00}, + {0x8d29, 0x00}, + {0x8d2a, 0x00}, + {0x8d2b, 0x00}, + {0x8d2c, 0x00}, + {0x8d2d, 0x00}, + {0x8d2e, 0x00}, + {0x8d2f, 0x00}, + {0x8d30, 0x00}, + {0x8d31, 0x00}, + {0x8d32, 0x00}, + {0x8d33, 0x00}, + {0x8d34, 0x00}, + {0x8d35, 0x00}, + {0x8d36, 0x00}, + {0x8d37, 0x00}, + {0x8d38, 0x00}, + {0x8d39, 0x00}, + {0x8d3a, 0x00}, + {0x8d3b, 0x00}, + {0x8d3c, 0x00}, + {0x8d3d, 0x00}, + {0x8d3e, 0x00}, + {0x8d3f, 0x00}, + {0x8d40, 0x00}, + {0x8d41, 0x00}, + {0x8d42, 0x00}, + {0x8d43, 0x00}, + {0x8d44, 0x00}, + {0x8d45, 0x00}, + {0x8d46, 0x00}, + {0x8d47, 0x00}, + {0x8d48, 0x00}, + {0x8d49, 0x00}, + {0x8d4a, 0x00}, + {0x8d4b, 0x00}, + {0x8d4c, 0x00}, + {0x8d4d, 0x00}, + {0x8d4e, 0x00}, + {0x8d4f, 0x00}, + {0x8d50, 0x00}, + {0x8d51, 0x00}, + {0x8d52, 0x00}, + {0x8d53, 0x00}, + {0x8d54, 0x00}, + {0x8d55, 0x00}, + {0x8d56, 0x00}, + {0x8d57, 0x00}, + {0x8d58, 0x00}, + {0x8d59, 0x00}, + {0x8d5a, 0x00}, + {0x8d5b, 0x00}, + {0x8d5c, 0x00}, + {0x8d5d, 0x00}, + {0x8d5e, 0x00}, + {0x8d5f, 0x00}, + {0x8d60, 0x00}, + {0x8d61, 0x00}, + {0x8d62, 0x00}, + {0x8d63, 0x00}, + {0x8d64, 0x00}, + {0x8d65, 0x00}, + {0x8d66, 0x00}, + {0x8d67, 0x00}, + {0x8d68, 0x00}, + {0x8d69, 0x00}, + {0x8d6a, 0x00}, + {0x8d6b, 0x00}, + {0x8d6c, 0x00}, + {0x8d6d, 0x00}, + {0x8d6e, 0x00}, + {0x8d6f, 0x00}, + {0x8d70, 0x00}, + {0x8d71, 0x00}, + {0x8d72, 0x00}, + {0x8d73, 0x00}, + {0x8d74, 0x00}, + {0x8d75, 0x00}, + {0x8d76, 0x00}, + {0x8d77, 0x00}, + {0x8d78, 0x00}, + {0x8d79, 0x00}, + {0x8d7a, 0x00}, + {0x8d7b, 0x00}, + {0x8d7c, 0x00}, + {0x8d7d, 0x00}, + {0x8d7e, 0x00}, + {0x8d7f, 0x00}, + {0x8d80, 0x00}, + {0x8d81, 0x00}, + {0x8d82, 0x00}, + {0x8d83, 0x00}, + {0x8d84, 0x00}, + {0x8d85, 0x00}, + {0x8d86, 0x00}, + {0x8d87, 0x00}, + {0x8d88, 0x00}, + {0x8d89, 0x00}, + {0x8d8a, 0x00}, + {0x8d8b, 0x00}, + {0x8d8c, 0x00}, + {0x8d8d, 0x00}, + {0x8d8e, 0x00}, + {0x8d8f, 0x00}, + {0x8d90, 0x00}, + {0x8d91, 0x00}, + {0x8d92, 0x00}, + {0x8d93, 0x00}, + {0x8d94, 0x00}, + {0x8d95, 0x00}, + {0x8d96, 0x00}, + {0x8d97, 0x00}, + {0x8d98, 0x00}, + {0x8d99, 0x00}, + {0x8d9a, 0x00}, + {0x8d9b, 0x00}, + {0x8d9c, 0x00}, + {0x8d9d, 0x00}, + {0x8d9e, 0x00}, + {0x8d9f, 0x00}, + {0x8da0, 0x00}, + {0x8da1, 0x00}, + {0x8da2, 0x00}, + {0x8da3, 0x00}, + {0x8da4, 0x00}, + {0x8da5, 0x00}, + {0x8da6, 0x00}, + {0x8da7, 0x00}, + {0x8da8, 0x00}, + {0x8da9, 0x00}, + {0x8daa, 0x00}, + {0x8dab, 0x00}, + {0x8dac, 0x00}, + {0x8dad, 0x00}, + {0x8dae, 0x00}, + {0x8daf, 0x00}, + {0x8db0, 0x00}, + {0x8db1, 0x00}, + {0x8db2, 0x00}, + {0x8db3, 0x00}, + {0x8db4, 0x00}, + {0x8db5, 0x00}, + {0x8db6, 0x00}, + {0x8db7, 0x00}, + {0x8db8, 0x00}, + {0x8db9, 0x00}, + {0x8dba, 0x00}, + {0x8dbb, 0x00}, + {0x8dbc, 0x00}, + {0x8dbd, 0x00}, + {0x8dbe, 0x00}, + {0x8dbf, 0x00}, + {0x8dc0, 0x00}, + {0x8dc1, 0x00}, + {0x8dc2, 0x00}, + {0x8dc3, 0x00}, + {0x8dc4, 0x00}, + {0x8dc5, 0x00}, + {0x8dc6, 0x00}, + {0x8dc7, 0x00}, + {0x8dc8, 0x00}, + {0x8dc9, 0x00}, + {0x8dca, 0x00}, + {0x8dcb, 0x00}, + {0x8dcc, 0x00}, + {0x8dcd, 0x00}, + {0x8dce, 0x00}, + {0x8dcf, 0x00}, + {0x8dd0, 0x00}, + {0x8dd1, 0x00}, + {0x8dd2, 0x00}, + {0x8dd3, 0x00}, + {0x8dd4, 0x00}, + {0x8dd5, 0x00}, + {0x8dd6, 0x00}, + {0x8dd7, 0x00}, + {0x8dd8, 0x00}, + {0x8dd9, 0x00}, + {0x8dda, 0x00}, + {0x8ddb, 0x00}, + {0x8ddc, 0x00}, + {0x8ddd, 0x00}, + {0x8dde, 0x00}, + {0x8ddf, 0x00}, + {0x8de0, 0x00}, + {0x8de1, 0x00}, + {0x8de2, 0x00}, + {0x8de3, 0x00}, + {0x8de4, 0x00}, + {0x8de5, 0x00}, + {0x8de6, 0x00}, + {0x8de7, 0x00}, + {0x8de8, 0x00}, + {0x8de9, 0x00}, + {0x8dea, 0x00}, + {0x8deb, 0x00}, + {0x8dec, 0x00}, + {0x8ded, 0x00}, + {0x8dee, 0x00}, + {0x8def, 0x00}, + {0x8df0, 0x00}, + {0x8df1, 0x00}, + {0x8df2, 0x00}, + {0x8df3, 0x00}, + {0x8df4, 0x00}, + {0x8df5, 0x00}, + {0x8df6, 0x00}, + {0x8df7, 0x00}, + {0x8df8, 0x00}, + {0x8df9, 0x00}, + {0x8dfa, 0x00}, + {0x8dfb, 0x00}, + {0x8dfc, 0x00}, + {0x8dfd, 0x00}, + {0x8dfe, 0x00}, + {0x8dff, 0x00}, + {0x8e00, 0x11}, + {0x8e01, 0x02}, + {0x8e02, 0x28}, + {0x8e03, 0x09}, + {0x8e04, 0x00}, + {0x8e05, 0x12}, + {0x8e06, 0x4f}, + {0x8e07, 0x56}, + {0x8e08, 0x54}, + {0x8e09, 0x20}, + {0x8e0a, 0x20}, + {0x8e0b, 0x20}, + {0x8e0c, 0x20}, + {0x8e0d, 0x20}, + {0x8e0e, 0x20}, + {0x8e0f, 0x01}, + {0x8e10, 0x10}, + {0x8e11, 0x00}, + {0x8e12, 0x56}, + {0x8e13, 0x40}, + {0x8e14, 0x1a}, + {0x8e15, 0x30}, + {0x8e16, 0x29}, + {0x8e17, 0x7e}, + {0x8e18, 0x00}, + {0x8e19, 0x30}, + {0x8e1a, 0x04}, + {0x8e1b, 0x20}, + {0x8e1c, 0xdf}, + {0x8e1d, 0x30}, + {0x8e1e, 0x05}, + {0x8e1f, 0x40}, + {0x8e20, 0xbf}, + {0x8e21, 0x50}, + {0x8e22, 0x25}, + {0x8e23, 0x04}, + {0x8e24, 0xfb}, + {0x8e25, 0x50}, + {0x8e26, 0x03}, + {0x8e27, 0x00}, + {0x8e28, 0xfd}, + {0x8e29, 0x50}, + {0x8e2a, 0x27}, + {0x8e2b, 0x01}, + {0x8e2c, 0xfe}, + {0x8e2d, 0x60}, + {0x8e2e, 0x00}, + {0x8e2f, 0x11}, + {0x8e30, 0x00}, + {0x8e31, 0x3f}, + {0x8e32, 0x05}, + {0x8e33, 0x30}, + {0x8e34, 0x00}, + {0x8e35, 0x3f}, + {0x8e36, 0x06}, + {0x8e37, 0x22}, + {0x8e38, 0x00}, + {0x8e39, 0x3f}, + {0x8e3a, 0x01}, + {0x8e3b, 0x29}, + {0x8e3c, 0x00}, + {0x8e3d, 0x3f}, + {0x8e3e, 0x02}, + {0x8e3f, 0x00}, + {0x8e40, 0x00}, + {0x8e41, 0x36}, + {0x8e42, 0x06}, + {0x8e43, 0x07}, + {0x8e44, 0x00}, + {0x8e45, 0x3f}, + {0x8e46, 0x0b}, + {0x8e47, 0x0f}, + {0x8e48, 0xf0}, + {0x8e49, 0x30}, + {0x8e4a, 0x01}, + {0x8e4b, 0x40}, + {0x8e4c, 0xbf}, + {0x8e4d, 0x30}, + {0x8e4e, 0x01}, + {0x8e4f, 0x00}, + {0x8e50, 0xbf}, + {0x8e51, 0x30}, + {0x8e52, 0x29}, + {0x8e53, 0x70}, + {0x8e54, 0x00}, + {0x8e55, 0x3a}, + {0x8e56, 0x00}, + {0x8e57, 0x01}, + {0x8e58, 0xfe}, + {0x8e59, 0x3a}, + {0x8e5a, 0x00}, + {0x8e5b, 0x00}, + {0x8e5c, 0xfe}, + {0x8e5d, 0x36}, + {0x8e5e, 0x03}, + {0x8e5f, 0x36}, + {0x8e60, 0x02}, + {0x8e61, 0x41}, + {0x8e62, 0x44}, + {0x8e63, 0x58}, + {0x8e64, 0x20}, + {0x8e65, 0x18}, + {0x8e66, 0x10}, + {0x8e67, 0x0a}, + {0x8e68, 0x04}, + {0x8e69, 0x04}, + {0x8e6a, 0x00}, + {0x8e6b, 0x03}, + {0x8e6c, 0xff}, + {0x8e6d, 0x64}, + {0x8e6e, 0x00}, + {0x8e6f, 0x00}, + {0x8e70, 0x80}, + {0x8e71, 0x00}, + {0x8e72, 0x00}, + {0x8e73, 0x00}, + {0x8e74, 0x00}, + {0x8e75, 0x00}, + {0x8e76, 0x00}, + {0x8e77, 0x02}, + {0x8e78, 0x04}, + {0x8e79, 0x06}, + {0x8e7a, 0x00}, + {0x8e7b, 0x03}, + {0x8e7c, 0x98}, + {0x8e7d, 0x00}, + {0x8e7e, 0xcc}, + {0x8e7f, 0x50}, + {0x8e80, 0x3c}, + {0x8e81, 0x28}, + {0x8e82, 0x1e}, + {0x8e83, 0x0c}, + {0x8e84, 0x0c}, + {0x8e85, 0x00}, + {0x8e86, 0x00}, + {0x8e87, 0x00}, + {0x8e88, 0x6e}, + {0x8e89, 0x05}, + {0x8e8a, 0x05}, + {0x8e8b, 0x00}, + {0x8e8c, 0xa5}, + {0x8e8d, 0x5a}, + {0x3022, 0x00}, + {0x3023, 0x00}, + {0x3024, 0x00}, + {0x3025, 0x00}, + {0x3026, 0x00}, + {0x3027, 0x00}, + {0x3028, 0x00}, + {0x3029, 0xFF}, + {0x3000, 0x00}, + {OV5640_TABLE_END, 0x0000} +}; + +static struct ov5640_reg tbl_single_focus[] = { + {0x3023, 0x01}, + {0x3022, 0x03}, + {OV5640_TABLE_END, 0x0000} +}; + +static struct ov5640_reg tbl_release_focus[] = { + {0x3023, 0x01}, + {0x3022, 0x08}, + {OV5640_TABLE_END, 0x0000} +}; + +#endif diff --git a/drivers/media/video/tegra/ov5650.c b/drivers/media/video/tegra/ov5650.c index 3adb46a3bb80..3e2d23ab3374 100644 --- a/drivers/media/video/tegra/ov5650.c +++ b/drivers/media/video/tegra/ov5650.c @@ -39,6 +39,11 @@ struct ov5650_info { enum StereoCameraMode camera_mode; struct ov5650_sensor left; struct ov5650_sensor right; + struct ov5650_sensordata sensor_data; + struct mutex mutex_le; + struct mutex mutex_ri; + int power_refcnt_le; + int power_refcnt_ri; u8 i2c_trans_buf[SIZEOF_I2C_TRANSBUF]; }; @@ -788,7 +793,7 @@ static int ov5650_read_reg(struct i2c_client *client, u16 addr, u8 *val) err = i2c_transfer(client->adapter, msg, 2); - if (err != 1) + if (err != 2) return -EINVAL; *val = data[2]; @@ -1245,31 +1250,71 @@ static int ov5650_test_pattern(struct ov5650_info *info, } static int set_power_helper(struct ov5650_platform_data *pdata, - int powerLevel) + int powerLevel, int *ref_cnt) { if (pdata) { - if (powerLevel && pdata->power_on) - pdata->power_on(); - else if (pdata->power_off) - pdata->power_off(); + if (powerLevel && pdata->power_on) { + if (*ref_cnt == 0) + pdata->power_on(); + *ref_cnt = *ref_cnt + 1; + } + else if (pdata->power_off) { + *ref_cnt = *ref_cnt - 1; + if (*ref_cnt <= 0) + pdata->power_off(); + } } return 0; } -static int ov5650_set_power(int powerLevel) +static int ov5650_set_power(struct ov5650_info *info, int powerLevel) { pr_info("%s: powerLevel=%d camera mode=%d\n", __func__, powerLevel, - stereo_ov5650_info->camera_mode); + info->camera_mode); - if (StereoCameraMode_Left & stereo_ov5650_info->camera_mode) - set_power_helper(stereo_ov5650_info->left.pdata, powerLevel); + if (StereoCameraMode_Left & info->camera_mode) { + mutex_lock(&info->mutex_le); + set_power_helper(info->left.pdata, powerLevel, + &info->power_refcnt_le); + mutex_unlock(&info->mutex_le); + } - if (StereoCameraMode_Right & stereo_ov5650_info->camera_mode) - set_power_helper(stereo_ov5650_info->right.pdata, powerLevel); + if (StereoCameraMode_Right & info->camera_mode) { + mutex_lock(&info->mutex_ri); + set_power_helper(info->right.pdata, powerLevel, + &info->power_refcnt_ri); + mutex_unlock(&info->mutex_ri); + } return 0; } +static int ov5650_get_sensor_id(struct ov5650_info *info) +{ + int ret = 0; + int i; + u8 bak; + + pr_info("%s\n", __func__); + if (info->sensor_data.fuse_id_size) + return 0; + + ov5650_set_power(info, 1); + + for (i = 0; i < 5; i++) { + ret |= ov5650_write_reg_helper(info, 0x3d00, i); + ret |= ov5650_read_reg_helper(info, 0x3d04, + &bak); + info->sensor_data.fuse_id[i] = bak; + } + + if (!ret) + info->sensor_data.fuse_id_size = i; + + ov5650_set_power(info, 0); + return ret; +} + static long ov5650_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1280,13 +1325,13 @@ static long ov5650_ioctl(struct file *file, case OV5650_IOCTL_SET_CAMERA_MODE: { if (info->camera_mode != arg) { - err = ov5650_set_power(0); + err = ov5650_set_power(info, 0); if (err) { pr_info("%s %d\n", __func__, __LINE__); return err; } info->camera_mode = arg; - err = ov5650_set_power(1); + err = ov5650_set_power(info, 1); if (err) return err; } @@ -1344,6 +1389,21 @@ static long ov5650_ioctl(struct file *file, } return ov5650_set_group_hold(info, &ae); } + case OV5650_IOCTL_GET_SENSORDATA: + { + err = ov5650_get_sensor_id(info); + if (err) { + pr_err("%s %d %d\n", __func__, __LINE__, err); + return err; + } + if (copy_to_user((void __user *)arg, + &info->sensor_data, + sizeof(struct ov5650_sensordata))) { + pr_info("%s %d\n", __func__, __LINE__); + return -EFAULT; + } + return 0; + } default: return -EINVAL; } @@ -1354,13 +1414,15 @@ static int ov5650_open(struct inode *inode, struct file *file) { pr_info("%s\n", __func__); file->private_data = stereo_ov5650_info; - ov5650_set_power(1); + ov5650_set_power(stereo_ov5650_info, 1); return 0; } int ov5650_release(struct inode *inode, struct file *file) { - ov5650_set_power(0); + struct ov5650_info *info = file->private_data; + + ov5650_set_power(info, 0); file->private_data = NULL; return 0; } @@ -1426,6 +1488,8 @@ static int left_ov5650_probe(struct i2c_client *client, stereo_ov5650_info->left.pdata = client->dev.platform_data; stereo_ov5650_info->left.i2c_client = client; + mutex_init(&stereo_ov5650_info->mutex_le); + mutex_init(&stereo_ov5650_info->mutex_ri); return 0; } @@ -1517,4 +1581,4 @@ static void __exit ov5650_exit(void) module_init(ov5650_init); module_exit(ov5650_exit); - +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/ov9726.c b/drivers/media/video/tegra/ov9726.c index 655d07c736a8..378d46fabedf 100644 --- a/drivers/media/video/tegra/ov9726.c +++ b/drivers/media/video/tegra/ov9726.c @@ -843,3 +843,4 @@ static void __exit ov9726_exit(void) module_init(ov9726_init); module_exit(ov9726_exit); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/sh532u.c b/drivers/media/video/tegra/sh532u.c index 7db14fcf2573..f41b44ce9530 100644 --- a/drivers/media/video/tegra/sh532u.c +++ b/drivers/media/video/tegra/sh532u.c @@ -1,7 +1,7 @@ /* * SH532U focuser driver. * - * Copyright (C) 2011 NVIDIA Corporation. + * Copyright (C) 2011-2012 NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -21,7 +21,7 @@ /* Implementation * -------------- * The board level details about the device need to be provided in the board - * file with the sh532u_platform_data structure. + * file with the <device>_platform_data structure. * Standard among NVC kernel drivers in this structure is: * .cfg = Use the NVC_CFG_ defines that are in nvc.h. * Descriptions of the configuration options are with the defines. @@ -40,11 +40,26 @@ * .num = 2, * .sync = 1, * The above example sync's device 1 and 2. + * To disable sync, set .sync = 0. Note that the .num = 0 device is + * not allowed to be synced to. * This is typically used for stereo applications. * .dev_name = The MISC driver name the device registers as. If not used, * then the part number of the device is used for the driver name. * If using the NVC user driver then use the name found in this * driver under _default_pdata. + * .gpio_count = The ARRAY_SIZE of the nvc_gpio_pdata table. + * .gpio = A pointer to the nvc_gpio_pdata structure's platform GPIO data. + * The GPIO mechanism works by cross referencing the .gpio_type key + * among the nvc_gpio_pdata GPIO data and the driver's nvc_gpio_init + * GPIO data to build a GPIO table the driver can use. The GPIO's + * defined in the device header file's _gpio_type enum are the + * gpio_type keys for the nvc_gpio_pdata and nvc_gpio_init structures. + * These need to be present in the board file's nvc_gpio_pdata + * structure for the GPIO's that are used. + * The driver's GPIO logic uses assert/deassert throughout until the + * low level _gpio_wr/rd calls where the .assert_high is used to + * convert the value to the correct signal level. + * See the GPIO notes in nvc.h for additional information. * * The following is specific to NVC kernel focus drivers: * .nvc = Pointer to the nvc_focus_nvc structure. This structure needs to @@ -52,27 +67,21 @@ * .cap = Pointer to the nvc_focus_cap structure. This structure needs to * be defined and populated if overriding the driver defaults. * - * The following is specific to only this NVC kernel focus driver: + * The following is specific to this NVC kernel focus driver: * .info = Pointer to the sh532u_pdata_info structure. This structure does * not need to be defined and populated unless overriding ROM data. .* .i2c_addr_rom = The I2C address of the onboard ROM. - * .gpio_reset = The GPIO connected to the devices reset. If not used then - * leave blank. - * .gpio_en = Due to a Linux limitation, a GPIO is defined to "enable" the - * device. This workaround is for when the device's power GPIO's - * are behind an I2C expander. The Linux limitation doesn't allow - * the I2C GPIO expander to be ready for use when this device is - * probed. When this problem is solved, this driver needs to - * remove the gpio_en WAR. * - * Power Requirements - * The board power file must contain the following labels for the power - * regulator(s) of this device: - * "vdd" = the power regulator for the device's power. - * "vdd_i2c" = the power regulator for the I2C power. - * - * The above values should be all that is needed to use the device with this - * driver. Modifications of this driver should not be needed. + * Power Requirements: + * The device's header file defines the voltage regulators needed with the + * enumeration <device>_vreg. The order these are enumerated is the order + * the regulators will be enabled when powering on the device. When the + * device is powered off the regulators are disabled in descending order. + * The <device>_vregs table in this driver uses the nvc_regulator_init + * structure to define the regulator ID strings that go with the regulators + * defined with <device>_vreg. These regulator ID strings (or supply names) + * will be used in the regulator_get function in the _vreg_init function. + * The board power file and <device>_vregs regulator ID strings must match. */ @@ -85,10 +94,10 @@ #include <linux/list.h> #include <linux/jiffies.h> #include <linux/gpio.h> -#include <media/nvc.h> #include <media/sh532u.h> -#define SH532U_ID 0xF0 +#define SH532U_ID 0x0532 +#define SH532U_STARTUP_DELAY_MS 10 /* defaults if no ROM data */ #define SH532U_HYPERFOCAL_RATIO 1836 /* 41.2f/224.4f Ratio source: SEMCO */ /* _HYPERFOCAL_RATIO is multiplied and _HYPERFOCAL_DIV divides for float */ @@ -96,10 +105,6 @@ #define SH532U_FOCAL_LENGTH 0x408D70A4 #define SH532U_FNUMBER 0x40333333 #define SH532U_MAX_APERATURE 0x3FCA0EA1 -/* SH532U_CAPS_VER = 0: invalid value */ -/* SH532U_CAPS_VER = 1: added NVC_PARAM_STS */ -/* SH532U_CAPS_VER = 2: expanded nvc_focus_cap */ -#define SH532U_CAPS_VER 2 #define SH532U_ACTUATOR_RANGE 1000 #define SH532U_SETTLETIME 30 #define SH532U_FOCUS_MACRO 950 @@ -110,24 +115,42 @@ #define SH532U_POS_HIGH_DEFAULT 0x6000 +static u8 sh532u_ids[] = { + 0xF0, +}; + +static struct nvc_gpio_init sh532u_gpios[] = { + { SH532U_GPIO_RESET, GPIOF_OUT_INIT_LOW, "reset", false, true, }, + { SH532U_GPIO_I2CMUX, 0, "i2c_mux", 0, false, }, + { SH532U_GPIO_GP1, 0, "gp1", 0, false, }, + { SH532U_GPIO_GP2, 0, "gp2", 0, false, }, + { SH532U_GPIO_GP3, 0, "gp3", 0, false, }, +}; + +static struct nvc_regulator_init sh532u_vregs[] = { + { SH532U_VREG_AVDD, "avdd", }, + { SH532U_VREG_DVDD, "dvdd", }, +}; + struct sh532u_info { atomic_t in_use; struct i2c_client *i2c_client; struct sh532u_platform_data *pdata; struct miscdevice miscdev; struct list_head list; + struct nvc_gpio gpio[ARRAY_SIZE(sh532u_gpios)]; + struct nvc_regulator vreg[ARRAY_SIZE(sh532u_vregs)]; int pwr_api; int pwr_dev; - struct nvc_regulator vreg_vdd; - struct nvc_regulator vreg_i2c; u8 s_mode; struct sh532u_info *s_info; + u8 id_minor; unsigned i2c_addr_rom; struct nvc_focus_nvc nvc; struct nvc_focus_cap cap; enum nvc_focus_sts sts; struct sh532u_pdata_info cfg; - bool gpio_flag_reset; + bool reset_flag; bool init_cal_flag; s16 abs_base; u32 abs_range; @@ -143,7 +166,7 @@ static struct sh532u_pdata_info sh532u_default_info = { }; static struct nvc_focus_cap sh532u_default_cap = { - .version = SH532U_CAPS_VER, + .version = NVC_FOCUS_CAP_VER2, .actuator_range = SH532U_ACTUATOR_RANGE, .settle_time = SH532U_SETTLETIME, .focus_macro = SH532U_FOCUS_MACRO, @@ -299,91 +322,227 @@ static int sh532u_i2c_rd32(struct sh532u_info *info, u8 addr, u8 reg, u32 *val) return 0; } -static void sh532u_gpio_en(struct sh532u_info *info, int val) +static int sh532u_gpio_wr(struct sh532u_info *info, + enum sh532u_gpio i, + int val) /* val: 0=deassert, 1=assert */ { - if (info->pdata->gpio_en) - gpio_set_value_cansleep(info->pdata->gpio_en, val); + int err = -EINVAL; + + if (info->gpio[i].flag) { + if (val) + val = 1; + if (!info->gpio[i].active_high) + val = !val; + val &= 1; + err = val; + gpio_set_value_cansleep(info->gpio[i].gpio, val); + dev_dbg(&info->i2c_client->dev, "%s %u %d\n", + __func__, info->gpio[i].gpio, val); + } + return err; /* return value written or error */ } -static void sh532u_gpio_reset(struct sh532u_info *info, int val) +static int sh532u_gpio_reset(struct sh532u_info *info, int val) { + int err = 0; + if (val) { - if (!info->gpio_flag_reset && info->pdata->gpio_reset) { - gpio_set_value_cansleep(info->pdata->gpio_reset, 0); + if (!info->reset_flag) { + info->reset_flag = true; + err = sh532u_gpio_wr(info, SH532U_GPIO_RESET, 1); + if (err < 0) + return 0; /* flag no reset */ + mdelay(1); - gpio_set_value_cansleep(info->pdata->gpio_reset, 1); - mdelay(10); /* delay for device startup */ - info->gpio_flag_reset = 1; + sh532u_gpio_wr(info, SH532U_GPIO_RESET, 0); + mdelay(SH532U_STARTUP_DELAY_MS); /* startup delay */ + err = 1; /* flag that a reset was done */ } } else { - info->gpio_flag_reset = 0; + info->reset_flag = false; } + return err; } -static void sh532u_pm_regulator_put(struct nvc_regulator *sreg) +static void sh532u_gpio_able(struct sh532u_info *info, int val) { - regulator_put(sreg->vreg); - sreg->vreg = NULL; + if (val) { + sh532u_gpio_wr(info, SH532U_GPIO_GP1, val); + sh532u_gpio_wr(info, SH532U_GPIO_GP2, val); + sh532u_gpio_wr(info, SH532U_GPIO_GP3, val); + } else { + sh532u_gpio_wr(info, SH532U_GPIO_GP3, val); + sh532u_gpio_wr(info, SH532U_GPIO_GP2, val); + sh532u_gpio_wr(info, SH532U_GPIO_GP1, val); + } } -static int sh532u_pm_regulator_get(struct sh532u_info *info, - struct nvc_regulator *sreg, - char vreg_name[]) +static void sh532u_gpio_exit(struct sh532u_info *info) +{ + unsigned i; + + for (i = 0; i <= ARRAY_SIZE(sh532u_gpios); i++) { + if (info->gpio[i].flag && info->gpio[i].own) { + gpio_free(info->gpio[i].gpio); + info->gpio[i].own = false; + } + } +} + +static void sh532u_gpio_init(struct sh532u_info *info) +{ + char label[32]; + unsigned long flags; + unsigned type; + unsigned i; + unsigned j; + int err; + + for (i = 0; i < ARRAY_SIZE(sh532u_gpios); i++) + info->gpio[i].flag = false; + if (!info->pdata->gpio_count || !info->pdata->gpio) + return; + + for (i = 0; i < ARRAY_SIZE(sh532u_gpios); i++) { + type = sh532u_gpios[i].gpio_type; + for (j = 0; j < info->pdata->gpio_count; j++) { + if (type == info->pdata->gpio[j].gpio_type) + break; + } + if (j == info->pdata->gpio_count) + continue; + + info->gpio[type].gpio = info->pdata->gpio[j].gpio; + info->gpio[type].flag = true; + if (sh532u_gpios[i].use_flags) { + flags = sh532u_gpios[i].flags; + info->gpio[type].active_high = + sh532u_gpios[i].active_high; + } else { + info->gpio[type].active_high = + info->pdata->gpio[j].active_high; + if (info->gpio[type].active_high) + flags = GPIOF_OUT_INIT_LOW; + else + flags = GPIOF_OUT_INIT_HIGH; + } + if (!info->pdata->gpio[j].init_en) + continue; + + snprintf(label, sizeof(label), "sh532u_%u_%s", + info->pdata->num, sh532u_gpios[i].label); + err = gpio_request_one(info->gpio[type].gpio, flags, label); + if (err) { + dev_err(&info->i2c_client->dev, "%s ERR %s %u\n", + __func__, label, info->gpio[type].gpio); + } else { + info->gpio[type].own = true; + dev_dbg(&info->i2c_client->dev, "%s %s %u\n", + __func__, label, info->gpio[type].gpio); + } + } +} + +static int sh532u_vreg_dis(struct sh532u_info *info, + enum sh532u_vreg i) { int err = 0; - sreg->vreg_flag = 0; - sreg->vreg = regulator_get(&info->i2c_client->dev, vreg_name); - if (IS_ERR_OR_NULL(sreg->vreg)) { - dev_err(&info->i2c_client->dev, - "%s err for regulator: %s err: %d\n", - __func__, vreg_name, (int)sreg->vreg); - err = PTR_ERR(sreg->vreg); - sreg->vreg = NULL; - } else { - sreg->vreg_name = vreg_name; - dev_dbg(&info->i2c_client->dev, - "%s vreg_name: %s\n", - __func__, sreg->vreg_name); + if (info->vreg[i].vreg_flag && (info->vreg[i].vreg != NULL)) { + err = regulator_disable(info->vreg[i].vreg); + if (!err) + dev_dbg(&info->i2c_client->dev, "%s: %s\n", + __func__, info->vreg[i].vreg_name); + else + dev_err(&info->i2c_client->dev, "%s %s ERR\n", + __func__, info->vreg[i].vreg_name); } + info->vreg[i].vreg_flag = false; return err; } -static int sh532u_pm_regulator_en(struct sh532u_info *info, - struct nvc_regulator *sreg) +static int sh532u_vreg_dis_all(struct sh532u_info *info) { + unsigned i; int err = 0; - if (!sreg->vreg_flag && (sreg->vreg != NULL)) { - err = regulator_enable(sreg->vreg); + for (i = ARRAY_SIZE(sh532u_vregs); i > 0; i--) + err |= sh532u_vreg_dis(info, (i - 1)); + return err; +} + +static int sh532u_vreg_en(struct sh532u_info *info, + enum sh532u_vreg i) +{ + int err = 0; + + if (!info->vreg[i].vreg_flag && (info->vreg[i].vreg != NULL)) { + err = regulator_enable(info->vreg[i].vreg); if (!err) { - dev_dbg(&info->i2c_client->dev, - "%s vreg_name: %s\n", - __func__, sreg->vreg_name); - sreg->vreg_flag = 1; + dev_dbg(&info->i2c_client->dev, "%s: %s\n", + __func__, info->vreg[i].vreg_name); + info->vreg[i].vreg_flag = true; err = 1; /* flag regulator state change */ } else { - dev_err(&info->i2c_client->dev, - "%s err, regulator: %s\n", - __func__, sreg->vreg_name); + dev_err(&info->i2c_client->dev, "%s %s ERR\n", + __func__, info->vreg[i].vreg_name); } } return err; } -static int sh532u_pm_regulator_dis(struct sh532u_info *info, - struct nvc_regulator *sreg) +static int sh532u_vreg_en_all(struct sh532u_info *info) { + unsigned i; int err = 0; - if (sreg->vreg_flag && (sreg->vreg != NULL)) { - err = regulator_disable(sreg->vreg); - if (err) - dev_err(&info->i2c_client->dev, - "%s err, regulator: %s\n", - __func__, sreg->vreg_name); + for (i = 0; i < ARRAY_SIZE(sh532u_vregs); i++) + err |= sh532u_vreg_en(info, i); + return err; +} + +static void sh532u_vreg_exit(struct sh532u_info *info) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(sh532u_vregs); i++) { + regulator_put(info->vreg[i].vreg); + info->vreg[i].vreg = NULL; + } +} + +static int sh532u_vreg_init(struct sh532u_info *info) +{ + unsigned i; + unsigned j; + int err = 0; + + for (i = 0; i < ARRAY_SIZE(sh532u_vregs); i++) { + j = sh532u_vregs[i].vreg_num; + info->vreg[j].vreg_name = sh532u_vregs[i].vreg_name; + info->vreg[j].vreg_flag = false; + info->vreg[j].vreg = regulator_get(&info->i2c_client->dev, + info->vreg[j].vreg_name); + if (IS_ERR_OR_NULL(info->vreg[j].vreg)) { + if (PTR_ERR(info->vreg[j].vreg) != -ENODEV) + dev_dbg(&info->i2c_client->dev, + "%s %s ERR: %d\n", + __func__, info->vreg[j].vreg_name, + (int)info->vreg[j].vreg); + else + dev_info(&info->i2c_client->dev, + "%s no regulator found for %s. " + "This board may not have an" + "independent %s regulator.\n", + __func__, info->vreg[j].vreg_name, + info->vreg[j].vreg_name); + err |= PTR_ERR(info->vreg[j].vreg); + info->vreg[j].vreg = NULL; + } else { + dev_dbg(&info->i2c_client->dev, "%s: %s\n", + __func__, info->vreg[j].vreg_name); + } } - sreg->vreg_flag = 0; return err; } @@ -402,17 +561,15 @@ static int sh532u_pm_wr(struct sh532u_info *info, int pwr) switch (pwr) { case NVC_PWR_OFF_FORCE: case NVC_PWR_OFF: - sh532u_gpio_en(info, 0); - err = sh532u_pm_regulator_dis(info, &info->vreg_vdd); - err |= sh532u_pm_regulator_dis(info, &info->vreg_i2c); + err = sh532u_vreg_dis_all(info); + sh532u_gpio_able(info, 0); sh532u_gpio_reset(info, 0); break; case NVC_PWR_STDBY_OFF: case NVC_PWR_STDBY: - err = sh532u_pm_regulator_en(info, &info->vreg_vdd); - err |= sh532u_pm_regulator_en(info, &info->vreg_i2c); - sh532u_gpio_en(info, 1); + err = sh532u_vreg_en_all(info); + sh532u_gpio_able(info, 1); sh532u_gpio_reset(info, 1); err |= sh532u_i2c_wr8(info, STBY_211, 0x80); err |= sh532u_i2c_wr8(info, CLKSEL_211, 0x38); @@ -421,9 +578,8 @@ static int sh532u_pm_wr(struct sh532u_info *info, int pwr) case NVC_PWR_COMM: case NVC_PWR_ON: - err = sh532u_pm_regulator_en(info, &info->vreg_vdd); - err |= sh532u_pm_regulator_en(info, &info->vreg_i2c); - sh532u_gpio_en(info, 1); + err = sh532u_vreg_en_all(info); + sh532u_gpio_able(info, 1); sh532u_gpio_reset(info, 1); err |= sh532u_i2c_wr8(info, CLKSEL_211, 0x38); err |= sh532u_i2c_wr8(info, CLKSEL_211, 0x34); @@ -436,11 +592,12 @@ static int sh532u_pm_wr(struct sh532u_info *info, int pwr) } if (err < 0) { - dev_err(&info->i2c_client->dev, "%s pwr err: %d\n", - __func__, pwr); + dev_err(&info->i2c_client->dev, "%s err %d\n", __func__, err); pwr = NVC_PWR_ERR; } info->pwr_dev = pwr; + dev_dbg(&info->i2c_client->dev, "%s pwr_dev=%d\n", + __func__, info->pwr_dev); if (err > 0) return 0; @@ -493,31 +650,58 @@ static int sh532u_pm_dev_wr(struct sh532u_info *info, int pwr) static void sh532u_pm_exit(struct sh532u_info *info) { sh532u_pm_wr(info, NVC_PWR_OFF_FORCE); - sh532u_pm_regulator_put(&info->vreg_vdd); - sh532u_pm_regulator_put(&info->vreg_i2c); - if (info->s_info != NULL) { - sh532u_pm_wr(info->s_info, NVC_PWR_OFF_FORCE); - sh532u_pm_regulator_put(&info->s_info->vreg_vdd); - sh532u_pm_regulator_put(&info->s_info->vreg_i2c); - } + sh532u_vreg_exit(info); + sh532u_gpio_exit(info); } static void sh532u_pm_init(struct sh532u_info *info) { - sh532u_pm_regulator_get(info, &info->vreg_vdd, "vdd"); - sh532u_pm_regulator_get(info, &info->vreg_i2c, "vdd_i2c"); + sh532u_gpio_init(info); + sh532u_vreg_init(info); +} + +static int sh532u_reset(struct sh532u_info *info, u32 level) +{ + int err; + + if (level == NVC_RESET_SOFT) { + err = sh532u_pm_wr(info, NVC_PWR_COMM); + err |= sh532u_i2c_wr8(info, SFTRST_211, 0xFF); /* SW reset */ + mdelay(1); + err |= sh532u_i2c_wr8(info, SFTRST_211, 0); + } else { + err = sh532u_pm_wr(info, NVC_PWR_OFF_FORCE); + } + err |= sh532u_pm_wr(info, info->pwr_api); + return err; } static int sh532u_dev_id(struct sh532u_info *info) { - u8 val; + u8 val = 0; + unsigned i; int err; + sh532u_pm_dev_wr(info, NVC_PWR_COMM); err = sh532u_i2c_rd8(info, 0, HVCA_DEVICE_ID, &val); - if (!err && (val == SH532U_ID)) - return 0; - - return -ENODEV; + if (!err) { + dev_dbg(&info->i2c_client->dev, "%s found devId: %x\n", + __func__, val); + info->id_minor = 0; + for (i = 0; i < ARRAY_SIZE(sh532u_ids); i++) { + if (val == sh532u_ids[i]) { + info->id_minor = val; + break; + } + } + if (!info->id_minor) { + err = -ENODEV; + dev_dbg(&info->i2c_client->dev, "%s No devId match\n", + __func__); + } + } + sh532u_pm_dev_wr(info, NVC_PWR_OFF); + return err; } static void sh532u_sts_rd(struct sh532u_info *info) @@ -633,9 +817,8 @@ static int sh532u_rel_pos_rd(struct sh532u_info *info, u32 *position) return 0; } -static int sh532u_calibration(struct sh532u_info *info, bool use_defaults) +static void sh532u_calibration_caps(struct sh532u_info *info) { - u8 reg; s16 abs_top; u32 rel_range; u32 rel_lo; @@ -643,45 +826,75 @@ static int sh532u_calibration(struct sh532u_info *info, bool use_defaults) u32 step; u32 loop_limit; u32 i; + + /* + * calculate relative and absolute positions + * Note that relative values, what upper SW uses, are the + * abstraction of HW (absolute) values. + * |<--limit_low limit_high-->| + * | |<-------------------_ACTUATOR_RANGE------------------->| | + * -focus_inf -focus_mac + * |<---RI--->| |<---RM--->| + * -abs_base -pos_low -pos_high -abs_top + * + * The pos_low and pos_high are fixed absolute positions and correspond + * to the relative focus_infinity and focus_macro, respectively. We'd + * like to have "wiggle" room (RI and RM) around these relative + * positions so the loop below finds the best fit for RI and RM without + * passing the absolute limits. + * We want our _ACTUATOR_RANGE to be infinity on the 0 end and macro + * on the max end. However, the focuser HW is opposite this. + * Therefore we use the rel(ative)_lo/hi variables in the calculation + * loop and assign them the focus_infinity and focus_macro values. + */ + rel_lo = (info->cap.actuator_range - info->cap.focus_macro); + rel_hi = info->cap.focus_infinity; + info->abs_range = (u32)(info->cfg.pos_high - info->cfg.pos_low); + loop_limit = (rel_lo > rel_hi) ? rel_lo : rel_hi; + for (i = 0; i <= loop_limit; i++) { + rel_range = info->cap.actuator_range - (rel_lo + rel_hi); + step = info->abs_range / rel_range; + info->abs_base = info->cfg.pos_low - (step * rel_lo); + abs_top = info->cfg.pos_high + (step * rel_hi); + if (info->abs_base < info->cfg.limit_low) { + if (rel_lo > 0) + rel_lo--; + } + if (abs_top > info->cfg.limit_high) { + if (rel_hi > 0) + rel_hi--; + } + if (info->abs_base >= info->cfg.limit_low && + abs_top <= info->cfg.limit_high) + break; + } + info->cap.focus_hyper = info->abs_range; + info->abs_range = (u32)(abs_top - info->abs_base); + /* calculate absolute hyperfocus position */ + info->cap.focus_hyper *= info->cfg.focus_hyper_ratio; + info->cap.focus_hyper /= info->cfg.focus_hyper_div; + abs_top = (s16)(info->cfg.pos_high - info->cap.focus_hyper); + /* update actual relative positions */ + info->cap.focus_hyper = sh532u_abs2rel(info, abs_top); + info->cap.focus_infinity = sh532u_abs2rel(info, info->cfg.pos_high); + info->cap.focus_macro = sh532u_abs2rel(info, info->cfg.pos_low); + dev_dbg(&info->i2c_client->dev, "%s focus_macro=%u\n", + __func__, info->cap.focus_macro); + dev_dbg(&info->i2c_client->dev, "%s focus_infinity=%u\n", + __func__, info->cap.focus_infinity); + dev_dbg(&info->i2c_client->dev, "%s focus_hyper=%u\n", + __func__, info->cap.focus_hyper); +} + +static int sh532u_calibration(struct sh532u_info *info, bool use_defaults) +{ + u8 reg; int err; int ret = 0; if (info->init_cal_flag) return 0; - /* set defaults */ - memcpy(&info->cfg, &sh532u_default_info, sizeof(info->cfg)); - memcpy(&info->nvc, &sh532u_default_nvc, sizeof(info->nvc)); - memcpy(&info->cap, &sh532u_default_cap, sizeof(info->cap)); - if (info->pdata->i2c_addr_rom) - info->i2c_addr_rom = info->pdata->i2c_addr_rom; - else - info->i2c_addr_rom = sh532u_default_pdata.i2c_addr_rom; - /* set overrides if any */ - if (info->pdata->nvc) { - if (info->pdata->nvc->fnumber) - info->nvc.fnumber = info->pdata->nvc->fnumber; - if (info->pdata->nvc->focal_length) - info->nvc.focal_length = - info->pdata->nvc->focal_length; - if (info->pdata->nvc->max_aperature) - info->nvc.max_aperature = - info->pdata->nvc->max_aperature; - } - if (info->pdata->cap) { - if (info->pdata->cap->actuator_range) - info->cap.actuator_range = - info->pdata->cap->actuator_range; - if (info->pdata->cap->settle_time) - info->cap.settle_time = info->pdata->cap->settle_time; - if (info->pdata->cap->focus_macro) - info->cap.focus_macro = info->pdata->cap->focus_macro; - if (info->pdata->cap->focus_hyper) - info->cap.focus_hyper = info->pdata->cap->focus_hyper; - if (info->pdata->cap->focus_infinity) - info->cap.focus_infinity = - info->pdata->cap->focus_infinity; - } /* * Get Inf1, Mac1 * Inf1 and Mac1 are the mechanical limit position. @@ -770,78 +983,22 @@ static int sh532u_calibration(struct sh532u_info *info, bool use_defaults) info->cfg.limit_low = SH532U_POS_LOW_DEFAULT; info->cfg.limit_high = SH532U_POS_HIGH_DEFAULT; dev_err(&info->i2c_client->dev, "%s ERR: ERPOM data is void! " - "Focuser will use defaults that will cause " - "reduced functionality!\n", __func__); + "Focuser will use defaults that will cause " + "reduced functionality!\n", __func__); } if (info->cfg.pos_low < info->cfg.limit_low) info->cfg.pos_low = info->cfg.limit_low; if (info->cfg.pos_high > info->cfg.limit_high) info->cfg.pos_high = info->cfg.limit_high; - dev_dbg(&info->i2c_client->dev, "%s pos_low=%d\n", __func__, - (int)info->cfg.pos_low); - dev_dbg(&info->i2c_client->dev, "%s pos_high=%d\n", __func__, - (int)info->cfg.pos_high); - dev_dbg(&info->i2c_client->dev, "%s limit_low=%d\n", __func__, - (int)info->cfg.limit_low); - dev_dbg(&info->i2c_client->dev, "%s limit_high=%d\n", __func__, - (int)info->cfg.limit_high); - /* - * calculate relative and absolute positions - * Note that relative values, what upper SW uses, are the - * abstraction of HW (absolute) values. - * |<--limit_low limit_high-->| - * | |<-------------------_ACTUATOR_RANGE------------------->| | - * -focus_inf -focus_mac - * |<---RI--->| |<---RM--->| - * -abs_base -pos_low -pos_high -abs_top - * - * The pos_low and pos_high are fixed absolute positions and correspond - * to the relative focus_infinity and focus_macro, respectively. We'd - * like to have "wiggle" room (RI and RM) around these relative - * positions so the loop below finds the best fit for RI and RM without - * passing the absolute limits. - * We want our _ACTUATOR_RANGE to be infinity on the 0 end and macro - * on the max end. However, the focuser HW is opposite this. - * Therefore we use the rel(ative)_lo/hi variables in the calculation - * loop and assign them the focus_infinity and focus_macro values. - */ - rel_lo = (info->cap.actuator_range - info->cap.focus_macro); - rel_hi = info->cap.focus_infinity; - info->abs_range = (u32)(info->cfg.pos_high - info->cfg.pos_low); - loop_limit = (rel_lo > rel_hi) ? rel_lo : rel_hi; - for (i = 0; i <= loop_limit; i++) { - rel_range = info->cap.actuator_range - (rel_lo + rel_hi); - step = info->abs_range / rel_range; - info->abs_base = info->cfg.pos_low - (step * rel_lo); - abs_top = info->cfg.pos_high + (step * rel_hi); - if (info->abs_base < info->cfg.limit_low) { - if (rel_lo > 0) - rel_lo--; - } - if (abs_top > info->cfg.limit_high) { - if (rel_hi > 0) - rel_hi--; - } - if (info->abs_base >= info->cfg.limit_low && - abs_top <= info->cfg.limit_high) - break; - } - info->cap.focus_hyper = info->abs_range; - info->abs_range = (u32)(abs_top - info->abs_base); - /* calculate absolute hyperfocus position */ - info->cap.focus_hyper *= info->cfg.focus_hyper_ratio; - info->cap.focus_hyper /= info->cfg.focus_hyper_div; - abs_top = (s16)(info->cfg.pos_high - info->cap.focus_hyper); - /* update actual relative positions */ - info->cap.focus_hyper = sh532u_abs2rel(info, abs_top); - info->cap.focus_infinity = sh532u_abs2rel(info, info->cfg.pos_high); - info->cap.focus_macro = sh532u_abs2rel(info, info->cfg.pos_low); - dev_dbg(&info->i2c_client->dev, "%s focus_macro=%u\n", __func__, - info->cap.focus_macro); - dev_dbg(&info->i2c_client->dev, "%s focus_infinity=%u\n", __func__, - info->cap.focus_infinity); - dev_dbg(&info->i2c_client->dev, "%s focus_hyper=%u\n", __func__, - info->cap.focus_hyper); + dev_dbg(&info->i2c_client->dev, "%s pos_low=%d\n", + __func__, (int)info->cfg.pos_low); + dev_dbg(&info->i2c_client->dev, "%s pos_high=%d\n", + __func__, (int)info->cfg.pos_high); + dev_dbg(&info->i2c_client->dev, "%s limit_low=%d\n", + __func__, (int)info->cfg.limit_low); + dev_dbg(&info->i2c_client->dev, "%s limit_high=%d\n", + __func__, (int)info->cfg.limit_high); + sh532u_calibration_caps(info); info->init_cal_flag = 1; dev_dbg(&info->i2c_client->dev, "%s complete\n", __func__); return 0; @@ -955,6 +1112,9 @@ static int sh532u_dev_init(struct sh532u_info *info) int ret = 0; err = sh532u_i2c_rd8(info, 0, SWTCH_211, &ep_data1); + if (err) + return err; /* exit if unable to communicate with device */ + ep_data2 = ep_data1; err |= sh532u_i2c_rd8(info, 0, ANA1_211, &ep_data1); ep_data2 |= ep_data1; @@ -1007,7 +1167,7 @@ static int sh532u_dev_init(struct sh532u_info *info) err = ret; if (err) dev_err(&info->i2c_client->dev, "%s programming err=%d\n", - __func__, err); + __func__, err); err |= sh532u_calibration(info, false); info->sts = NVC_FOCUS_STS_LENS_SETTLED; return err; @@ -1031,7 +1191,7 @@ static int sh532u_pos_abs_wr(struct sh532u_info *info, s16 tar_pos) return err; dev_dbg(&info->i2c_client->dev, "%s cur_pos=%d tar_pos=%d\n", - __func__, (int)cur_pos, (int)tar_pos); + __func__, (int)cur_pos, (int)tar_pos); info->sts = NVC_FOCUS_STS_WAIT_FOR_MOVE_END; /* Check move distance to Target Position */ move_distance = abs((int)cur_pos - (int)tar_pos); @@ -1135,7 +1295,7 @@ static int sh532u_pos_rel_wr(struct sh532u_info *info, u32 position) if (position > info->cap.actuator_range) { dev_err(&info->i2c_client->dev, "%s invalid position %u\n", - __func__, position); + __func__, position); return -EINVAL; } @@ -1159,7 +1319,7 @@ static int sh532u_param_rd(struct sh532u_info *info, unsigned long arg) (const void __user *)arg, sizeof(struct nvc_param))) { dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n", - __func__, __LINE__); + __func__, __LINE__); return -EFAULT; } @@ -1176,28 +1336,28 @@ static int sh532u_param_rd(struct sh532u_info *info, unsigned long arg) data_size = sizeof(position); sh532u_pm_dev_wr(info, NVC_PWR_STDBY); dev_dbg(&info->i2c_client->dev, "%s LOCUS: %d\n", - __func__, position); + __func__, position); break; case NVC_PARAM_FOCAL_LEN: data_ptr = &info->nvc.focal_length; data_size = sizeof(info->nvc.focal_length); dev_dbg(&info->i2c_client->dev, "%s FOCAL_LEN: %x\n", - __func__, info->nvc.focal_length); + __func__, info->nvc.focal_length); break; case NVC_PARAM_MAX_APERTURE: data_ptr = &info->nvc.max_aperature; data_size = sizeof(info->nvc.max_aperature); dev_dbg(&info->i2c_client->dev, "%s MAX_APERTURE: %x\n", - __func__, info->nvc.max_aperature); + __func__, info->nvc.max_aperature); break; case NVC_PARAM_FNUMBER: data_ptr = &info->nvc.fnumber; data_size = sizeof(info->nvc.fnumber); - dev_dbg(&info->i2c_client->dev, "%s FNUMBER: %x\n", - __func__, info->nvc.fnumber); + dev_dbg(&info->i2c_client->dev, "%s FNUMBER: %u\n", + __func__, info->nvc.fnumber); break; case NVC_PARAM_CAPS: @@ -1215,41 +1375,42 @@ static int sh532u_param_rd(struct sh532u_info *info, unsigned long arg) else data_size = sizeof(info->cap); dev_dbg(&info->i2c_client->dev, "%s CAPS\n", - __func__); + __func__); break; case NVC_PARAM_STS: data_ptr = &info->sts; data_size = sizeof(info->sts); dev_dbg(&info->i2c_client->dev, "%s STS: %d\n", - __func__, info->sts); + __func__, info->sts); break; case NVC_PARAM_STEREO: data_ptr = &info->s_mode; data_size = sizeof(info->s_mode); dev_dbg(&info->i2c_client->dev, "%s STEREO: %d\n", - __func__, info->s_mode); + __func__, info->s_mode); break; default: - dev_err(&info->i2c_client->dev, - "%s unsupported parameter: %d\n", - __func__, params.param); + dev_dbg(&info->i2c_client->dev, + "%s unsupported parameter: %d\n", + __func__, params.param); return -EINVAL; } if (params.sizeofvalue < data_size) { - dev_err(&info->i2c_client->dev, "%s %d data size err\n", - __func__, __LINE__); + dev_err(&info->i2c_client->dev, + "%s data size mismatch %d != %d Param: %d\n", + __func__, params.sizeofvalue, data_size, params.param); return -EINVAL; } if (copy_to_user((void __user *)params.p_value, data_ptr, data_size)) { - dev_err(&info->i2c_client->dev, "%s %d copy_to_user err\n", - __func__, __LINE__); + dev_err(&info->i2c_client->dev, + "%s copy_to_user err line %d\n", __func__, __LINE__); return -EFAULT; } @@ -1258,35 +1419,59 @@ static int sh532u_param_rd(struct sh532u_info *info, unsigned long arg) static int sh532u_param_wr_s(struct sh532u_info *info, struct nvc_param *params, - u32 u32_val) + u32 u32val) { + struct nvc_focus_cap cap; + u8 u8val; int err; + u8val = (u8)u32val; switch (params->param) { case NVC_PARAM_LOCUS: dev_dbg(&info->i2c_client->dev, "%s LOCUS: %u\n", - __func__, u32_val); - err = sh532u_pos_rel_wr(info, u32_val); + __func__, u32val); + err = sh532u_pos_rel_wr(info, u32val); return err; case NVC_PARAM_RESET: - err = sh532u_pm_wr(info, NVC_PWR_OFF); - err |= sh532u_pm_wr(info, NVC_PWR_ON); - err |= sh532u_pm_wr(info, info->pwr_api); + err = sh532u_reset(info, u32val); dev_dbg(&info->i2c_client->dev, "%s RESET: %d\n", - __func__, err); + __func__, err); return err; case NVC_PARAM_SELF_TEST: err = sh532u_hvca_pos_init(info); dev_dbg(&info->i2c_client->dev, "%s SELF_TEST: %d\n", - __func__, err); + __func__, err); return err; + case NVC_PARAM_CAPS: + dev_dbg(&info->i2c_client->dev, "%s CAPS\n", + __func__); + if (copy_from_user(&cap, (const void __user *)params->p_value, + sizeof(params->sizeofvalue))) { + dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n", + __func__, __LINE__); + return -EFAULT; + } + + if (!cap.version) + return -EINVAL; + + if (cap.version >= NVC_FOCUS_CAP_VER1) + info->cap.actuator_range = cap.actuator_range; + if (cap.version >= NVC_FOCUS_CAP_VER2) { + info->cap.focus_macro = cap.focus_macro; + info->cap.focus_hyper = cap.focus_hyper; + info->cap.focus_infinity = cap.focus_infinity; + } + sh532u_calibration_caps(info); + return 0; + default: - dev_err(&info->i2c_client->dev, - "%s unsupported parameter: %d\n", - __func__, params->param); + dev_dbg(&info->i2c_client->dev, + "%s unsupported parameter: %d\n", + __func__, params->param); return -EINVAL; } } @@ -1294,47 +1479,48 @@ static int sh532u_param_wr_s(struct sh532u_info *info, static int sh532u_param_wr(struct sh532u_info *info, unsigned long arg) { struct nvc_param params; - u8 val; - u32 u32_val; + u8 u8val; + u32 u32val; int err = 0; - if (copy_from_user(¶ms, - (const void __user *)arg, - sizeof(struct nvc_param))) { - dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n", - __func__, __LINE__); + if (copy_from_user(¶ms, (const void __user *)arg, + sizeof(struct nvc_param))) { + dev_err(&info->i2c_client->dev, + "%s copy_from_user err line %d\n", __func__, __LINE__); return -EFAULT; } - if (copy_from_user(&u32_val, (const void __user *)params.p_value, - sizeof(u32_val))) { + if (copy_from_user(&u32val, (const void __user *)params.p_value, + sizeof(u32val))) { dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n", - __func__, __LINE__); + __func__, __LINE__); return -EFAULT; } + u8val = (u8)u32val; /* parameters independent of sync mode */ switch (params.param) { case NVC_PARAM_STEREO: - dev_dbg(&info->i2c_client->dev, "%s STEREO: %u\n", - __func__, u32_val); - val = (u8)u32_val; - if (val == info->s_mode) + dev_dbg(&info->i2c_client->dev, "%s STEREO: %d\n", + __func__, u8val); + if (u8val == info->s_mode) return 0; - switch (val) { + switch (u8val) { case NVC_SYNC_OFF: - info->s_mode = val; + info->s_mode = u8val; + sh532u_gpio_wr(info, SH532U_GPIO_I2CMUX, 0); if (info->s_info != NULL) { - info->s_info->s_mode = val; + info->s_info->s_mode = u8val; sh532u_pm_wr(info->s_info, NVC_PWR_OFF); } break; case NVC_SYNC_MASTER: - info->s_mode = val; + info->s_mode = u8val; + sh532u_gpio_wr(info, SH532U_GPIO_I2CMUX, 0); if (info->s_info != NULL) - info->s_info->s_mode = val; + info->s_info->s_mode = u8val; break; case NVC_SYNC_SLAVE: @@ -1343,8 +1529,10 @@ static int sh532u_param_wr(struct sh532u_info *info, unsigned long arg) err = sh532u_pos_rel_wr(info->s_info, info->s_info->cap.focus_infinity); if (!err) { - info->s_mode = val; - info->s_info->s_mode = val; + info->s_mode = u8val; + info->s_info->s_mode = u8val; + sh532u_gpio_wr(info, + SH532U_GPIO_I2CMUX, 0); } else { if (info->s_mode != NVC_SYNC_STEREO) sh532u_pm_wr(info->s_info, @@ -1364,8 +1552,10 @@ static int sh532u_param_wr(struct sh532u_info *info, unsigned long arg) err = sh532u_pos_rel_wr(info->s_info, info->pos_rel); if (!err) { - info->s_mode = val; - info->s_info->s_mode = val; + info->s_mode = u8val; + info->s_info->s_mode = u8val; + sh532u_gpio_wr(info, + SH532U_GPIO_I2CMUX, 1); } else { if (info->s_mode != NVC_SYNC_SLAVE) sh532u_pm_wr(info->s_info, @@ -1390,49 +1580,52 @@ static int sh532u_param_wr(struct sh532u_info *info, unsigned long arg) switch (info->s_mode) { case NVC_SYNC_OFF: case NVC_SYNC_MASTER: - return sh532u_param_wr_s(info, ¶ms, u32_val); + return sh532u_param_wr_s(info, ¶ms, u32val); case NVC_SYNC_SLAVE: - return sh532u_param_wr_s(info->s_info, - ¶ms, - u32_val); + return sh532u_param_wr_s(info->s_info, ¶ms, + u32val); case NVC_SYNC_STEREO: - err = sh532u_param_wr_s(info, ¶ms, u32_val); + err = sh532u_param_wr_s(info, ¶ms, u32val); if (!(info->pdata->cfg & NVC_CFG_SYNC_I2C_MUX)) err |= sh532u_param_wr_s(info->s_info, ¶ms, - u32_val); + u32val); return err; default: dev_err(&info->i2c_client->dev, "%s %d internal err\n", - __func__, __LINE__); + __func__, __LINE__); return -EINVAL; } } } static long sh532u_ioctl(struct file *file, - unsigned int cmd, - unsigned long arg) + unsigned int cmd, + unsigned long arg) { struct sh532u_info *info = file->private_data; int pwr; + int err; switch (cmd) { case NVC_IOCTL_PARAM_WR: - return sh532u_param_wr(info, arg); + err = sh532u_param_wr(info, arg); + return err; case NVC_IOCTL_PARAM_RD: - return sh532u_param_rd(info, arg); + err = sh532u_param_rd(info, arg); + return err; case NVC_IOCTL_PWR_WR: /* This is a Guaranteed Level of Service (GLOS) call */ pwr = (int)arg * 2; - dev_dbg(&info->i2c_client->dev, "%s PWR: %d\n", - __func__, pwr); - return sh532u_pm_api_wr(info, pwr); + dev_dbg(&info->i2c_client->dev, "%s PWR_WR: %d\n", + __func__, pwr); + err = sh532u_pm_api_wr(info, pwr); + return err; case NVC_IOCTL_PWR_RD: if (info->s_mode == NVC_SYNC_SLAVE) @@ -1440,7 +1633,7 @@ static long sh532u_ioctl(struct file *file, else pwr = info->pwr_api / 2; dev_dbg(&info->i2c_client->dev, "%s PWR_RD: %d\n", - __func__, pwr); + __func__, pwr); if (copy_to_user((void __user *)arg, (const void *)&pwr, sizeof(pwr))) { dev_err(&info->i2c_client->dev, @@ -1452,46 +1645,84 @@ static long sh532u_ioctl(struct file *file, return 0; default: - dev_err(&info->i2c_client->dev, "%s unsupported ioctl: %x\n", - __func__, cmd); - return -EINVAL; + dev_dbg(&info->i2c_client->dev, "%s unsupported ioctl: %x\n", + __func__, cmd); } + + return -EINVAL; } -static int sh532u_sync_en(int dev1, int dev2) +static void sh532u_sdata_init(struct sh532u_info *info) { - struct sh532u_info *sync1 = NULL; - struct sh532u_info *sync2 = NULL; + /* set defaults */ + memcpy(&info->cfg, &sh532u_default_info, sizeof(info->cfg)); + memcpy(&info->nvc, &sh532u_default_nvc, sizeof(info->nvc)); + memcpy(&info->cap, &sh532u_default_cap, sizeof(info->cap)); + if (info->pdata->i2c_addr_rom) + info->i2c_addr_rom = info->pdata->i2c_addr_rom; + else + info->i2c_addr_rom = sh532u_default_pdata.i2c_addr_rom; + /* set overrides if any */ + if (info->pdata->nvc) { + if (info->pdata->nvc->fnumber) + info->nvc.fnumber = info->pdata->nvc->fnumber; + if (info->pdata->nvc->focal_length) + info->nvc.focal_length = + info->pdata->nvc->focal_length; + if (info->pdata->nvc->max_aperature) + info->nvc.max_aperature = + info->pdata->nvc->max_aperature; + } + if (info->pdata->cap) { + if (info->pdata->cap->actuator_range) + info->cap.actuator_range = + info->pdata->cap->actuator_range; + if (info->pdata->cap->settle_time) + info->cap.settle_time = info->pdata->cap->settle_time; + if (info->pdata->cap->focus_macro) + info->cap.focus_macro = info->pdata->cap->focus_macro; + if (info->pdata->cap->focus_hyper) + info->cap.focus_hyper = info->pdata->cap->focus_hyper; + if (info->pdata->cap->focus_infinity) + info->cap.focus_infinity = + info->pdata->cap->focus_infinity; + } +} + +static int sh532u_sync_en(unsigned num, unsigned sync) +{ + struct sh532u_info *master = NULL; + struct sh532u_info *slave = NULL; struct sh532u_info *pos = NULL; rcu_read_lock(); list_for_each_entry_rcu(pos, &sh532u_info_list, list) { - if (pos->pdata->num == dev1) { - sync1 = pos; + if (pos->pdata->num == num) { + master = pos; break; } } pos = NULL; list_for_each_entry_rcu(pos, &sh532u_info_list, list) { - if (pos->pdata->num == dev2) { - sync2 = pos; + if (pos->pdata->num == sync) { + slave = pos; break; } } rcu_read_unlock(); - if (sync1 != NULL) - sync1->s_info = NULL; - if (sync2 != NULL) - sync2->s_info = NULL; - if (!dev1 && !dev2) - return 0; /* no err if default instance 0's used */ - - if (dev1 == dev2) + if (master != NULL) + master->s_info = NULL; + if (slave != NULL) + slave->s_info = NULL; + if (!sync) + return 0; /* no err if sync disabled */ + + if (num == sync) return -EINVAL; /* err if sync instance is itself */ - if ((sync1 != NULL) && (sync2 != NULL)) { - sync1->s_info = sync2; - sync2->s_info = sync1; + if ((master != NULL) && (slave != NULL)) { + master->s_info = slave; + slave->s_info = master; } return 0; } @@ -1529,8 +1760,8 @@ static int sh532u_open(struct inode *inode, struct file *file) err = sh532u_sync_en(info->pdata->num, info->pdata->sync); if (err == -EINVAL) dev_err(&info->i2c_client->dev, - "%s err: invalid num (%u) and sync (%u) instance\n", - __func__, info->pdata->num, info->pdata->sync); + "%s err: invalid num (%u) and sync (%u) instance\n", + __func__, info->pdata->num, info->pdata->sync); if (atomic_xchg(&info->in_use, 1)) return -EBUSY; @@ -1542,10 +1773,11 @@ static int sh532u_open(struct inode *inode, struct file *file) file->private_data = info; dev_dbg(&info->i2c_client->dev, "%s\n", __func__); sh532u_pos_rel_wr(info, info->cap.focus_infinity); + sh532u_pm_wr_s(info, NVC_PWR_OFF); return 0; } -int sh532u_release(struct inode *inode, struct file *file) +static int sh532u_release(struct inode *inode, struct file *file) { struct sh532u_info *info = file->private_data; @@ -1569,6 +1801,9 @@ static const struct file_operations sh532u_fileops = { static void sh532u_del(struct sh532u_info *info) { sh532u_pm_exit(info); + if ((info->s_mode == NVC_SYNC_SLAVE) || + (info->s_mode == NVC_SYNC_STEREO)) + sh532u_pm_exit(info->s_info); sh532u_sync_dis(info); spin_lock(&sh532u_spinlock); list_del_rcu(&info->list); @@ -1590,7 +1825,7 @@ static int sh532u_probe( struct i2c_client *client, const struct i2c_device_id *id) { - struct sh532u_info *info = NULL; + struct sh532u_info *info; char dname[16]; int err; @@ -1607,8 +1842,7 @@ static int sh532u_probe( } else { info->pdata = &sh532u_default_pdata; dev_dbg(&client->dev, - "%s No platform data. Using defaults.\n", - __func__); + "%s No platform data. Using defaults.\n", __func__); } i2c_set_clientdata(client, info); INIT_LIST_HEAD(&info->list); @@ -1616,24 +1850,27 @@ static int sh532u_probe( list_add_rcu(&info->list, &sh532u_info_list); spin_unlock(&sh532u_spinlock); sh532u_pm_init(info); - sh532u_pm_dev_wr(info, NVC_PWR_COMM); - err = sh532u_dev_id(info); - if (err < 0) { - dev_err(&client->dev, "%s device not found\n", __func__); - sh532u_pm_wr(info, NVC_PWR_OFF); - if (info->pdata->cfg & NVC_CFG_NODEV) { - sh532u_del(info); - return -ENODEV; - } - } else { - dev_dbg(&client->dev, "%s device found\n", __func__); - sh532u_calibration(info, false); - if (info->pdata->cfg & NVC_CFG_BOOT_INIT) { - /* initial move causes full initialization */ - sh532u_pos_rel_wr(info, info->cap.focus_infinity); + sh532u_sdata_init(info); + if (info->pdata->cfg & (NVC_CFG_NODEV | NVC_CFG_BOOT_INIT)) { + err = sh532u_dev_id(info); + if (err < 0) { + if (info->pdata->cfg & NVC_CFG_NODEV) { + sh532u_del(info); + return -ENODEV; + } else { + dev_err(&client->dev, "%s dev %x not found\n", + __func__, SH532U_ID); + } } else { - sh532u_pm_wr(info, NVC_PWR_OFF); + dev_dbg(&client->dev, "%s device found\n", __func__); + sh532u_pm_dev_wr(info, NVC_PWR_ON); + sh532u_calibration(info, false); + if (info->pdata->cfg & NVC_CFG_BOOT_INIT) + /* initial move causes full initialization */ + sh532u_pos_rel_wr(info, + info->cap.focus_infinity); } + sh532u_pm_dev_wr(info, NVC_PWR_OFF); } if (info->pdata->dev_name != 0) @@ -1648,7 +1885,7 @@ static int sh532u_probe( info->miscdev.minor = MISC_DYNAMIC_MINOR; if (misc_register(&info->miscdev)) { dev_err(&client->dev, "%s unable to register misc device %s\n", - __func__, dname); + __func__, dname); sh532u_del(info); return -ENODEV; } diff --git a/drivers/media/video/tegra/soc380.c b/drivers/media/video/tegra/soc380.c index 7f2c13614660..e0022166fff6 100644 --- a/drivers/media/video/tegra/soc380.c +++ b/drivers/media/video/tegra/soc380.c @@ -471,3 +471,4 @@ static void __exit soc380_exit(void) module_init(soc380_init); module_exit(soc380_exit); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/tegra/tegra_camera.c b/drivers/media/video/tegra/tegra_camera.c index e90b130bcd65..de0c662ba613 100644 --- a/drivers/media/video/tegra/tegra_camera.c +++ b/drivers/media/video/tegra/tegra_camera.c @@ -48,7 +48,8 @@ struct tegra_camera_dev { struct regulator *reg; struct tegra_camera_clk_info info; struct mutex tegra_camera_lock; - int power_refcnt; + atomic_t in_use; + int power_on; }; struct tegra_camera_block { @@ -57,56 +58,47 @@ struct tegra_camera_block { bool is_enabled; }; -static int tegra_camera_enable_isp(struct tegra_camera_dev *dev) +static int tegra_camera_enable_clk(struct tegra_camera_dev *dev) { - return clk_enable(dev->isp_clk); -} - -static int tegra_camera_disable_isp(struct tegra_camera_dev *dev) -{ - clk_disable(dev->isp_clk); + clk_enable(dev->vi_clk); + clk_enable(dev->vi_sensor_clk); + clk_enable(dev->csus_clk); + + tegra_periph_reset_assert(dev->vi_clk); + udelay(2); + tegra_periph_reset_deassert(dev->vi_clk); + + clk_enable(dev->isp_clk); + tegra_periph_reset_assert(dev->isp_clk); + udelay(2); + tegra_periph_reset_deassert(dev->isp_clk); + + clk_enable(dev->csi_clk); + tegra_periph_reset_assert(dev->csi_clk); + udelay(2); + tegra_periph_reset_deassert(dev->csi_clk); return 0; } -static int tegra_camera_enable_vi(struct tegra_camera_dev *dev) -{ - int ret = 0; - - ret |= clk_enable(dev->vi_clk); - ret |= clk_enable(dev->vi_sensor_clk); - ret |= clk_enable(dev->csus_clk); - return ret; -} - -static int tegra_camera_disable_vi(struct tegra_camera_dev *dev) +static int tegra_camera_disable_clk(struct tegra_camera_dev *dev) { - clk_disable(dev->vi_clk); - clk_disable(dev->vi_sensor_clk); + clk_disable(dev->csi_clk); + tegra_periph_reset_assert(dev->csi_clk); + clk_disable(dev->isp_clk); + tegra_periph_reset_assert(dev->isp_clk); clk_disable(dev->csus_clk); - return 0; -} - -static int tegra_camera_enable_csi(struct tegra_camera_dev *dev) -{ - return clk_enable(dev->csi_clk); -} + clk_disable(dev->vi_sensor_clk); + clk_disable(dev->vi_clk); + tegra_periph_reset_assert(dev->vi_clk); -static int tegra_camera_disable_csi(struct tegra_camera_dev *dev) -{ - clk_disable(dev->csi_clk); return 0; } static int tegra_camera_enable_emc(struct tegra_camera_dev *dev) { - /* tegra_camera wasn't added as a user of emc_clk until 3x. - set to 150 MHz, will likely need to be increased as we support - sensors with higher framerates and resolutions. */ clk_enable(dev->emc_clk); #ifdef CONFIG_ARCH_TEGRA_2x_SOC clk_set_rate(dev->emc_clk, 300000000); -#else - clk_set_rate(dev->emc_clk, 150000000); #endif return 0; } @@ -117,32 +109,6 @@ static int tegra_camera_disable_emc(struct tegra_camera_dev *dev) return 0; } -struct tegra_camera_block tegra_camera_block[] = { - [TEGRA_CAMERA_MODULE_ISP] = {tegra_camera_enable_isp, - tegra_camera_disable_isp, false}, - [TEGRA_CAMERA_MODULE_VI] = {tegra_camera_enable_vi, - tegra_camera_disable_vi, false}, - [TEGRA_CAMERA_MODULE_CSI] = {tegra_camera_enable_csi, - tegra_camera_disable_csi, false}, -}; - -#define TEGRA_CAMERA_VI_CLK_SEL_INTERNAL 0 -#define TEGRA_CAMERA_VI_CLK_SEL_EXTERNAL (1<<24) -#define TEGRA_CAMERA_PD2VI_CLK_SEL_VI_SENSOR_CLK (1<<25) -#define TEGRA_CAMERA_PD2VI_CLK_SEL_PD2VI_CLK 0 - -static bool tegra_camera_enabled(struct tegra_camera_dev *dev) -{ - bool ret = false; - - mutex_lock(&dev->tegra_camera_lock); - ret = tegra_camera_block[TEGRA_CAMERA_MODULE_ISP].is_enabled == true || - tegra_camera_block[TEGRA_CAMERA_MODULE_VI].is_enabled == true || - tegra_camera_block[TEGRA_CAMERA_MODULE_CSI].is_enabled == true; - mutex_unlock(&dev->tegra_camera_lock); - return ret; -} - static int tegra_camera_clk_set_rate(struct tegra_camera_dev *dev) { struct clk *clk, *clk_parent; @@ -156,7 +122,8 @@ static int tegra_camera_clk_set_rate(struct tegra_camera_dev *dev) return -EINVAL; } - if (info->id != TEGRA_CAMERA_MODULE_VI) { + if (info->id != TEGRA_CAMERA_MODULE_VI && + info->id != TEGRA_CAMERA_MODULE_EMC) { dev_err(dev->dev, "%s: set rate only aplies to vi module %d\n", __func__, info->id); @@ -170,6 +137,14 @@ static int tegra_camera_clk_set_rate(struct tegra_camera_dev *dev) case TEGRA_CAMERA_VI_SENSOR_CLK: clk = dev->vi_sensor_clk; break; + case TEGRA_CAMERA_EMC_CLK: + clk = dev->emc_clk; +#ifndef CONFIG_ARCH_TEGRA_2x_SOC + dev_dbg(dev->dev, "%s: emc_clk rate=%lu\n", + __func__, info->rate); + clk_set_rate(dev->emc_clk, info->rate); +#endif + goto set_rate_end; default: dev_err(dev->dev, "%s: invalid clk id for set rate %d\n", @@ -215,61 +190,39 @@ static int tegra_camera_clk_set_rate(struct tegra_camera_dev *dev) #endif } +set_rate_end: info->rate = clk_get_rate(clk); dev_dbg(dev->dev, "%s: get_rate=%lu", __func__, info->rate); return 0; } -static int tegra_camera_reset(struct tegra_camera_dev *dev, uint id) -{ - struct clk *clk; - - switch (id) { - case TEGRA_CAMERA_MODULE_VI: - clk = dev->vi_clk; - break; - case TEGRA_CAMERA_MODULE_ISP: - clk = dev->isp_clk; - break; - case TEGRA_CAMERA_MODULE_CSI: - clk = dev->csi_clk; - break; - default: - return -EINVAL; - } - tegra_periph_reset_assert(clk); - udelay(10); - tegra_periph_reset_deassert(clk); - - return 0; -} static int tegra_camera_power_on(struct tegra_camera_dev *dev) { int ret = 0; - if (dev->power_refcnt++ == 0) { - /* Enable external power */ - if (dev->reg) { - ret = regulator_enable(dev->reg); - if (ret) { - dev_err(dev->dev, - "%s: enable csi regulator failed.\n", - __func__); - return ret; - } - } -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* Unpowergate VE */ - ret = tegra_unpowergate_partition(TEGRA_POWERGATE_VENC); - if (ret) + dev_dbg(dev->dev, "%s++\n", __func__); + + /* Enable external power */ + if (dev->reg) { + ret = regulator_enable(dev->reg); + if (ret) { dev_err(dev->dev, - "%s: unpowergate failed.\n", + "%s: enable csi regulator failed.\n", __func__); -#endif + return ret; + } } - +#ifndef CONFIG_ARCH_TEGRA_2x_SOC + /* Unpowergate VE */ + ret = tegra_unpowergate_partition(TEGRA_POWERGATE_VENC); + if (ret) + dev_err(dev->dev, + "%s: unpowergate failed.\n", + __func__); +#endif + dev->power_on = 1; return ret; } @@ -277,26 +230,27 @@ static int tegra_camera_power_off(struct tegra_camera_dev *dev) { int ret = 0; - if (--dev->power_refcnt == 0) { + dev_dbg(dev->dev, "%s++\n", __func__); + #ifndef CONFIG_ARCH_TEGRA_2x_SOC - /* Powergate VE */ - ret = tegra_powergate_partition(TEGRA_POWERGATE_VENC); - if (ret) + /* Powergate VE */ + ret = tegra_powergate_partition(TEGRA_POWERGATE_VENC); + if (ret) + dev_err(dev->dev, + "%s: powergate failed.\n", + __func__); +#endif + /* Disable external power */ + if (dev->reg) { + ret = regulator_disable(dev->reg); + if (ret) { dev_err(dev->dev, - "%s: powergate failed.\n", + "%s: disable csi regulator failed.\n", __func__); -#endif - /* Disable external power */ - if (dev->reg) { - ret = regulator_disable(dev->reg); - if (ret) { - dev_err(dev->dev, - "%s: disable csi regulator failed.\n", - __func__); - return ret; - } + return ret; } } + dev->power_on = 0; return ret; } @@ -313,7 +267,7 @@ static long tegra_camera_ioctl(struct file *file, return -EFAULT; } - if (id >= ARRAY_SIZE(tegra_camera_block)) { + if (id >= TEGRA_CAMERA_MODULE_MAX) { dev_err(dev->dev, "%s: Invalid id to tegra isp ioctl%d\n", __func__, id); @@ -321,44 +275,15 @@ static long tegra_camera_ioctl(struct file *file, } switch (cmd) { + /* + * Clock enable/disable and reset should be handled in kernel. + * In order to support legacy code in user space, we don't remove + * these IOCTL. + */ case TEGRA_CAMERA_IOCTL_ENABLE: - { - int ret = 0; - - mutex_lock(&dev->tegra_camera_lock); - /* Unpowergate camera blocks (vi, csi and isp) - before enabling clocks */ - ret = tegra_camera_power_on(dev); - if (ret) { - dev->power_refcnt = 0; - mutex_unlock(&dev->tegra_camera_lock); - return ret; - } - - if (!tegra_camera_block[id].is_enabled) { - ret = tegra_camera_block[id].enable(dev); - tegra_camera_block[id].is_enabled = true; - } - mutex_unlock(&dev->tegra_camera_lock); - return ret; - } case TEGRA_CAMERA_IOCTL_DISABLE: - { - int ret = 0; - - mutex_lock(&dev->tegra_camera_lock); - if (tegra_camera_block[id].is_enabled) { - ret = tegra_camera_block[id].disable(dev); - tegra_camera_block[id].is_enabled = false; - } - /* Powergate camera blocks (vi, csi and isp) - after disabling all the clocks */ - if (!ret) { - ret = tegra_camera_power_off(dev); - } - mutex_unlock(&dev->tegra_camera_lock); - return ret; - } + case TEGRA_CAMERA_IOCTL_RESET: + return 0; case TEGRA_CAMERA_IOCTL_CLK_SET_RATE: { int ret; @@ -380,8 +305,6 @@ static long tegra_camera_ioctl(struct file *file, } return 0; } - case TEGRA_CAMERA_IOCTL_RESET: - return tegra_camera_reset(dev, id); default: dev_err(dev->dev, "%s: Unknown tegra_camera ioctl.\n", __func__); @@ -396,40 +319,58 @@ static int tegra_camera_open(struct inode *inode, struct file *file) struct tegra_camera_dev *dev = container_of(miscdev, struct tegra_camera_dev, misc_dev); + int ret = 0; + dev_info(dev->dev, "%s\n", __func__); - file->private_data = dev; - tegra_camera_enable_emc(dev); + if (atomic_xchg(&dev->in_use, 1)) + return -EBUSY; - return 0; + file->private_data = dev; + + mutex_lock(&dev->tegra_camera_lock); + /* turn on CSI regulator */ + ret = tegra_camera_power_on(dev); + if (ret) + goto open_exit; + /* set EMC request */ + ret = tegra_camera_enable_emc(dev); + if (ret) + goto open_exit; + /* enable camera HW clock */ + ret = tegra_camera_enable_clk(dev); + if (ret) + goto open_exit; +open_exit: + mutex_unlock(&dev->tegra_camera_lock); + return ret; } static int tegra_camera_release(struct inode *inode, struct file *file) { - int i, err; + int ret = 0; struct tegra_camera_dev *dev = file->private_data; dev_info(dev->dev, "%s\n", __func__); - for (i = 0; i < ARRAY_SIZE(tegra_camera_block); i++) - if (tegra_camera_block[i].is_enabled) { - tegra_camera_block[i].disable(dev); - tegra_camera_block[i].is_enabled = false; - } - /* If camera blocks are not powergated yet, do it now */ - if (dev->power_refcnt > 0) { - mutex_lock(&dev->tegra_camera_lock); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - err = tegra_powergate_partition(TEGRA_POWERGATE_VENC); - if (err) - dev_err(dev->dev, "%s: powergate failed.\n", __func__); -#endif - dev->power_refcnt = 0; - mutex_unlock(&dev->tegra_camera_lock); - } - - tegra_camera_disable_emc(dev); + mutex_lock(&dev->tegra_camera_lock); + /* disable HW clock */ + ret = tegra_camera_disable_clk(dev); + if (ret) + goto release_exit; + /* nullify EMC request */ + ret = tegra_camera_disable_emc(dev); + if (ret) + goto release_exit; + /* turn off CSI regulator */ + tegra_camera_power_off(dev); + if (ret) + goto release_exit; + +release_exit: + mutex_unlock(&dev->tegra_camera_lock); + WARN_ON(!atomic_xchg(&dev->in_use, 0)); return 0; } @@ -472,7 +413,6 @@ static int tegra_camera_probe(struct platform_device *pdev) /* Powergate VE when boot */ mutex_lock(&dev->tegra_camera_lock); - dev->power_refcnt = 0; #ifndef CONFIG_ARCH_TEGRA_2x_SOC err = tegra_powergate_partition(TEGRA_POWERGATE_VENC); if (err) @@ -574,12 +514,14 @@ static int tegra_camera_suspend(struct platform_device *pdev, pm_message_t state struct tegra_camera_dev *dev = platform_get_drvdata(pdev); int ret = 0; - if (tegra_camera_enabled(dev)) { + mutex_lock(&dev->tegra_camera_lock); + if (dev->power_on) { ret = -EBUSY; dev_err(&pdev->dev, "tegra_camera cannot suspend, " "application is holding on to camera. \n"); } + mutex_unlock(&dev->tegra_camera_lock); return ret; } |