summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQinggang Zhou <qzhou@nvidia.com>2011-03-12 00:03:43 -0800
committerVarun Colbert <vcolbert@nvidia.com>2011-03-17 20:45:42 -0800
commitd0139efe969951cb144a77a13e65f67ac4b82b84 (patch)
treeda6465905d2e4cc8caa49b30db39a1589d29cea9
parent8fa457c5ac6394a181610e9a095586e4a8ff3123 (diff)
media: video: tegra: SH532U: Add the SH532U focuser driver.
This focuser is from SEMCO and is integrated with OV5650 sensor and LC898211 driver. bug 778859 Change-Id: I6e5dcc129c72aed7d92a00a1d926424050583c1d Reviewed-on: http://git-master/r/22711 Reviewed-by: Qinggang Zhou <qzhou@nvidia.com> Tested-by: Qinggang Zhou <qzhou@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
-rw-r--r--drivers/media/video/tegra/Kconfig6
-rw-r--r--drivers/media/video/tegra/Makefile2
-rw-r--r--drivers/media/video/tegra/sh532u.c585
-rw-r--r--include/media/sh532u.h303
4 files changed, 896 insertions, 0 deletions
diff --git a/drivers/media/video/tegra/Kconfig b/drivers/media/video/tegra/Kconfig
index d6e5368f5652..dcf41a9afedc 100644
--- a/drivers/media/video/tegra/Kconfig
+++ b/drivers/media/video/tegra/Kconfig
@@ -28,5 +28,11 @@ config TORCH_SSL3250A
depends on I2C && ARCH_TEGRA
---help---
This is a driver for the SSL3250A flash/torch camera device
+
+config VIDEO_SH532U
+ tristate "SH532U focuser support"
+ depends on I2C && ARCH_TEGRA
+ ---help---
+ This is a driver for the SEMCO SH532U focuser
for use with the tegra isp.
diff --git a/drivers/media/video/tegra/Makefile b/drivers/media/video/tegra/Makefile
index 1aacd5ef07d2..ce0cb388f8b5 100644
--- a/drivers/media/video/tegra/Makefile
+++ b/drivers/media/video/tegra/Makefile
@@ -6,4 +6,6 @@ obj-$(CONFIG_TEGRA_CAMERA) += tegra_camera.o
obj-$(CONFIG_VIDEO_OV5650) += ov5650.o
obj-$(CONFIG_VIDEO_OV2710) += ov2710.o
obj-$(CONFIG_TORCH_SSL3250A) += ssl3250a.o
+obj-$(CONFIG_VIDEO_SH532U) += sh532u.o
+
diff --git a/drivers/media/video/tegra/sh532u.c b/drivers/media/video/tegra/sh532u.c
new file mode 100644
index 000000000000..bc9fa43a8d30
--- /dev/null
+++ b/drivers/media/video/tegra/sh532u.c
@@ -0,0 +1,585 @@
+/*
+ * SH532U focuser driver.
+ *
+ * Copyright (C) 2011 NVIDIA Corporation.
+ *
+ * Contributors:
+ * Qinggang Zhou <qzhou@nvidia.com>
+ *
+ * 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
+ */
+
+#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/sh532u.h>
+
+#include <asm/traps.h>
+
+#define POS_LOW (0xA000)
+#define POS_HIGH (0x6000)
+#define SETTLETIME_MS (7)
+#define FOCAL_LENGTH 0x408d70a4 /* (4.42f) */
+#define FNUMBER 0x40333333 /* (2.8f) */
+
+
+struct sh532u_info {
+ struct i2c_client *i2c_client;
+ struct sh532u_config config;
+};
+
+static struct sh532u_info *info;
+
+static int sh532u_read_u8(u8 dev, u8 addr, u8 *val)
+{
+ struct i2c_client *client = info->i2c_client;
+ struct i2c_msg msg[2];
+ unsigned char data[3];
+
+ if (dev)
+ msg[0].addr = dev;
+ else
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = data;
+
+ data[0] = (u8)addr;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 1;
+ msg[1].buf = data + 2;
+
+ if (i2c_transfer(client->adapter, msg, 2) != 2)
+ return -1;
+ *val = data[2];
+ return 0;
+}
+
+static int sh532u_read_u16(u8 addr, u16 *val)
+{
+ struct i2c_client *client = info->i2c_client;
+ struct i2c_msg msg[2];
+ u8 buf[4];
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = &buf[0];
+
+ /* high byte goes out first */
+ buf[0] = (u8) (addr);
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 2;
+ msg[1].buf = &buf[1];
+
+ if (i2c_transfer(client->adapter, msg, 2) != 2)
+ return -1;
+ *val = (((u16)buf[1] << 8) | (u16)buf[2]);
+ return 0;
+}
+
+static int eeprom_read_u32(u8 addr, u32 *val)
+{
+ struct i2c_client *client = info->i2c_client;
+ struct i2c_msg msg[2];
+ union {
+ u8 dataU8[8];
+ u32 dataU32[2];
+ } buffer;
+
+ msg[0].addr = 0x50;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = &(buffer.dataU8[0]);
+
+ /* high byte goes out first */
+ buffer.dataU8[0] = (u8) (addr);
+ buffer.dataU8[1] = (u8) (0);
+
+ msg[1].addr = 0x50;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 4;
+ msg[1].buf = (u8 *)&(buffer.dataU32[1]);
+
+ if (i2c_transfer(client->adapter, msg, 2) != 2)
+ return -1;
+ *val = buffer.dataU32[1];
+ return 0;
+}
+
+static int sh532u_write_u8(u16 addr, u8 val)
+{
+ struct i2c_client *client = info->i2c_client;
+ struct i2c_msg msg;
+ unsigned char data[2];
+ u8 tmp;
+
+ data[0] = (u8) (addr & 0xff);
+ data[1] = (u8) (val & 0xff);
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ msg.buf = data;
+
+ if (i2c_transfer(client->adapter, &msg, 1) != 1)
+ return -1;
+
+ return 0;
+}
+
+static int sh532u_write_u16(u16 addr, u16 val)
+{
+ struct i2c_client *client = info->i2c_client;
+ struct i2c_msg msg;
+ unsigned char data[3];
+
+ data[0] = (u8) (addr & 0xff);
+ data[1] = (u8) (val >> 8);
+ data[2] = (u8) (val & 0xff);
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 3;
+ msg.buf = data;
+
+ if (i2c_transfer(client->adapter, &msg, 1) != 1)
+ return -1;
+ return 0;
+}
+
+static void move_driver(s16 tarPos)
+{
+ s16 curPos, moveStep;
+ u16 moveDistance;
+ int err;
+
+ /* Read Current Position */
+ err = sh532u_read_u16(RZ_211H, &curPos);
+ if (err)
+ goto move_driver_error;
+ /* Check move distance to Target Position */
+ moveDistance = abs((int)curPos - (int)tarPos);
+
+ /* if move distance is shorter than MS1Z12(=Step width) */
+ if (moveDistance <= STMV_SIZE) {
+ err = sh532u_write_u8(MSSET_211, (INI_MSSET_211 | 0x01));
+ err = err | sh532u_write_u16(MS1Z22_211H, tarPos);
+ if (err)
+ goto move_driver_error;
+ } else {
+ if (curPos < tarPos)
+ moveStep = STMV_SIZE;
+ else
+ moveStep = -STMV_SIZE;
+
+ /* Set StepMove Target Positon */
+ err = sh532u_write_u16(MS1Z12_211H, moveStep);
+ err = err | sh532u_write_u16(STMVENDH_211, tarPos);
+ /* Start StepMove */
+ err = err |
+ sh532u_write_u8(
+ STMVEN_211,
+ (STMCHTG_ON | STMSV_ON | STMLFF_OFF | STMVEN_ON));
+ if (err)
+ goto move_driver_error;
+ }
+
+ return;
+move_driver_error:
+ pr_err("Focuser: %s failed!\n", __func__);
+}
+
+static void wait_for_move(void)
+{
+ u16 usSmvFin;
+ u8 moveTime, ucParMod, tmp;
+ int err;
+
+ moveTime = 0;
+ do {
+ mdelay(1);
+ err = sh532u_read_u8(0, STMVEN_211, &ucParMod);
+ err = err | sh532u_read_u16(RZ_211H, &usSmvFin);
+ if (err)
+ goto wait_for_move_error;
+ /* StepMove Error Handling, Unexpected Position */
+ if ((usSmvFin == 0x7FFF) || (usSmvFin == 0x8001)) {
+ /* Stop StepMove Operation */
+ err = sh532u_write_u8(STMVEN_211, ucParMod & 0xFE);
+ if (err)
+ goto wait_for_move_error;
+ }
+ moveTime++;
+ /* Wait StepMove operation end */
+ } while ((ucParMod & STMVEN_ON) && (moveTime < 50));
+
+ moveTime = 0;
+ if ((ucParMod & 0x08) == STMCHTG_ON) {
+ mdelay(5);
+ do {
+ mdelay(1);
+ moveTime++;
+ err = sh532u_read_u8(0, MSSET_211, &tmp);
+ if (err)
+ goto wait_for_move_error;
+ } while ((tmp & CHTGST_ON) && (moveTime < 15));
+ }
+
+ return;
+wait_for_move_error:
+ pr_err("Focuser: %s failed!\n", __func__);
+}
+
+static void lens_move_pulse(s16 position)
+{
+ move_driver(position);
+ wait_for_move();
+}
+
+static void get_rom_info(void)
+{
+ u8 tmp;
+ int err;
+
+ /* Get Inf1, Mac1
+ Inf1 and Mac1 are the mechanical limit position.
+ Inf1 : Bottom limit.
+ Mac1 : Top limit. */
+ err = sh532u_read_u8(0x50, addrMac1, &tmp);
+ if (err)
+ goto get_rom_info_error;
+ info->config.limit_low = (tmp<<8) & 0xff00;
+ err = sh532u_read_u8(0x50, addrInf1, &tmp);
+ if (err)
+ goto get_rom_info_error;
+ info->config.limit_high = (tmp<<8) & 0xff00;
+
+ /* Get Inf2, Mac2
+ Inf2 and Mac2 are the calibration data for SEMCO AF lens.
+ Inf2: Best focus (lens position) when object distance is 1.2M.
+ Mac2: Best focus (lens position) when object distance is 10cm. */
+ err = sh532u_read_u8(0x50, addrMac2, &tmp);
+ if (err)
+ goto get_rom_info_error;
+ info->config.pos_low = (tmp << 8) & 0xff00;
+ err = sh532u_read_u8(0x50, addrInf2, &tmp);
+ if (err)
+ goto get_rom_info_error;
+ info->config.pos_high = (tmp << 8) & 0xff00;
+
+ return;
+get_rom_info_error:
+ pr_err("Focuser: %s failed!\n", __func__);
+ info->config.limit_high = POS_HIGH;
+ info->config.limit_low = POS_LOW;
+ info->config.pos_high = POS_HIGH;
+ info->config.pos_low = POS_LOW;
+}
+
+static void init_hvca_pos(void)
+{
+ short sBottomLimit, sTopLimit;
+
+ get_rom_info();
+ sBottomLimit = (((int)info->config.limit_low * 5) >> 3) & 0xFFC0;
+ lens_move_pulse(sBottomLimit);
+ sTopLimit = (((int)info->config.limit_high * 5) >> 3) & 0xFFC0;
+ lens_move_pulse(sTopLimit);
+ lens_move_pulse(info->config.pos_high);
+}
+
+static unsigned int a2buf[] = {
+ 0x0018019c,
+ 0x0018019d,
+ 0x0000019e,
+ 0x007f0192,
+ 0x00000194,
+ 0x00f00184,
+ 0x00850187,
+ 0x0000018a,
+ 0x00fd7187,
+ 0x007f7183,
+ 0x0008025a,
+ 0x05042218,
+ 0x80010216,
+ 0x000601a0,
+ 0x00808183,
+ 0xffffffff
+};
+
+/* Write 1 byte data to the HVCA Drive IC by data type */
+static void sh532u_hvca_wr1(u8 ep_type, u8 ep_data1, u8 ep_addr)
+{
+ int err;
+ u8 us_data;
+
+ switch (ep_type & 0xF0) {
+ case DIRECT_MODE:
+ us_data = ep_data1;
+ break;
+
+ case INDIRECT_EEPROM:
+ err = sh532u_read_u8(0x50, ep_data1, &us_data);
+ break;
+
+ case INDIRECT_HVCA:
+ err = sh532u_read_u8(0, (u16)ep_data1, &us_data);
+ break;
+
+ case MASK_AND:
+ err = sh532u_read_u8(0, (u16)ep_addr, &us_data);
+ us_data = us_data & ep_data1;
+ break;
+
+ case MASK_OR:
+ err = sh532u_read_u8(0, (u16)ep_addr, &us_data);
+ us_data = us_data | ep_data1;
+ break;
+
+ default:
+ err = 1;
+ }
+ if (!err)
+ sh532u_write_u8((u16)ep_addr, us_data);
+}
+
+/* Write 2 byte data to the HVCA Drive IC by data type */
+static void sh532u_hvca_wr2(u8 ep_type, u8 ep_data1, u8 ep_data2, u8 ep_addr)
+{
+ int err;
+ u8 uc_data1;
+ u8 uc_data2;
+ u16 us_data;
+
+ switch (ep_type & 0xF0) {
+ case DIRECT_MODE:
+ us_data = (((u16)ep_data1 << 8) & 0xFF00) |
+ ((u16)ep_data2 & 0x00FF);
+ break;
+
+ case INDIRECT_EEPROM:
+ err = sh532u_read_u8(0x50, (u16)ep_data1, &uc_data1);
+ err = err | sh532u_read_u8(0x50, (u16)ep_data2, &uc_data2);
+ us_data = (((u16)uc_data1 << 8) & 0xFF00) |
+ ((u16)uc_data2 & 0x00FF);
+ break;
+
+ case INDIRECT_HVCA:
+ err = sh532u_read_u8(0, (u16)ep_data1, &uc_data1);
+ err = err | sh532u_read_u8(0, (u16)ep_data2, &uc_data2);
+ us_data = (((u16)uc_data1 << 8) & 0xFF00) |
+ ((u16)uc_data2 & 0x00FF);
+ break;
+
+ case MASK_AND:
+ err = sh532u_read_u16((u16)ep_addr, &us_data);
+ us_data = us_data & ((((u16)ep_data1 << 8) & 0xFF00) |
+ ((u16)ep_data2 & 0x00FF));
+ break;
+
+ case MASK_OR:
+ err = sh532u_read_u16((u16)ep_addr, &us_data);
+ us_data = us_data | ((((u16)ep_data1 << 8) & 0xFF00) |
+ ((u16)ep_data2 & 0x00FF));
+ break;
+
+ default:
+ err = 1;
+ }
+ if (!err)
+ sh532u_write_u16((u16)ep_addr, us_data);
+}
+
+static void init_driver(void)
+{
+ int eeprom_addr;
+ unsigned int eeprom_data;
+ u8 ep_addr, ep_type, ep_data1, ep_data2, uc_data;
+
+ for (eeprom_addr = 0x30; eeprom_addr <= 0x013C; eeprom_addr += 4) {
+ if (eeprom_addr > 0xff) {
+ /* use hardcoded data instead */
+ eeprom_data = a2buf[(eeprom_addr & 0xFF) / 4];
+ } else {
+ if (!eeprom_read_u32(eeprom_addr & 0xFF, &eeprom_data))
+ pr_info("sh532u: cannot read eeprom\n");
+ }
+
+ /* HVCA Address to write eeprom Data1,Data2 by the Data type */
+ ep_addr = (u8)(eeprom_data & 0x000000ff);
+ ep_type = (u8)((eeprom_data & 0x0000ff00) >> 8);
+ ep_data1 = (u8)((eeprom_data & 0x00ff0000) >> 16);
+ ep_data2 = (u8)((eeprom_data & 0xff000000) >> 24);
+
+ if (ep_addr == 0xFF)
+ break;
+
+ if (ep_addr == 0xDD) {
+ mdelay((unsigned int)((ep_data1 << 8) | ep_data2));
+ } else {
+ if ((ep_type & 0x0F) == DATA_1BYTE) {
+ sh532u_hvca_wr1(ep_type, ep_data1, ep_addr);
+ } else {
+ sh532u_hvca_wr2(ep_type,
+ ep_data1,
+ ep_data2,
+ ep_addr);
+ }
+ }
+ }
+ msleep(300);
+
+ init_hvca_pos();
+}
+
+
+static int sh532u_set_position(struct sh532u_info *info, s16 position)
+{
+ if (position > info->config.limit_high)
+ return -1;
+ lens_move_pulse(position);
+ return 0;
+}
+
+static long sh532u_ioctl(
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ struct sh532u_info *info = file->private_data;
+
+ switch (cmd) {
+ case SH532U_IOCTL_GET_CONFIG:
+ if (copy_to_user((void __user *) arg,
+ &info->config,
+ sizeof(info->config))) {
+ pr_err("%s: 0x%x\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+
+ case SH532U_IOCTL_SET_POSITION:
+ return sh532u_set_position(info, (s16)(arg & 0xffff));
+
+ default:
+ return -EINVAL;
+ }
+}
+
+
+static int sh532u_open(struct inode *inode, struct file *file)
+{
+ pr_info("sh532 open\n");
+ file->private_data = info;
+ init_driver();
+ return 0;
+}
+
+int sh532u_release(struct inode *inode, struct file *file)
+{
+ pr_info("sh532 release\n");
+ file->private_data = NULL;
+ return 0;
+}
+
+
+static const struct file_operations sh532u_fileops = {
+ .owner = THIS_MODULE,
+ .open = sh532u_open,
+ .unlocked_ioctl = sh532u_ioctl,
+ .release = sh532u_release,
+};
+
+static struct miscdevice sh532u_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "sh532u",
+ .fops = &sh532u_fileops,
+};
+
+static int sh532u_probe(
+ struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err;
+
+ pr_info("sh532u: probing sensor.\n");
+ info = kzalloc(sizeof(struct sh532u_info), GFP_KERNEL);
+ if (!info) {
+ pr_err("sh532u: Unable to allocate memory!\n");
+ return -ENOMEM;
+ }
+ err = misc_register(&sh532u_device);
+ if (err) {
+ pr_err("sh532u: Unable to register misc device!\n");
+ kfree(info);
+ return err;
+ }
+ info->i2c_client = client;
+ info->config.settle_time = SETTLETIME_MS;
+ info->config.focal_length = FOCAL_LENGTH;
+ info->config.fnumber = FNUMBER;
+ info->config.pos_low = POS_LOW;
+ info->config.pos_high = POS_HIGH;
+ i2c_set_clientdata(client, info);
+ return 0;
+}
+
+static int sh532u_remove(struct i2c_client *client)
+{
+ struct sh532u_info *info;
+ info = i2c_get_clientdata(client);
+ misc_deregister(&sh532u_device);
+ kfree(info);
+ return 0;
+}
+
+static const struct i2c_device_id sh532u_id[] = {
+ { "sh532u", 0 },
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, sh532u_id);
+
+static struct i2c_driver sh532u_i2c_driver = {
+ .driver = {
+ .name = "sh532u",
+ .owner = THIS_MODULE,
+ },
+ .probe = sh532u_probe,
+ .remove = sh532u_remove,
+ .id_table = sh532u_id,
+};
+
+static int __init sh532u_init(void)
+{
+ return i2c_add_driver(&sh532u_i2c_driver);
+}
+
+static void __exit sh532u_exit(void)
+{
+ i2c_del_driver(&sh532u_i2c_driver);
+}
+
+module_init(sh532u_init);
+module_exit(sh532u_exit);
+
diff --git a/include/media/sh532u.h b/include/media/sh532u.h
new file mode 100644
index 000000000000..b363c0f279b9
--- /dev/null
+++ b/include/media/sh532u.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2011 NVIDIA Corporation.
+ *
+ * Contributors:
+ * Qinggang Zhou <qzhou@nvidia.com>
+ *
+ * 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 __SH532U_H__
+#define __SH532U_H__
+
+#include <linux/ioctl.h> /* For IOCTL macros */
+
+#define SH532U_IOCTL_GET_CONFIG _IOR('o', 1, struct sh532u_config)
+#define SH532U_IOCTL_SET_POSITION _IOW('o', 2, u32)
+
+struct sh532u_config {
+ __u32 settle_time;
+ __u32 focal_length;
+ __u32 fnumber;
+ s16 pos_low;
+ s16 pos_high;
+ s16 limit_low;
+ s16 limit_high;
+};
+
+/* Register Definition : Sany Driver IC */
+/* EEPROM addresses */
+#define addrHallOffset 0x10
+#define addrHallBias 0x11
+#define addrInf1 0x12
+#define addrMac1 0x13
+#define addrLoopGainH 0x14
+#define addrLoopGainL 0x15
+#define addrInf2 0x16
+#define addrMac2 0x17
+
+#define addrInf1_H 0x20 /* bottom mechanical limit of HVCA */
+#define addrInf1_L 0x21
+#define addrMac1_H 0x22 /* top mechanical limit of HVCA */
+#define addrMac1_L 0x23
+#define addrInf2_H 0x24 /* lens position when object is ?120cm */
+#define addrInf2_L 0x25
+#define addrMac2_H 0x26 /* lens position when object is ?10cm */
+#define addrMac2_L 0x27
+#define addrDacDeltaUp_H 0x28 /* difference between face up and down */
+#define addrDacDeltaUp_L 0x29
+#define addrAFoffset_H 0x2A /* best focus position subtract value */
+#define addrAFoffset_L 0x2B
+
+/* Convergence Judgement */
+#define INI_MSSET_211 0x00
+#define CHTGOKN_TIME 0x80
+#define CHTGOKN_WAIT 1
+#define CHTGOKN_TIMEOUT 50
+#define CHTGSTOKN_TOMEOUT 15
+
+/* StepMove */
+#define STMV_SIZE 0x0180
+
+#define STMCHTG_ON 0x08
+#define STMSV_ON 0x04
+#define STMLFF_ON 0x02
+#define STMVEN_ON 0x01
+#define STMCHTG_OFF 0x00
+#define STMSV_OFF 0x00
+#define STMLFF_OFF 0x00
+#define STMVEN_OFF 0x00
+
+#define STMCHTG_SET STMCHTG_ON
+#define STMSV_SET STMSV_ON
+#define STMLFF_SET STMLFF_OFF
+
+#define CHTGST_ON 0x01
+#define DEFAULT_DADAT 0x8040
+
+/* Delay RAM 00h ~ 3Fh */
+#define ADHXI_211H 0x00
+#define ADHXI_211L 0x01
+#define PIDZO_211H 0x02
+#define PIDZO_211L 0x03
+#define RZ_211H 0x04
+#define RZ_211L 0x05
+#define DZ1_211H 0x06
+#define DZ1_211L 0x07
+#define DZ2_211H 0x08
+#define DZ2_211L 0x09
+#define UZ1_211H 0x0A
+#define UZ1_211L 0x0B
+#define UZ2_211H 0x0C
+#define UZ2_211L 0x0D
+#define IZ1_211H 0x0E
+#define IZ1_211L 0x0F
+#define IZ2_211H 0x10
+#define IZ2_211L 0x11
+#define MS1Z01_211H 0x12
+#define MS1Z01_211L 0x13
+#define MS1Z11_211H 0x14
+#define MS1Z11_211L 0x15
+#define MS1Z12_211H 0x16
+#define MS1Z12_211L 0x17
+#define MS1Z22_211H 0x18
+#define MS1Z22_211L 0x19
+#define MS2Z01_211H 0x1A
+#define MS2Z01_211L 0x1B
+#define MS2Z11_211H 0x1C
+#define MS2Z11_211L 0x1D
+#define MS2Z12_211H 0x1E
+#define MS2Z12_211L 0x1F
+#define MS2Z22_211H 0x20
+#define MS2Z22_211L 0x21
+#define MS2Z23_211H 0x22
+#define MS2Z23_211L 0x23
+#define OZ1_211H 0x24
+#define OZ1_211L 0x25
+#define OZ2_211H 0x26
+#define OZ2_211L 0x27
+#define DAHLXO_211H 0x28
+#define DAHLXO_211L 0x29
+#define OZ3_211H 0x2A
+#define OZ3_211L 0x2B
+#define OZ4_211H 0x2C
+#define OZ4_211L 0x2D
+#define OZ5_211H 0x2E
+#define OZ5_211L 0x2F
+#define oe_211H 0x30
+#define oe_211L 0x31
+#define MSR1CMAX_211H 0x32
+#define MSR1CMAX_211L 0x33
+#define MSR1CMIN_211H 0x34
+#define MSR1CMIN_211L 0x35
+#define MSR2CMAX_211H 0x36
+#define MSR2CMAX_211L 0x37
+#define MSR2CMIN_211H 0x38
+#define MSR2CMIN_211L 0x39
+#define OFFSET_211H 0x3A
+#define OFFSET_211L 0x3B
+#define ADOFFSET_211H 0x3C
+#define ADOFFSET_211L 0x3D
+#define EZ_211H 0x3E
+#define EZ_211L 0x3F
+
+/* Coefficient RAM 40h ~ 7Fh */
+#define ag_211H 0x40
+#define ag_211L 0x41
+#define da_211H 0x42
+#define da_211L 0x43
+#define db_211H 0x44
+#define db_211L 0x45
+#define dc_211H 0x46
+#define dc_211L 0x47
+#define dg_211H 0x48
+#define dg_211L 0x49
+#define pg_211H 0x4A
+#define pg_211L 0x4B
+#define gain1_211H 0x4C
+#define gain1_211L 0x4D
+#define gain2_211H 0x4E
+#define gain2_211L 0x4F
+#define ua_211H 0x50
+#define ua_211L 0x51
+#define uc_211H 0x52
+#define uc_211L 0x53
+#define ia_211H 0x54
+#define ia_211L 0x55
+#define ib_211H 0x56
+#define ib_211L 0x57
+#define i_c_211H 0x58
+#define i_c_211L 0x59
+#define ms11a_211H 0x5A
+#define ms11a_211L 0x5B
+#define ms11c_211H 0x5C
+#define ms11c_211L 0x5D
+#define ms12a_211H 0x5E
+#define ms12a_211L 0x5F
+#define ms12c_211H 0x60
+#define ms12c_211L 0x61
+#define ms21a_211H 0x62
+#define ms21a_211L 0x63
+#define ms21b_211H 0x64
+#define ms21b_211L 0x65
+#define ms21c_211H 0x66
+#define ms21c_211L 0x67
+#define ms22a_211H 0x68
+#define ms22a_211L 0x69
+#define ms22c_211H 0x6A
+#define ms22c_211L 0x6B
+#define ms22d_211H 0x6C
+#define ms22d_211L 0x6D
+#define ms22e_211H 0x6E
+#define ms22e_211L 0x6F
+#define ms23p_211H 0x70
+#define ms23p_211L 0x71
+#define oa_211H 0x72
+#define oa_211L 0x73
+#define oc_211H 0x74
+#define oc_211L 0x75
+#define PX12_211H 0x76
+#define PX12_211L 0x77
+#define PX3_211H 0x78
+#define PX3_211L 0x79
+#define MS2X_211H 0x7A
+#define MS2X_211L 0x7B
+#define CHTGX_211H 0x7C
+#define CHTGX_211L 0x7D
+#define CHTGN_211H 0x7E
+#define CHTGN_211L 0x7F
+
+/* Register 80h ~ 9F */
+#define CLKSEL_211 0x80
+#define ADSET_211 0x81
+#define PWMSEL_211 0x82
+#define SWTCH_211 0x83
+#define STBY_211 0x84
+#define CLR_211 0x85
+#define DSSEL_211 0x86
+#define ENBL_211 0x87
+#define ANA1_211 0x88
+#define STMVEN_211 0x8A
+#define STPT_211 0x8B
+#define SWFC_211 0x8C
+#define SWEN_211 0x8D
+#define MSNUM_211 0x8E
+#define MSSET_211 0x8F
+#define DLYMON_211 0x90
+#define MONA_211 0x91
+#define PWMLIMIT_211 0x92
+#define PINSEL_211 0x93
+#define PWMSEL2_211 0x94
+#define SFTRST_211 0x95
+#define TEST_211 0x96
+#define PWMZONE2_211 0x97
+#define PWMZONE1_211 0x98
+#define PWMZONE0_211 0x99
+#define ZONE3_211 0x9A
+#define ZONE2_211 0x9B
+#define ZONE1_211 0x9C
+#define ZONE0_211 0x9D
+#define GCTIM_211 0x9E
+#define GCTIM_211NU 0x9F
+#define STMINT_211 0xA0
+#define STMVENDH_211 0xA1
+#define STMVENDL_211 0xA2
+#define MSNUMR_211 0xA3
+#define ANA2_211 0xA4
+
+/* Device ID of HVCA Drive IC */
+#define HVCA_DEVICE_ID 0xE4
+
+/* Device ID of E2P ROM */
+#define EEP_DEVICE_ID 0xA0
+#define EEP_PAGE0 0x00
+#define EEP_PAGE1 0x02
+#define EEP_PAGE2 0x04
+#define EEP_PAGE3 0x06
+/* E2P ROM has 1023 bytes. So there are 4 pages memory */
+/* E2PROM Device ID = 1 0 1 0 0 P0 P1 0 */
+/*
+P0 P1
+0 0 : Page 0
+0 1 : Page 1
+1 0 : Page 2
+1 1 : Page 3
+*/
+/* Page 0: address 0x000~0x0FF, E2PROM Device ID = E2P_DEVICE_ID|E2P_PAGE0 */
+/* Page 1: address 0x100~0x1FF, E2PROM Device ID = E2P_DEVICE_ID|E2P_PAGE1 */
+/* Page 2: address 0x200~0x2FF, E2PROM Device ID = E2P_DEVICE_ID|E2P_PAGE2 */
+/* Page 3: address 0x300~0x3FF, E2PROM Device ID = E2P_DEVICE_ID|E2P_PAGE3 */
+/*
+*/
+
+/* E2P data type define of HVCA Initial Value Section */
+#define DIRECT_MODE 0x00
+#define INDIRECT_EEPROM 0x10
+#define INDIRECT_HVCA 0x20
+#define MASK_AND 0x70
+#define MASK_OR 0x80
+
+#define DATA_1BYTE 0x01
+#define DATA_2BYTE 0x02
+
+#define START_ADDR 0x0030
+#define END_ADDR 0x01BF
+
+/*Macro define*/
+#define abs(a) (((a) > 0) ? (a) : -(a))
+
+#endif
+/* __SH532U_H__ */
+