summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch')
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch228
1 files changed, 228 insertions, 0 deletions
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch
new file mode 100644
index 00000000..efe99fbd
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch
@@ -0,0 +1,228 @@
+From 95a48f63ed8839cce6d91c53a72f67551c2f7a92 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 13 May 2019 16:38:48 +0300
+Subject: [PATCH 117/122] lvds: ISX019: fix add address intf, fix read/write
+
+- Add command/address register access interfaces
+- fix endianess of data
+- read resolution from registers
+---
+ drivers/media/i2c/soc_camera/isx019.c | 112 ++++++++++++++++++++--------------
+ drivers/media/i2c/soc_camera/isx019.h | 9 ++-
+ 2 files changed, 73 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/isx019.c b/drivers/media/i2c/soc_camera/isx019.c
+index 650b533..c2f5a4a 100644
+--- a/drivers/media/i2c/soc_camera/isx019.c
++++ b/drivers/media/i2c/soc_camera/isx019.c
+@@ -25,7 +25,7 @@
+ static const int isx019_i2c_addr[] = {0x1a};
+
+ #define ISX019_PID 0x0000
+-#define ISX019_VERSION_REG 0x0740
++#define ISX019_VERSION_REG 0x4000
+
+ #define ISX019_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
+
+@@ -51,6 +51,10 @@ struct isx019_priv {
+ int gpio_fsin;
+ };
+
++static char *intf = "command";
++module_param(intf, charp, 0644);
++MODULE_PARM_DESC(intf, " Registers access interface command,address (default: command)");
++
+ static inline struct isx019_priv *to_isx019(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct isx019_priv, sd);
+@@ -72,31 +76,40 @@ static void isx019_s_port(struct i2c_client *client, int fwd_en)
+
+ static int isx019_read16(struct i2c_client *client, u8 category, u16 reg, u16 *val)
+ {
+- int ret;
++ int ret = -1;
++
++ if (strcmp(intf, "command") == 0) {
+ #define R_NUM_BYTES 9
+ #define R_NUM_CMDS 1
+ #define R_NUM_CMD_BYTES 6
+ #define R_CMD 1
+ #define R_BYTES 2
+- u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
+- R_NUM_CMD_BYTES, R_CMD,
+- category, reg >> 8, reg & 0xff,
+- R_BYTES, 0x00};
+-
+- /* calculate checksum */
+- buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
+- category + (reg >> 8) + (reg & 0xff) + R_BYTES;
+-
+- ret = i2c_master_send(client, buf, R_NUM_BYTES);
+- if (ret == R_NUM_BYTES)
+- ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
+-
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "read fail: chip 0x%x register 0x%x: %d\n",
+- client->addr, reg, ret);
++ u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
++ R_NUM_CMD_BYTES, R_CMD,
++ category, reg >> 8, reg & 0xff,
++ R_BYTES, 0x00};
++
++ /* calculate checksum */
++ buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
++ category + (reg >> 8) + (reg & 0xff) + R_BYTES;
++
++ ret = i2c_master_send(client, buf, R_NUM_BYTES);
++ if (ret == R_NUM_BYTES)
++ ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = buf[4] | ((u16)buf[5] << 8);
++ }
++ } else if (strcmp(intf, "address") == 0) {
++ reg16_write(client, 0xFFFF, category);
++ ret = reg16_read16(client, reg, val);
++ *val = swab16p(val);
+ } else {
+- *val = ((u16)buf[4] << 8) | buf[5];
++ dev_err(&client->dev, "invalid register access interface %s\n", intf);
+ }
+
+ return ret < 0 ? ret : 0;
+@@ -104,26 +117,35 @@ static int isx019_read16(struct i2c_client *client, u8 category, u16 reg, u16 *v
+
+ static int isx019_write16(struct i2c_client *client, u8 category, u16 reg, u16 val)
+ {
+- int ret;
++ int ret = -1;
++
++ if (strcmp(intf, "command") == 0) {
+ #define W_NUM_BYTES 10
+ #define W_NUM_CMDS 1
+ #define W_NUM_CMD_BYTES 7
+ #define W_CMD 2
+- u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
+- W_NUM_CMD_BYTES, W_CMD,
+- category, reg >> 8, reg & 0xff,
+- val >> 8, val & 0xff};
++ u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
++ W_NUM_CMD_BYTES, W_CMD,
++ category, reg >> 8, reg & 0xff,
++ val & 0xff, val >> 8};
+
+- /* calculate checksum */
+- buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
+- category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
++ /* calculate checksum */
++ buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
++ category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
+
+- ret = i2c_master_send(client, buf, W_NUM_BYTES);
++ ret = i2c_master_send(client, buf, W_NUM_BYTES);
+
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "write fail: chip 0x%x register 0x%x: %d\n",
+- client->addr, reg, ret);
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++ } else if (strcmp(intf, "address") == 0) {
++ val = swab16(val);
++ reg16_write(client, 0xFFFF, category);
++ ret = reg16_write16(client, reg, val);
++ } else {
++ dev_err(&client->dev, "invalid register acces interface %s\n", intf);
+ }
+
+ return ret < 0 ? ret : 0;
+@@ -404,13 +426,11 @@ static DEVICE_ATTR(otp_id_isx019, S_IRUGO, isx019_otp_id_show, NULL);
+ static int isx019_initialize(struct i2c_client *client)
+ {
+ struct isx019_priv *priv = to_isx019(client);
+- u16 pid = 0;
++ u16 pid = 0, val = 0;
+ int ret = 0;
+ int tmp_addr;
+ int i;
+
+- isx019_s_port(client, 1);
+-
+ for (i = 0; i < ARRAY_SIZE(isx019_i2c_addr); i++) {
+ tmp_addr = client->addr;
+ if (priv->max9286_addr) {
+@@ -423,26 +443,28 @@ static int isx019_initialize(struct i2c_client *client)
+ /* check model ID */
+ isx019_read16(client, 0, ISX019_PID, &pid);
+
+- if (pid == ISX019_VERSION_REG)
++ if ((pid & 0xff00) == ISX019_VERSION_REG)
+ break;
+ }
+
+- if (pid != ISX019_VERSION_REG) {
+- dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ if ((pid & 0xff00) != ISX019_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x\n", pid);
+ ret = -ENODEV;
+ goto err;
+ }
+
+- priv->max_width = ISX019_MAX_WIDTH;
+- priv->max_height = ISX019_MAX_HEIGHT;
+-
+ /* Read OTP IDs */
+ isx019_otp_id_read(client);
+ /* Program wizard registers */
+ isx019_set_regs(client, isx019_regs_wizard, ARRAY_SIZE(isx019_regs_wizard));
+-
+- dev_info(&client->dev, "isx019 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ /* read resolution used by current firmware */
++ isx019_read16(client, 86, 0x8, &val);
++ priv->max_width = val;
++ isx019_read16(client, 86, 0xa, &val);
++ priv->max_height = val;
++
++ dev_info(&client->dev, "isx019 PID %x (rev %x), res %dx%d, if=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid & 0xff00, pid & 0xff, priv->max_width, priv->max_height, intf, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ isx019_s_port(client, 0);
+
+diff --git a/drivers/media/i2c/soc_camera/isx019.h b/drivers/media/i2c/soc_camera/isx019.h
+index edaa767..c7072a3 100644
+--- a/drivers/media/i2c/soc_camera/isx019.h
++++ b/drivers/media/i2c/soc_camera/isx019.h
+@@ -9,8 +9,8 @@
+ * option) any later version.
+ */
+
+-#define ISX019_MAX_WIDTH 1280
+-#define ISX019_MAX_HEIGHT 800
++//#define ISX019_MAX_WIDTH 1280
++//#define ISX019_MAX_HEIGHT 960
+
+ #define ISX019_DELAY 0xffff
+
+@@ -22,6 +22,9 @@ struct isx019_reg {
+ static const struct isx019_reg isx019_regs_wizard[] = {
+ #if 0
+ /* enable FSIN */
+-#endif
+ {ISX019_DELAY, 100},
++#endif
++/* disable embedded data */
++{0x504c, 0x0},
++{0x504e, 0x0},
+ };
+--
+2.7.4
+