M: Renjun Xu <renjun.xu@amlogic.com>
F: Documentation/devicetree/bindings/amlogic/axg-sound-adc3010-d608mic-pcm.txt
+AMLOGIC LCD EXTERN DRIVER
+M: evoke zhang <evoke.zhang@amlogic.com>
+F: drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c
+
AMLOGIC SYSTEM AS ROOT
M: Xindong Xu <xindong.xu@amlogic.com>
F: arch/arm64/boot/dts/amlogic/firmware_avb_system.dtsi
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
+ i2c_bus = "i2c_bus_1";
key_valid = <0>;
extern_0{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
+ i2c_bus = "i2c_bus_0";
key_valid = <0>;
extern_0{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
+ i2c_bus = "i2c_bus_0";
key_valid = <0>;
extern_0{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
+ i2c_bus = "i2c_bus_d";
key_valid = <0>;
extern_0{
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
i2c_second_address = <0xff>; /* 0xff for none */
- i2c_bus = "i2c_bus_d";
cmd_size = <0xff>; /*0xff for dynamic cmd_size*/
/* init on/off:
type = <0>; /*0=i2c, 1=spi, 2=mipi*/
i2c_address = <0x1c>; /*7bit i2c_addr*/
i2c_second_address = <0xff>;
- i2c_bus = "i2c_bus_c";
cmd_size = <0xff>; /*dynamic cmd_size*/
/* init on/off:
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
- i2c_bus = "i2c_bus_c";
cmd_size = <9>;
};
};
"power_on_step", j, &val);
lcd_power->power_on_step[i].delay = val;
- /* gpio probe */
+ /* gpio/extern probe */
+ index = lcd_power->power_on_step[i].index;
switch (lcd_power->power_on_step[i].type) {
case LCD_POWER_TYPE_CPU:
- index = lcd_power->power_on_step[i].index;
if (index < LCD_CPU_GPIO_NUM_MAX)
lcd_cpu_gpio_probe(index);
break;
+ case LCD_POWER_TYPE_EXTERN:
+ pconf->extern_index = index;
+ break;
default:
break;
}
"power_off_step", j, &val);
lcd_power->power_off_step[i].delay = val;
- /* gpio probe */
+ /* gpio/extern probe */
+ index = lcd_power->power_off_step[i].index;
switch (lcd_power->power_off_step[i].type) {
case LCD_POWER_TYPE_CPU:
- index = lcd_power->power_off_step[i].index;
if (index < LCD_CPU_GPIO_NUM_MAX)
lcd_cpu_gpio_probe(index);
break;
+ case LCD_POWER_TYPE_EXTERN:
+ if (pconf->extern_index == 0xff)
+ pconf->extern_index = index;
+ break;
default:
break;
}
(*(p + LCD_UKEY_PWR_DELAY + 5*i) |
((*(p + LCD_UKEY_PWR_DELAY + 5*i + 1)) << 8));
- /* gpio probe */
+ /* gpio/extern probe */
+ index = pconf->lcd_power->power_on_step[i].index;
switch (pconf->lcd_power->power_on_step[i].type) {
case LCD_POWER_TYPE_CPU:
- index = pconf->lcd_power->power_on_step[i].index;
if (index < LCD_CPU_GPIO_NUM_MAX)
lcd_cpu_gpio_probe(index);
break;
+ case LCD_POWER_TYPE_EXTERN:
+ pconf->extern_index = index;
+ break;
default:
break;
}
(*(p + LCD_UKEY_PWR_DELAY + 5*j) |
((*(p + LCD_UKEY_PWR_DELAY + 5*j + 1)) << 8));
- /* gpio probe */
+ /* gpio/extern probe */
+ index = pconf->lcd_power->power_off_step[j].index;
switch (pconf->lcd_power->power_off_step[j].type) {
case LCD_POWER_TYPE_CPU:
- index = pconf->lcd_power->power_off_step[j].index;
if (index < LCD_CPU_GPIO_NUM_MAX)
lcd_cpu_gpio_probe(index);
break;
+ case LCD_POWER_TYPE_EXTERN:
+ if (pconf->extern_index == 0xff)
+ pconf->extern_index = index;
+ break;
default:
break;
}
-obj-$(CONFIG_AMLOGIC_LCD_EXTERN) += lcd_extern.o ext_default.o mipi_default.o
+obj-$(CONFIG_AMLOGIC_LCD_EXTERN) += lcd_extern.o ext_default.o mipi_default.o ext_i2c_dev.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q) += i2c_T5800Q.o
-obj-$(CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2) += spi_LD070WS2.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439) += i2c_DLPC3439.o
+obj-$(CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2) += spi_LD070WS2.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13) += mipi_KD080D13.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_TV070WSM) += mipi_TV070WSM.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_ST7701) += mipi_ST7701.o
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
-#include <linux/amlogic/i2c-amlogic.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
#include "lcd_extern.h"
-#define LCD_EXTERN_INDEX 0
#define LCD_EXTERN_NAME "ext_default"
-#define LCD_EXTERN_TYPE LCD_EXTERN_I2C
-
-#define LCD_EXTERN_I2C_ADDR (0x1c) /* 7bit address */
-#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */
-#define LCD_EXTERN_I2C_BUS AML_I2C_MASTER_A
-
-#define SPI_GPIO_CS 0 /* index */
-#define SPI_GPIO_CLK 1 /* index */
-#define SPI_GPIO_DATA 2 /* index */
-#define SPI_CLK_FREQ 10000 /* Hz */
-#define SPI_CLK_POL 1
+#define LCD_EXTERN_TYPE LCD_EXTERN_MAX
static struct lcd_extern_config_s *ext_config;
-static struct aml_lcd_extern_i2c_dev_s *i2c_device;
-
-#define LCD_EXTERN_CMD_SIZE 9
-static unsigned char init_on_table[] = {
- 0x00, 0x20, 0x01, 0x02, 0x00, 0x40, 0xFF, 0x00, 0x00,
- 0x00, 0x80, 0x02, 0x00, 0x40, 0x62, 0x51, 0x73, 0x00,
- 0x00, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xC1, 0x05, 0x0F, 0x00, 0x08, 0x70, 0x00, 0x00,
- 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x3D, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xED, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* delay 10ms */
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
-};
-
-static unsigned char init_off_table[] = {
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
-};
-
-static int lcd_extern_i2c_write(struct i2c_client *i2client,
- unsigned char *buff, unsigned int len)
-{
- int ret = 0;
- struct i2c_msg msg[] = {
- {
- .addr = i2client->addr,
- .flags = 0,
- .len = len,
- .buf = buff,
- }
- };
+static struct aml_lcd_extern_i2c_dev_s *i2c0_dev;
+static struct aml_lcd_extern_i2c_dev_s *i2c1_dev;
- ret = i2c_transfer(i2client->adapter, msg, 1);
- if (ret < 0)
- EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
-
- return ret;
-}
static void set_lcd_csb(unsigned int v)
{
static int lcd_extern_reg_read(unsigned char reg, unsigned char *buf)
{
+ struct aml_lcd_extern_i2c_dev_s *i2c_dev;
+ unsigned char tmp;
int ret = 0;
+ tmp = reg;
+ switch (ext_config->type) {
+ case LCD_EXTERN_I2C:
+ if (ext_config->addr_sel)
+ i2c_dev = i2c1_dev;
+ else
+ i2c_dev = i2c0_dev;
+ if (i2c_dev == NULL) {
+ EXTERR("invalid i2c device\n");
+ return -1;
+ }
+ lcd_extern_i2c_read(i2c_dev->client, &tmp, 1);
+ buf[0] = tmp;
+ break;
+ case LCD_EXTERN_SPI:
+ EXTPR("not support\n");
+ break;
+ default:
+ break;
+ }
+
return ret;
}
static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
{
+ struct aml_lcd_extern_i2c_dev_s *i2c_dev;
+ unsigned char tmp[2];
int ret = 0;
+ tmp[0] = reg;
+ tmp[1] = value;
+ switch (ext_config->type) {
+ case LCD_EXTERN_I2C:
+ if (ext_config->addr_sel)
+ i2c_dev = i2c1_dev;
+ else
+ i2c_dev = i2c0_dev;
+ if (i2c_dev == NULL) {
+ EXTERR("invalid i2c device\n");
+ return -1;
+ }
+ lcd_extern_i2c_write(i2c_dev->client, tmp, 2);
+ break;
+ case LCD_EXTERN_SPI:
+ lcd_extern_spi_write(tmp, 2);
+ break;
+ default:
+ break;
+ }
+
return ret;
}
if (init_table[i+4] > 0)
mdelay(init_table[i+4]);
} else if (type == LCD_EXTERN_INIT_CMD) {
- if (i2c_device == NULL) {
- EXTERR("invalid i2c device\n");
+ if (i2c0_dev == NULL) {
+ EXTERR("invalid i2c0 device\n");
return -1;
}
- ret = lcd_extern_i2c_write(
- i2c_device->client,
+ ret = lcd_extern_i2c_write(i2c0_dev->client,
&init_table[i+2], (cmd_size-1));
if (init_table[i+cmd_size+1] > 0)
mdelay(init_table[i+cmd_size+1]);
} else if (type == LCD_EXTERN_INIT_CMD2) {
- EXTPR("%s not support cmd2\n", __func__);
+ if (i2c1_dev == NULL) {
+ EXTERR("invalid i2c1 device\n");
+ return -1;
+ }
+ ret = lcd_extern_i2c_write(i2c1_dev->client,
+ &init_table[i+2], (cmd_size-1));
+ if (init_table[i+cmd_size+1] > 0)
+ mdelay(init_table[i+cmd_size+1]);
} else {
EXTERR("%s(%d: %s): type %d invalid\n",
__func__, ext_config->index,
init_table[i+2]);
}
} else if (type == LCD_EXTERN_INIT_CMD) {
- if (i2c_device == NULL) {
- EXTERR("invalid i2c device\n");
+ if (i2c0_dev == NULL) {
+ EXTERR("invalid i2c0 device\n");
return -1;
}
- ret = lcd_extern_i2c_write(
- i2c_device->client,
+ ret = lcd_extern_i2c_write(i2c0_dev->client,
&init_table[i+1], (cmd_size-2));
} else if (type == LCD_EXTERN_INIT_CMD2) {
- EXTPR("%s not support cmd2\n", __func__);
+ if (i2c1_dev == NULL) {
+ EXTERR("invalid i2c1 device\n");
+ return -1;
+ }
+ ret = lcd_extern_i2c_write(i2c1_dev->client,
+ &init_table[i+1], (cmd_size-2));
} else {
EXTERR("%s(%d: %s): type %d invalid\n",
__func__, ext_config->index,
return ret;
}
-static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_on(void)
{
int ret;
- lcd_extern_pinmux_set(ext_drv, 1);
+ lcd_extern_pinmux_set(1);
ret = lcd_extern_power_ctrl(1);
return ret;
}
-static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_off(void)
{
int ret;
- lcd_extern_pinmux_set(ext_drv, 0);
ret = lcd_extern_power_ctrl(0);
+ lcd_extern_pinmux_set(0);
return ret;
}
return -1;
}
- if (ext_drv->config.type == LCD_EXTERN_MAX) { /* default for no dts */
- ext_drv->config.index = LCD_EXTERN_INDEX;
- ext_drv->config.type = LCD_EXTERN_TYPE;
- strcpy(ext_drv->config.name, LCD_EXTERN_NAME);
- ext_drv->config.cmd_size = LCD_EXTERN_CMD_SIZE;
- switch (ext_drv->config.type) {
- case LCD_EXTERN_I2C:
- ext_drv->config.i2c_addr = LCD_EXTERN_I2C_ADDR;
- ext_drv->config.i2c_addr2 = LCD_EXTERN_I2C_ADDR2;
- ext_drv->config.i2c_bus = LCD_EXTERN_I2C_BUS;
- break;
- case LCD_EXTERN_SPI:
- ext_drv->config.spi_gpio_cs = SPI_GPIO_CS;
- ext_drv->config.spi_gpio_clk = SPI_GPIO_CLK;
- ext_drv->config.spi_gpio_data = SPI_GPIO_DATA;
- ext_drv->config.spi_clk_freq = SPI_CLK_FREQ;
- ext_drv->config.spi_clk_pol = SPI_CLK_POL;
- break;
- default:
- break;
- }
- }
- if (ext_drv->config.table_init_loaded == 0) {
- ext_drv->config.table_init_on = init_on_table;
- ext_drv->config.table_init_off = init_off_table;
- }
- if (ext_drv->config.type == LCD_EXTERN_SPI) {
- ext_drv->config.spi_delay_us =
- 1000000 / ext_drv->config.spi_clk_freq;
+ if (ext_drv->config->type == LCD_EXTERN_SPI) {
+ ext_drv->config->spi_delay_us =
+ 1000000 / ext_drv->config->spi_clk_freq;
}
ext_drv->reg_read = lcd_extern_reg_read;
{
int ret = 0;
- ext_config = &ext_drv->config;
+ ext_config = ext_drv->config;
- switch (ext_drv->config.type) {
+ switch (ext_config->type) {
case LCD_EXTERN_I2C:
- if (i2c_device == NULL) {
- EXTERR("invalid i2c device\n");
- return -1;
+ if (ext_config->i2c_addr < LCD_EXTERN_I2C_ADDR_INVALID) {
+ i2c0_dev = lcd_extern_get_i2c_device(
+ ext_config->i2c_addr);
+ if (i2c0_dev == NULL) {
+ EXTERR("invalid i2c0 device\n");
+ return -1;
+ }
+ EXTPR("get i2c0 device: %s, addr 0x%02x OK\n",
+ i2c0_dev->name, i2c0_dev->client->addr);
}
- if (ext_drv->config.i2c_addr != i2c_device->client->addr) {
- EXTERR("invalid i2c addr\n");
- return -1;
+ if (ext_config->i2c_addr2 < LCD_EXTERN_I2C_ADDR_INVALID) {
+ i2c1_dev = lcd_extern_get_i2c_device(
+ ext_config->i2c_addr2);
+ if (i2c1_dev == NULL) {
+ EXTERR("invalid i2c1 device\n");
+ i2c0_dev = NULL;
+ return -1;
+ }
+ EXTPR("get i2c1 device: %s, addr 0x%02x OK\n",
+ i2c1_dev->name, i2c1_dev->client->addr);
}
break;
case LCD_EXTERN_SPI:
return ret;
}
-static int lcd_extern_i2c_config_from_dts(struct device *dev,
- struct aml_lcd_extern_i2c_dev_s *i2c_device)
+int aml_lcd_extern_default_remove(void)
{
- int ret;
- struct device_node *np = dev->of_node;
- const char *str;
-
- ret = of_property_read_string(np, "dev_name", &str);
- if (ret) {
- EXTERR("failed to get dev_i2c_name\n");
- str = "lcd_extern_i2c_default";
- }
- strcpy(i2c_device->name, str);
+ i2c0_dev = NULL;
+ i2c1_dev = NULL;
+ ext_config = NULL;
return 0;
}
-static int aml_lcd_extern_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- EXTERR("I2C check functionality failed.");
- return -ENODEV;
- }
-
- i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s),
- GFP_KERNEL);
- if (!i2c_device) {
- EXTERR("driver malloc error\n");
- return -ENOMEM;
- }
- i2c_device->client = client;
- lcd_extern_i2c_config_from_dts(&client->dev, i2c_device);
- EXTPR("I2C %s Address: 0x%02x", i2c_device->name,
- i2c_device->client->addr);
-
- return 0;
-}
-
-static int aml_lcd_extern_i2c_remove(struct i2c_client *client)
-{
- kfree(i2c_device);
- i2c_set_clientdata(client, NULL);
-
- return 0;
-}
-
-static const struct i2c_device_id aml_lcd_extern_i2c_id[] = {
- {"ext_default", 0},
- {}
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = {
- {
- .compatible = "amlogic, lcd_ext_default",
- },
- {},
-};
-#endif
-
-static struct i2c_driver aml_lcd_extern_i2c_driver = {
- .probe = aml_lcd_extern_i2c_probe,
- .remove = aml_lcd_extern_i2c_remove,
- .id_table = aml_lcd_extern_i2c_id,
- .driver = {
- .name = "ext_default",
- .owner = THIS_MODULE,
-#ifdef CONFIG_OF
- .of_match_table = aml_lcd_extern_i2c_dt_match,
-#endif
- },
-};
-
-module_i2c_driver(aml_lcd_extern_i2c_driver);
-
-MODULE_AUTHOR("AMLOGIC");
-MODULE_DESCRIPTION("lcd extern driver");
-MODULE_LICENSE("GPL");
-
--- /dev/null
+/*
+ * drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/amlogic/i2c-amlogic.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
+#include "lcd_extern.h"
+
+static struct aml_lcd_extern_i2c_dev_s *i2c_dev[LCD_EXT_I2C_DEV_MAX];
+static unsigned int i2c_dev_cnt;
+
+struct aml_lcd_extern_i2c_dev_s *lcd_extern_get_i2c_device(unsigned char addr)
+{
+ struct aml_lcd_extern_i2c_dev_s *i2c_device = NULL;
+ int i;
+
+ /*pr_info("%s: addr=0x%02x\n", __func__, addr);*/
+ for (i = 0; i < i2c_dev_cnt; i++) {
+ if (i2c_dev[i] == NULL)
+ break;
+ if (i2c_dev[i]->client->addr == addr) {
+ i2c_device = i2c_dev[i];
+ break;
+ }
+ }
+ return i2c_device;
+}
+
+int lcd_extern_i2c_write(struct i2c_client *i2client,
+ unsigned char *buff, unsigned int len)
+{
+ struct i2c_msg msg;
+ int ret = 0;
+
+ if (i2client == NULL) {
+ EXTERR("i2client is null\n");
+ return -1;
+ }
+
+ msg.addr = i2client->addr;
+ msg.flags = 0;
+ msg.len = len;
+ msg.buf = buff;
+
+ ret = i2c_transfer(i2client->adapter, &msg, 1);
+ if (ret < 0)
+ EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
+
+ return ret;
+}
+
+int lcd_extern_i2c_read(struct i2c_client *i2client,
+ unsigned char *buff, unsigned int len)
+{
+ struct i2c_msg msgs[2];
+ int ret = 0;
+
+ if (i2client == NULL) {
+ EXTERR("i2client is null\n");
+ return -1;
+ }
+
+ msgs[0].addr = i2client->addr;
+ msgs[0].flags = 0;
+ msgs[0].len = 1;
+ msgs[0].buf = buff;
+ msgs[1].addr = i2client->addr;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].len = len;
+ msgs[1].buf = buff;
+
+ ret = i2c_transfer(i2client->adapter, msgs, 2);
+ if (ret < 0) {
+ EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
+ __func__, i2client->addr);
+ }
+
+ return ret;
+}
+
+static int lcd_extern_i2c_config_from_dts(struct device *dev,
+ struct aml_lcd_extern_i2c_dev_s *i2c_device)
+{
+ int ret;
+ struct device_node *np = dev->of_node;
+ const char *str;
+
+ ret = of_property_read_string(np, "dev_name", &str);
+ if (ret) {
+ EXTERR("failed to get dev_i2c_name\n");
+ strcpy(i2c_device->name, "lcd_ext_i2c0");
+ } else {
+ strncpy(i2c_device->name, str, 30);
+ i2c_device->name[29] = '\0';
+ }
+
+ return 0;
+}
+
+static int lcd_extern_i2c_dev_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ if (i2c_dev_cnt >= LCD_EXT_I2C_DEV_MAX) {
+ EXTERR("i2c_dev_cnt reach max\n");
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ EXTERR("i2c0_dev check functionality failed");
+ return -ENODEV;
+ }
+
+ i2c_dev[i2c_dev_cnt] = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s),
+ GFP_KERNEL);
+ if (!i2c_dev[i2c_dev_cnt]) {
+ EXTERR("i2c0_dev %d driver malloc error\n", i2c_dev_cnt);
+ return -ENOMEM;
+ }
+
+ i2c_dev[i2c_dev_cnt]->client = client;
+ lcd_extern_i2c_config_from_dts(&client->dev, i2c_dev[i2c_dev_cnt]);
+ EXTPR("i2c_dev probe: %s address 0x%02x OK",
+ i2c_dev[i2c_dev_cnt]->name,
+ i2c_dev[i2c_dev_cnt]->client->addr);
+
+ i2c_dev_cnt++;
+
+ return 0;
+}
+
+static int lcd_extern_i2c_dev_remove(struct i2c_client *client)
+{
+ int i;
+
+ if (i2c_dev_cnt == 0)
+ return 0;
+
+ for (i = 0; i < i2c_dev_cnt; i++) {
+ kfree(i2c_dev[i]);
+ i2c_dev[i] = NULL;
+ }
+ i2c_dev_cnt = 0;
+
+ return 0;
+}
+
+static const struct i2c_device_id lcd_extern_i2c_dev_id[] = {
+ {"lcd_ext_i2c", 0},
+ {}
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id lcd_extern_i2c_dev_dt_match[] = {
+ {
+ .compatible = "lcd_ext, i2c",
+ },
+ {},
+};
+#endif
+
+static struct i2c_driver lcd_extern_i2c_dev_driver = {
+ .probe = lcd_extern_i2c_dev_probe,
+ .remove = lcd_extern_i2c_dev_remove,
+ .id_table = lcd_extern_i2c_dev_id,
+ .driver = {
+ .name = "lcd_ext_i2c",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = lcd_extern_i2c_dev_dt_match,
+#endif
+ },
+};
+
+static int __init aml_lcd_extern_i2c_dev_init(void)
+{
+ int ret;
+
+ if (lcd_debug_print_flag)
+ EXTPR("%s\n", __func__);
+
+ i2c_dev_cnt = 0;
+
+ ret = i2c_add_driver(&lcd_extern_i2c_dev_driver);
+ if (ret) {
+ EXTERR("i2c0_dev driver register failed\n");
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+static void __exit aml_lcd_extern_i2c_dev_exit(void)
+{
+ i2c_del_driver(&lcd_extern_i2c_dev_driver);
+}
+
+
+module_init(aml_lcd_extern_i2c_dev_init);
+module_exit(aml_lcd_extern_i2c_dev_exit);
+
+MODULE_AUTHOR("AMLOGIC");
+MODULE_DESCRIPTION("lcd extern i2c device driver");
+MODULE_LICENSE("GPL");
+
#define LCD_EXTERN_NAME "i2c_DLPC3439"
+#define LCD_EXTERN_I2C_ADDR (0x1b) /* 7bit address */
+#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */
+#define LCD_EXTERN_I2C_BUS LCD_EXTERN_I2C_BUS_2
+
static struct lcd_extern_config_s *ext_config;
-static struct aml_lcd_extern_i2c_dev_s *i2c_device;
+static struct aml_lcd_extern_i2c_dev_s *i2c_dev;
/* Write: ImageCrop: 1920x1080
*/
static unsigned char data_5[] = {0x07, 0x43};
-static int lcd_extern_i2c_write(struct i2c_client *i2client,
- unsigned char *buff, unsigned int len)
-{
- int ret = 0;
- struct i2c_msg msg[] = {
- {
- .addr = i2client->addr,
- .flags = 0,
- .len = len,
- .buf = buff,
- }
- };
-
- ret = i2c_transfer(i2client->adapter, msg, 1);
- if (ret < 0)
- EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
-
- return ret;
-}
-
-static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_on(void)
{
int ret = 0;
- lcd_extern_pinmux_set(ext_drv, 1);
+ lcd_extern_pinmux_set(1);
- if (i2c_device == NULL) {
+ if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
- lcd_extern_i2c_write(i2c_device->client, data_1, 9);
- lcd_extern_i2c_write(i2c_device->client, data_2, 5);
- lcd_extern_i2c_write(i2c_device->client, data_3, 5);
- lcd_extern_i2c_write(i2c_device->client, data_4, 2);
- lcd_extern_i2c_write(i2c_device->client, data_5, 2);
+ lcd_extern_i2c_write(i2c_dev->client, data_1, 9);
+ lcd_extern_i2c_write(i2c_dev->client, data_2, 5);
+ lcd_extern_i2c_write(i2c_dev->client, data_3, 5);
+ lcd_extern_i2c_write(i2c_dev->client, data_4, 2);
+ lcd_extern_i2c_write(i2c_dev->client, data_5, 2);
EXTPR("%s\n", __func__);
return ret;
}
-static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_off(void)
{
int ret = 0;
- lcd_extern_pinmux_set(ext_drv, 0);
+ lcd_extern_pinmux_set(0);
return ret;
}
{
int ret = 0;
- ext_config = &ext_drv->config;
- if (i2c_device == NULL) {
+ ext_config = ext_drv->config;
+
+ i2c_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr);
+ if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
- if (ext_drv->config.i2c_addr != i2c_device->client->addr) {
- EXTERR("invalid i2c addr\n");
- return -1;
- }
+ EXTPR("get i2c device: %s, addr 0x%02x OK\n",
+ i2c_dev->name, i2c_dev->client->addr);
ret = lcd_extern_driver_update(ext_drv);
return ret;
}
-static int lcd_extern_i2c_config_from_dts(struct device *dev,
- struct aml_lcd_extern_i2c_dev_s *i2c_device)
+int aml_lcd_extern_i2c_DLPC3439_remove(void)
{
- int ret;
- struct device_node *np = dev->of_node;
- const char *str;
-
- ret = of_property_read_string(np, "dev_name", &str);
- if (ret) {
- EXTERR("failed to get dev_i2c_name\n");
- str = "lcd_extern_i2c_DLPC3439";
- }
- strcpy(i2c_device->name, str);
+ i2c_dev = NULL;
+ ext_config = NULL;
return 0;
}
-static int aml_lcd_extern_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- EXTERR("I2C check functionality failed.");
- return -ENODEV;
- }
-
- i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s),
- GFP_KERNEL);
- if (!i2c_device) {
- EXTERR("driver malloc error\n");
- return -ENOMEM;
- }
- i2c_device->client = client;
- lcd_extern_i2c_config_from_dts(&client->dev, i2c_device);
- EXTPR("I2C %s Address: 0x%02x", i2c_device->name,
- i2c_device->client->addr);
-
- return 0;
-}
-
-static int aml_lcd_extern_i2c_remove(struct i2c_client *client)
-{
- kfree(i2c_device);
- i2c_set_clientdata(client, NULL);
-
- return 0;
-}
-
-static const struct i2c_device_id aml_lcd_extern_i2c_id[] = {
- {"i2c_DLPC3439", 0},
- {}
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = {
- {
- .compatible = "amlogic, lcd_i2c_DLPC3439",
- },
- {},
-};
-#endif
-
-static struct i2c_driver aml_lcd_extern_i2c_driver = {
- .probe = aml_lcd_extern_i2c_probe,
- .remove = aml_lcd_extern_i2c_remove,
- .id_table = aml_lcd_extern_i2c_id,
- .driver = {
- .name = "i2c_DLPC3439",
- .owner = THIS_MODULE,
-#ifdef CONFIG_OF
- .of_match_table = aml_lcd_extern_i2c_dt_match,
-#endif
- },
-};
-
-module_i2c_driver(aml_lcd_extern_i2c_driver);
-
-MODULE_AUTHOR("AMLOGIC");
-MODULE_DESCRIPTION("lcd extern driver");
-MODULE_LICENSE("GPL");
-
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
#include "lcd_extern.h"
-#define LCD_EXTERN_NAME "i2c_T5800Q"
+#define LCD_EXTERN_NAME "i2c_T5800Q"
+
+#define LCD_EXTERN_I2C_ADDR (0x1c) /* 7bit address */
+#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */
+#define LCD_EXTERN_I2C_BUS LCD_EXTERN_I2C_BUS_2
static struct lcd_extern_config_s *ext_config;
-static struct aml_lcd_extern_i2c_dev_s *i2c_device;
+static struct aml_lcd_extern_i2c_dev_s *i2c_dev;
#define LCD_EXTERN_CMD_SIZE 9
static unsigned char init_on_table[] = {
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
};
-static int lcd_extern_i2c_write(struct i2c_client *i2client,
- unsigned char *buff, unsigned int len)
-{
- int ret = 0;
- struct i2c_msg msg[] = {
- {
- .addr = i2client->addr,
- .flags = 0,
- .len = len,
- .buf = buff,
- }
- };
-
- ret = i2c_transfer(i2client->adapter, msg, 1);
- if (ret < 0)
- EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
-
- return ret;
-}
-
static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
{
int i = 0, max_len = 0, step = 0;
init_table[i+2]);
}
} else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
- if (i2c_device == NULL) {
+ if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
- ret = lcd_extern_i2c_write(i2c_device->client,
+ ret = lcd_extern_i2c_write(i2c_dev->client,
&init_table[i+1], (cmd_size-2));
} else {
EXTERR("%s(%d: %s): power_type %d is invalid\n",
return ret;
}
-static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_on(void)
{
int ret;
- lcd_extern_pinmux_set(ext_drv, 1);
+ lcd_extern_pinmux_set(1);
ret = lcd_extern_power_ctrl(1);
return ret;
}
-static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_off(void)
{
int ret;
- lcd_extern_pinmux_set(ext_drv, 0);
ret = lcd_extern_power_ctrl(0);
+ lcd_extern_pinmux_set(0);
return ret;
}
return -1;
}
- if (ext_drv->config.table_init_loaded == 0) {
- ext_drv->config.table_init_on = init_on_table;
- ext_drv->config.table_init_off = init_off_table;
+ if (ext_drv->config->table_init_loaded == 0) {
+ ext_drv->config->table_init_on = init_on_table;
+ ext_drv->config->table_init_off = init_off_table;
}
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
{
int ret = 0;
- ext_config = &ext_drv->config;
- if (i2c_device == NULL) {
+ ext_config = ext_drv->config;
+
+ i2c_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr);
+ if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
- if (ext_drv->config.i2c_addr != i2c_device->client->addr) {
- EXTERR("invalid i2c addr\n");
- return -1;
- }
+ EXTPR("get i2c device: %s, addr 0x%02x OK\n",
+ i2c_dev->name, i2c_dev->client->addr);
ret = lcd_extern_driver_update(ext_drv);
EXTPR("%s: %d\n", __func__, ret);
int aml_lcd_extern_i2c_T5800Q_remove(void)
{
- return 0;
-}
-
-static int lcd_extern_i2c_config_from_dts(struct device *dev,
- struct aml_lcd_extern_i2c_dev_s *i2c_device)
-{
- int ret;
- struct device_node *np = dev->of_node;
- const char *str;
-
- ret = of_property_read_string(np, "dev_name", &str);
- if (ret) {
- EXTERR("failed to get dev_i2c_name\n");
- str = "lcd_extern_i2c_T5800Q";
- }
- strcpy(i2c_device->name, str);
-
- return 0;
-}
-
-static int aml_lcd_extern_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- EXTERR("I2C check functionality failed.");
- return -ENODEV;
- }
-
- i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s),
- GFP_KERNEL);
- if (!i2c_device) {
- EXTERR("driver malloc error\n");
- return -ENOMEM;
- }
-
- i2c_device->client = client;
- lcd_extern_i2c_config_from_dts(&client->dev, i2c_device);
- EXTPR("I2C %s Address: 0x%02x", i2c_device->name,
- i2c_device->client->addr);
-
- return 0;
-}
-
-static int aml_lcd_extern_i2c_remove(struct i2c_client *client)
-{
- kfree(i2c_device);
- //i2c_set_clientdata(client, NULL);
+ i2c_dev = NULL;
+ ext_config = NULL;
return 0;
}
-static const struct i2c_device_id aml_lcd_extern_i2c_id[] = {
- {"i2c_T5800Q", 0},
- {}
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = {
- {
- .compatible = "amlogic, lcd_i2c_T5800Q",
- },
- {},
-};
-#endif
-
-static struct i2c_driver aml_lcd_extern_i2c_driver = {
- .probe = aml_lcd_extern_i2c_probe,
- .remove = aml_lcd_extern_i2c_remove,
- .id_table = aml_lcd_extern_i2c_id,
- .driver = {
- .name = "i2c_T5800Q",
- .owner = THIS_MODULE,
-#ifdef CONFIG_OF
- .of_match_table = aml_lcd_extern_i2c_dt_match,
-#endif
- },
-};
-
-static int __init aml_lcd_extern_i2c_init(void)
-{
- int ret;
-
- //if (lcd_debug_print_flag)
- EXTPR("%s\n", __func__);
-
- ret = i2c_add_driver(&aml_lcd_extern_i2c_driver);
- if (ret) {
- EXTERR("driver register failed\n");
- return -ENODEV;
- }
- return ret;
-}
-
-static void __exit aml_lcd_extern_i2c_exit(void)
-{
- i2c_del_driver(&aml_lcd_extern_i2c_driver);
-}
-
-
-module_init(aml_lcd_extern_i2c_init);
-module_exit(aml_lcd_extern_i2c_exit);
-
-//module_i2c_driver(aml_lcd_extern_i2c_driver);
-
-MODULE_AUTHOR("AMLOGIC");
-MODULE_DESCRIPTION("lcd extern driver");
-MODULE_LICENSE("GPL");
-
#include "i2c_anx6345.h"
static struct lcd_extern_config_s *ext_config;
-static struct i2c_client *aml_anx6345_70_client;
-static struct i2c_client *aml_anx6345_72_client;
+static struct aml_lcd_extern_i2c_dev_s *i2c0_dev;
+static struct aml_lcd_extern_i2c_dev_s *i2c1_dev;
-const char *anx_addr_name[2] = {"anx6345_70", "anx6345_72"};
static unsigned int edp_tx_lane = 1;
-#define LCD_EXTERN_NAME "lcd_anx6345"
+#define LCD_EXTERN_NAME "lcd_anx6345"
-static int aml_i2c_write(struct i2c_client *i2client, unsigned char *buff,
- unsigned int len)
-{
- int ret = 0;
- struct i2c_msg msg[] = {
- {
- .addr = i2client->addr,
- .flags = 0,
- .len = len,
- .buf = buff,
- },
- };
-
- ret = i2c_transfer(i2client->adapter, msg, 1);
- if (ret < 0) {
- EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
- __func__, i2client->addr);
- }
-
- return ret;
-}
-
-static int aml_i2c_read(struct i2c_client *i2client, unsigned char *buff,
- unsigned int len)
-{
- int ret = 0;
- struct i2c_msg msgs[] = {
- {
- .addr = i2client->addr,
- .flags = 0,
- .len = 1,
- .buf = buff,
- },
- {
- .addr = i2client->addr,
- .flags = I2C_M_RD,
- .len = len,
- .buf = buff,
- },
- };
-
- ret = i2c_transfer(i2client->adapter, msgs, 2);
- if (ret < 0) {
- EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
- __func__, i2client->addr);
- }
-
- return ret;
-}
-
-#if 0
-static int i2c_reg_read(unsigned char reg, unsigned char *buf)
-{
- int ret = 0;
-
- return ret;
-}
-
-static int i2c_reg_write(unsigned char reg, unsigned char value)
-{
- int ret = 0;
-
- return ret;
-}
-#endif
+#define LCD_EXTERN_I2C_ADDR (0x38) /* 7bit address */
+#define LCD_EXTERN_I2C_ADDR2 (0x39) /* 7bit address */
+#define LCD_EXTERN_I2C_BUS LCD_EXTERN_I2C_BUS_2
static int SP_TX_Write_Reg(unsigned char addr, unsigned char reg,
unsigned char data)
buff[0] = reg;
buff[1] = data;
if (addr == 0x70)
- client = aml_anx6345_70_client;
+ client = i2c0_dev->client;
else if (addr == 0x72)
- client = aml_anx6345_72_client;
+ client = i2c1_dev->client;
if (client == NULL) {
EXTERR("%s: invalid i2c client\n", __func__);
return -1;
}
- ret = aml_i2c_write(client, buff, 1);
+ ret = lcd_extern_i2c_write(client, buff, 1);
return ret;
}
*data = reg;
if (addr == 0x70)
- client = aml_anx6345_70_client;
+ client = i2c0_dev->client;
else if (addr == 0x72)
- client = aml_anx6345_72_client;
+ client = i2c1_dev->client;
if (client == NULL) {
EXTERR("%s: invalid i2c client\n", __func__);
return -1;
}
- ret = aml_i2c_read(client, data, 1);
+ ret = lcd_extern_i2c_read(client, data, 1);
return ret;
}
return 0; /* aux ok */
}
-static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_on(void)
{
unsigned int lane_num;
unsigned int link_rate;
unsigned int count = 0;
unsigned int count1 = 0;
- lcd_extern_pinmux_set(ext_drv, 1);
+ lcd_extern_pinmux_set(1);
+
lane_num = edp_tx_lane; /* 1 lane */
link_rate = VAL_EDP_TX_LINK_BW_SET_270; /* 2.7G */
bits = 0; /* 0x00: 6bit; 0x10:8bit */
return 0;
}
-static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_off(void)
{
int ret = 0;
- lcd_extern_pinmux_set(ext_drv, 0);
+ lcd_extern_pinmux_set(0);
return ret;
}
return ret;
}
-static int aml_anx6345_70_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
- EXTERR("%s: functionality check failed\n", __func__);
- else
- aml_anx6345_70_client = client;
-
- EXTPR("%s OK\n", __func__);
- return 0;
-}
-
-static int aml_anx6345_72_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
- EXTERR("%s: functionality check failed\n", __func__);
- else
- aml_anx6345_72_client = client;
-
- EXTPR("%s OK\n", __func__);
- return 0;
-}
-
-static int aml_anx6345_70_remove(struct i2c_client *client)
-{
- return 0;
-}
-static int aml_anx6345_72_remove(struct i2c_client *client)
-{
- return 0;
-}
-
-static const struct i2c_device_id aml_anx6345_70_id[] = {
- {"anx6345_70", 0},
- { }
-};
-static const struct i2c_device_id aml_anx6345_72_id[] = {
- {"anx6345_72", 0},
- { }
-};
-
-/* MODULE_DEVICE_TABLE(i2c, aml_tc101_id); */
-
-static struct i2c_driver aml_anx6345_70_driver = {
- .probe = aml_anx6345_70_probe,
- .remove = aml_anx6345_70_remove,
- .id_table = aml_anx6345_70_id,
- .driver = {
- .name = "anx6345_70",
- .owner = THIS_MODULE,
- },
-};
-
-static struct i2c_driver aml_anx6345_72_driver = {
- .probe = aml_anx6345_72_probe,
- .remove = aml_anx6345_72_remove,
- .id_table = aml_anx6345_72_id,
- .driver = {
- .name = "anx6345_72",
- .owner = THIS_MODULE,
- },
-};
-
int aml_lcd_extern_i2c_anx6345_probe(struct aml_lcd_extern_driver_s *ext_drv)
{
- struct i2c_board_info i2c_info[2];
- struct i2c_adapter *adapter;
- struct i2c_client *i2c_client;
- int i = 0;
int ret = 0;
- ext_config = &ext_drv->config;
- if (ext_config->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) {
- EXTERR("invalid i2c bus\n");
- return -1;
- }
- for (i = 0; i < 2; i++)
- memset(&i2c_info[i], 0, sizeof(i2c_info[i]));
+ ext_config = ext_drv->config;
- adapter = i2c_get_adapter(ext_config->i2c_bus);
- if (!adapter) {
- EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name);
+ i2c0_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr);
+ if (i2c0_dev == NULL) {
+ EXTERR("invalid i2c0 device\n");
return -1;
}
+ EXTPR("get i2c0 device: %s, addr 0x%02x OK\n",
+ i2c0_dev->name, i2c0_dev->client->addr);
- i2c_info[0].addr = 0x38; /* 0x70 >> 1; */
- i2c_info[1].addr = 0x39; /* 0x72 >> 1; */
- for (i = 0; i < 2; i++) {
- strncpy(i2c_info[i].type, anx_addr_name[i], I2C_NAME_SIZE);
- /* i2c_info[i].platform_data = &ext_drv->config; */
- i2c_info[i].flags = 0;
- if (i2c_info[i].addr > 0x7f) {
- EXTERR("%s invalid i2c address: 0x%02x\n",
- ext_drv->config.name, i2c_info[i].addr);
- return -1;
- }
- i2c_client = i2c_new_device(adapter, &i2c_info[i]);
- if (!i2c_client) {
- EXTERR("%s failed to new i2c device\n",
- ext_drv->config.name);
- } else {
- if (lcd_debug_print_flag) {
- EXTPR("%s new i2c device succeed\n",
- ext_drv->config.name);
- }
- }
- }
-
- if (!aml_anx6345_70_client) {
- ret = i2c_add_driver(&aml_anx6345_70_driver);
- if (ret) {
- EXTERR("%s add i2c_driver failed\n",
- ext_drv->config.name);
- return -1;
- }
- }
- if (!aml_anx6345_72_client) {
- ret = i2c_add_driver(&aml_anx6345_72_driver);
- if (ret) {
- EXTERR("%s add i2c_driver failed\n",
- ext_drv->config.name);
- return -1;
- }
+ i2c1_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr2);
+ if (i2c1_dev == NULL) {
+ EXTERR("invalid i2c1 device\n");
+ i2c0_dev = NULL;
+ return -1;
}
+ EXTPR("get i2c1 device: %s, addr 0x%02x OK\n",
+ i2c1_dev->name, i2c1_dev->client->addr);
ret = lcd_extern_driver_update(ext_drv);
return ret;
}
+int aml_lcd_extern_i2c_anx6345_remove(void)
+{
+ i2c0_dev = NULL;
+ i2c1_dev = NULL;
+ ext_config = NULL;
+
+ return 0;
+}
+
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
#include "lcd_extern.h"
-#define LCD_EXTERN_NAME "i2c_tc101"
+#define LCD_EXTERN_NAME "i2c_tc101"
+
+#define LCD_EXTERN_I2C_ADDR (0x7e) /* 7bit address */
+#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */
+#define LCD_EXTERN_I2C_BUS LCD_EXTERN_I2C_BUS_2
static struct lcd_extern_config_s *ext_config;
-static struct aml_lcd_extern_i2c_dev_s *i2c_device;
+static struct aml_lcd_extern_i2c_dev_s *i2c0_dev;
+static struct aml_lcd_extern_i2c_dev_s *i2c1_dev;
static unsigned char init_on_table[][3] = {
/* {0xff, 0xff, 20},//delay mark(20ms) */
return ret;
}
-static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_on(void)
{
unsigned char tData[4];
int i = 0, ending_flag = 0;
int ret = 0;
- lcd_extern_pinmux_set(ext_drv, 1);
+ lcd_extern_pinmux_set(1);
- if (i2c_device == NULL) {
+ if (i2c0_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
tData[0] = init_on_table[i][0];
tData[1] = init_on_table[i][1];
tData[2] = init_on_table[i][2];
- lcd_extern_i2c_write(i2c_device->client, tData, 3);
+ lcd_extern_i2c_write(i2c0_dev->client, tData, 3);
}
i++;
}
return ret;
}
-static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv)
+static int lcd_extern_power_off(void)
{
int ret = 0;
- lcd_extern_pinmux_set(ext_drv, 0);
+ lcd_extern_pinmux_set(0);
return ret;
}
{
int ret = 0;
- ext_config = &ext_drv->config;
- if (i2c_device == NULL) {
- EXTERR("invalid i2c device\n");
+ ext_config = ext_drv->config;
+
+ i2c0_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr);
+ if (i2c0_dev == NULL) {
+ EXTERR("invalid i2c0 device\n");
return -1;
}
- if (ext_drv->config.i2c_addr != i2c_device->client->addr) {
- EXTERR("invalid i2c addr\n");
+ EXTPR("get i2c0 device: %s, addr 0x%02x OK\n",
+ i2c0_dev->name, i2c0_dev->client->addr);
+
+ i2c1_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr2);
+ if (i2c1_dev == NULL) {
+ EXTERR("invalid i2c1 device\n");
+ i2c0_dev = NULL;
return -1;
}
+ EXTPR("get i2c1 device: %s, addr 0x%02x OK\n",
+ i2c1_dev->name, i2c1_dev->client->addr);
ret = lcd_extern_driver_update(ext_drv);
return ret;
}
-static int lcd_extern_i2c_config_from_dts(struct device *dev,
- struct aml_lcd_extern_i2c_dev_s *i2c_device)
-{
- int ret;
- struct device_node *np = dev->of_node;
- const char *str;
-
- ret = of_property_read_string(np, "dev_name", &str);
- if (ret) {
- EXTERR("failed to get dev_i2c_name\n");
- str = "lcd_extern_i2c_tc101";
- }
- strcpy(i2c_device->name, str);
-
- return 0;
-}
-
-static int aml_lcd_extern_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- EXTERR("I2C check functionality failed.");
- return -ENODEV;
- }
-
- i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s),
- GFP_KERNEL);
- if (!i2c_device) {
- EXTERR("driver malloc error\n");
- return -ENOMEM;
- }
- i2c_device->client = client;
- lcd_extern_i2c_config_from_dts(&client->dev, i2c_device);
- EXTPR("I2C %s Address: 0x%02x", i2c_device->name,
- i2c_device->client->addr);
-
- return 0;
-}
-
-static int aml_lcd_extern_i2c_remove(struct i2c_client *client)
+int aml_lcd_extern_i2c_tc101_remove(void)
{
- kfree(i2c_device);
- i2c_set_clientdata(client, NULL);
+ i2c0_dev = NULL;
+ i2c1_dev = NULL;
+ ext_config = NULL;
return 0;
}
-
-static const struct i2c_device_id aml_lcd_extern_i2c_id[] = {
- {"i2c_tc101", 0},
- {}
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = {
- {
- .compatible = "amlogic, lcd_i2c_tc101",
- },
- {},
-};
-#endif
-
-static struct i2c_driver aml_lcd_extern_i2c_driver = {
- .probe = aml_lcd_extern_i2c_probe,
- .remove = aml_lcd_extern_i2c_remove,
- .id_table = aml_lcd_extern_i2c_id,
- .driver = {
- .name = "i2c_tc101",
- .owner = THIS_MODULE,
-#ifdef CONFIG_OF
- .of_match_table = aml_lcd_extern_i2c_dt_match,
-#endif
- },
-};
-
-module_i2c_driver(aml_lcd_extern_i2c_driver);
-
-MODULE_AUTHOR("AMLOGIC");
-MODULE_DESCRIPTION("lcd extern driver");
-MODULE_LICENSE("GPL");
-
#include <linux/of.h>
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
#include <linux/amlogic/media/vout/lcd/lcd_unifykey.h>
+#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
#include "lcd_extern.h"
static struct device *lcd_extern_dev;
-static int lcd_ext_driver_num;
-static struct aml_lcd_extern_driver_s *lcd_ext_driver[LCD_EXT_DRIVER_MAX];
+static struct aml_lcd_extern_driver_s *lcd_ext_driver;
static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf);
-static unsigned int lcd_ext_key_valid;
static unsigned char lcd_ext_config_load;
-static unsigned char lcd_ext_i2c_bus = LCD_EXTERN_I2C_BUS_INVALID;
-static unsigned char lcd_ext_i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX;
-static unsigned char lcd_ext_i2c_sck_gpio_off = 2;
-static unsigned char lcd_ext_i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX;
-static unsigned char lcd_ext_i2c_sda_gpio_off = 2;
struct lcd_ext_gpio_s {
char name[15];
{.probe_flag = 0, .register_flag = 0,},
};
+static struct lcd_extern_config_s lcd_extern_config = {
+ .index = LCD_EXTERN_INDEX_INVALID,
+ .name = "invalid",
+ .type = LCD_EXTERN_MAX,
+ .status = 0,
+ .pinmux_valid = 0,
+ .key_valid = 0,
+ .addr_sel = 0,
+
+ .i2c_addr = LCD_EXTERN_I2C_ADDR_INVALID,
+ .i2c_addr2 = LCD_EXTERN_I2C_ADDR_INVALID,
+ .i2c_bus = LCD_EXTERN_I2C_BUS_INVALID,
+ .i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX,
+ .i2c_sck_gpio_off = 2,
+ .i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX,
+ .i2c_sda_gpio_off = 2,
+
+ .spi_gpio_cs = LCD_EXTERN_GPIO_NUM_MAX,
+ .spi_gpio_clk = LCD_EXTERN_GPIO_NUM_MAX,
+ .spi_gpio_data = LCD_EXTERN_GPIO_NUM_MAX,
+ .spi_clk_freq = 0,
+ .spi_delay_us = 0,
+ .spi_clk_pol = 1,
+
+ .cmd_size = 0,
+ .table_init_on = NULL,
+ .table_init_off = NULL,
+ .table_init_loaded = 0, /* internal use */
+ .table_init_on_cnt = 0, /* internal use */
+};
+
struct aml_lcd_extern_driver_s *aml_lcd_extern_get_driver(int index)
{
- int i;
- struct aml_lcd_extern_driver_s *ext_driver = NULL;
-
if (index >= LCD_EXTERN_INDEX_INVALID) {
EXTERR("invalid driver index: %d\n", index);
return NULL;
}
- for (i = 0; i < lcd_ext_driver_num; i++) {
- if (lcd_ext_driver[i]->config.index == index) {
- ext_driver = lcd_ext_driver[i];
- break;
- }
- }
- if (ext_driver == NULL)
- EXTERR("invalid driver index: %d\n", index);
- return ext_driver;
-}
-
-#if 0
-static struct aml_lcd_extern_driver_s
- *aml_lcd_extern_get_driver_by_name(char *name)
-{
- int i;
- struct aml_lcd_extern_driver_s *ext_driver = NULL;
+ if (lcd_ext_driver->config->index == index)
+ return lcd_ext_driver;
- for (i = 0; i < lcd_ext_driver_num; i++) {
- if (strcmp(lcd_ext_driver[i]->config.name, name) == 0) {
- ext_driver = lcd_ext_driver[i];
- break;
- }
- }
- if (ext_driver == NULL)
- EXTERR("invalid driver name: %s\n", name);
- return ext_driver;
+ EXTERR("invalid driver index: %d\n", index);
+ return NULL;
}
-#endif
#ifdef CONFIG_OF
void lcd_extern_gpio_probe(unsigned char index)
return gpiod_get_value(ext_gpio->gpio);
}
-void lcd_extern_pinmux_set(struct aml_lcd_extern_driver_s *ext_drv, int status)
+void lcd_extern_pinmux_set(int status)
{
- struct lcd_ext_gpio_s *ext_gpio_sck;
- struct lcd_ext_gpio_s *ext_gpio_sda;
+ /* kernel4.9 can't release pins */
+ if (lcd_ext_driver == NULL)
+ return;
- ext_gpio_sck = &lcd_extern_gpio[ext_drv->config.i2c_sck_gpio];
- ext_gpio_sda = &lcd_extern_gpio[ext_drv->config.i2c_sda_gpio];
+ if (lcd_ext_driver->config->pinmux_valid == 0) {
+ if (lcd_debug_print_flag) {
+ EXTPR("%s: pinmux_valid %d, bypass\n",
+ __func__, lcd_ext_driver->config->pinmux_valid);
+ }
+ return;
+ }
if (lcd_debug_print_flag)
EXTPR("%s: %d\n", __func__, status);
if (status) {
/* release gpio */
- if (ext_drv->pinmux_flag) {
+ if (lcd_ext_driver->pinmux_flag) {
EXTPR("drv_index %d pinmux is already selected\n",
- ext_drv->config.index);
+ lcd_ext_driver->config->index);
return;
}
- if (ext_drv->config.type == LCD_EXTERN_I2C) {
- if (ext_drv->config.i2c_sck_gpio <
- LCD_EXTERN_GPIO_NUM_MAX)
- lcd_extern_gpio_unregister(
- ext_drv->config.i2c_sck_gpio);
- if (ext_drv->config.i2c_sda_gpio <
- LCD_EXTERN_GPIO_NUM_MAX)
- lcd_extern_gpio_unregister(
- ext_drv->config.i2c_sda_gpio);
- }
+
/* request pinmux */
- ext_drv->pin = devm_pinctrl_get_select(lcd_extern_dev,
+ lcd_ext_driver->pin = devm_pinctrl_get_select(lcd_extern_dev,
"extern_pins");
- if (IS_ERR(ext_drv->pin)) {
+ if (IS_ERR(lcd_ext_driver->pin)) {
EXTERR("set drv_index %d pinmux error\n",
- ext_drv->config.index);
+ lcd_ext_driver->config->index);
} else {
if (lcd_debug_print_flag) {
EXTPR("set drv_index %d pinmux ok\n",
- ext_drv->config.index);
- }
- }
- ext_drv->pinmux_flag = 1;
- } else {
- if (ext_drv->pinmux_flag) {
- if (lcd_debug_print_flag)
- EXTPR("release pinmux: %p\n", ext_drv->pin);
- /* release pinmux */
- if (!IS_ERR(ext_drv->pin))
- devm_pinctrl_put(ext_drv->pin);
- ext_drv->pinmux_flag = 0;
- }
- /* request gpio & set gpio */
- if (ext_drv->config.type == LCD_EXTERN_I2C) {
- if (ext_drv->config.i2c_sck_gpio <
- LCD_EXTERN_GPIO_NUM_MAX) {
- lcd_extern_gpio_set(
- ext_drv->config.i2c_sck_gpio,
- ext_drv->config.i2c_sck_gpio_off);
- }
- if (ext_drv->config.i2c_sda_gpio <
- LCD_EXTERN_GPIO_NUM_MAX) {
- lcd_extern_gpio_set(
- ext_drv->config.i2c_sda_gpio,
- ext_drv->config.i2c_sda_gpio_off);
+ lcd_ext_driver->config->index);
}
}
+ lcd_ext_driver->pinmux_flag = 1;
}
}
unsigned char i2c_bus;
if (strncmp(str, "i2c_bus_ao", 10) == 0)
- i2c_bus = AML_I2C_MASTER_AO;
+ i2c_bus = LCD_EXTERN_I2C_BUS_4;
else if (strncmp(str, "i2c_bus_a", 9) == 0)
- i2c_bus = AML_I2C_MASTER_A;
+ i2c_bus = LCD_EXTERN_I2C_BUS_0;
else if (strncmp(str, "i2c_bus_b", 9) == 0)
- i2c_bus = AML_I2C_MASTER_B;
+ i2c_bus = LCD_EXTERN_I2C_BUS_1;
else if (strncmp(str, "i2c_bus_c", 9) == 0)
- i2c_bus = AML_I2C_MASTER_C;
+ i2c_bus = LCD_EXTERN_I2C_BUS_2;
else if (strncmp(str, "i2c_bus_d", 9) == 0)
- i2c_bus = AML_I2C_MASTER_D;
+ i2c_bus = LCD_EXTERN_I2C_BUS_3;
+ else if (strncmp(str, "i2c_bus_0", 9) == 0)
+ i2c_bus = LCD_EXTERN_I2C_BUS_0;
+ else if (strncmp(str, "i2c_bus_1", 9) == 0)
+ i2c_bus = LCD_EXTERN_I2C_BUS_1;
+ else if (strncmp(str, "i2c_bus_2", 9) == 0)
+ i2c_bus = LCD_EXTERN_I2C_BUS_2;
+ else if (strncmp(str, "i2c_bus_3", 9) == 0)
+ i2c_bus = LCD_EXTERN_I2C_BUS_3;
+ else if (strncmp(str, "i2c_bus_4", 9) == 0)
+ i2c_bus = LCD_EXTERN_I2C_BUS_4;
else {
i2c_bus = LCD_EXTERN_I2C_BUS_INVALID;
EXTERR("invalid i2c_bus: %s\n", str);
ret = of_property_read_string(of_node, "extern_name", &str);
if (ret) {
- str = "none";
EXTERR("get extern_name failed\n");
+ strncpy(extconf->name, "none", LCD_EXTERN_NAME_LEN_MAX);
+ } else {
+ strncpy(extconf->name, str, LCD_EXTERN_NAME_LEN_MAX);
}
- strncpy(extconf->name, str, LCD_EXTERN_NAME_LEN_MAX);
/* ensure string ending */
extconf->name[LCD_EXTERN_NAME_LEN_MAX-1] = '\0';
EXTPR("load config: %s[%d]\n", extconf->name, extconf->index);
switch (extconf->type) {
case LCD_EXTERN_I2C:
- if (lcd_ext_i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) {
- ret = of_property_read_string(of_node, "i2c_bus", &str);
- if (ret) {
- EXTERR("get %s i2c_bus failed, exit\n",
- extconf->name);
- extconf->i2c_bus = LCD_EXTERN_I2C_BUS_INVALID;
- return -1;
- }
- extconf->i2c_bus = lcd_extern_get_i2c_bus_str(str);
- } else
- extconf->i2c_bus = lcd_ext_i2c_bus;
+ if (extconf->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID)
+ EXTERR("get %s i2c_bus failed\n", extconf->name);
if (lcd_debug_print_flag) {
EXTPR("%s i2c_bus=%d\n",
extconf->name, extconf->i2c_bus);
extconf->name, extconf->i2c_addr2);
}
- extconf->i2c_sck_gpio = lcd_ext_i2c_sck_gpio;
- extconf->i2c_sck_gpio_off = lcd_ext_i2c_sck_gpio_off;
- extconf->i2c_sda_gpio = lcd_ext_i2c_sda_gpio;
- extconf->i2c_sda_gpio_off = lcd_ext_i2c_sda_gpio_off;
- if ((lcd_ext_i2c_sck_gpio < LCD_EXTERN_GPIO_NUM_MAX) ||
- (lcd_ext_i2c_sda_gpio < LCD_EXTERN_GPIO_NUM_MAX)) {
- EXTPR("find i2c_gpio_off config\n");
- lcd_extern_gpio_probe(extconf->i2c_sck_gpio);
- lcd_extern_gpio_probe(extconf->i2c_sda_gpio);
- }
-
ret = of_property_read_u32(of_node, "cmd_size", &val);
if (ret) {
if (extconf->index == 0) {
}
#endif
-
-static unsigned char lcd_extern_get_i2c_bus_unifykey(unsigned char val)
-{
- if (lcd_ext_i2c_bus == LCD_EXTERN_I2C_BUS_INVALID)
- EXTERR("get i2c_bus failed\n");
- if (lcd_debug_print_flag)
- EXTPR("i2c_bus=%d\n", lcd_ext_i2c_bus);
-
- return lcd_ext_i2c_bus;
-}
-
static int lcd_extern_init_table_dynamic_size_load_unifykey(
struct lcd_extern_config_s *extconf, unsigned char *p,
int key_len, int len, int flag)
case LCD_EXTERN_I2C:
extconf->i2c_addr = *(p + LCD_UKEY_EXT_TYPE_VAL_0);
extconf->i2c_addr2 = *(p + LCD_UKEY_EXT_TYPE_VAL_1);
- extconf->i2c_bus = lcd_extern_get_i2c_bus_unifykey(
- *(p + LCD_UKEY_EXT_TYPE_VAL_2));
- extconf->i2c_sck_gpio = lcd_ext_i2c_sck_gpio;
- extconf->i2c_sck_gpio_off = lcd_ext_i2c_sck_gpio_off;
- extconf->i2c_sda_gpio = lcd_ext_i2c_sda_gpio;
- extconf->i2c_sda_gpio_off = lcd_ext_i2c_sda_gpio_off;
- if ((lcd_ext_i2c_sck_gpio < LCD_EXTERN_GPIO_NUM_MAX) ||
- (lcd_ext_i2c_sda_gpio < LCD_EXTERN_GPIO_NUM_MAX)) {
- EXTPR("find i2c_gpio_off config\n");
- lcd_extern_gpio_probe(extconf->i2c_sck_gpio);
- lcd_extern_gpio_probe(extconf->i2c_sda_gpio);
- }
+ /*extconf->i2c_bus = *(p + LCD_UKEY_EXT_TYPE_VAL_2);*/
+ if (extconf->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID)
+ EXTERR("get %s i2c_bus failed\n", extconf->name);
+
extconf->cmd_size = *(p + LCD_UKEY_EXT_TYPE_VAL_3);
/* init */
static int lcd_extern_get_config(void)
{
struct device_node *child;
- struct lcd_extern_config_s extconf;
- unsigned char *lcd_ext_init_on_table;
- unsigned char *lcd_ext_init_off_table;
+ unsigned int ext_index = LCD_EXTERN_INDEX_INVALID;
+ char ext_propname[20];
unsigned int extern_para[5];
const char *str;
int load_id = 0;
return -1;
}
- lcd_ext_init_on_table =
- kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX,
+ lcd_extern_config.table_init_on =
+ kzalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX,
GFP_KERNEL);
- if (lcd_ext_init_on_table == NULL) {
+ if (lcd_extern_config.table_init_on == NULL) {
EXTERR("failed to alloc default init table\n");
return -1;
}
- lcd_ext_init_off_table =
- kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX,
+ lcd_extern_config.table_init_off =
+ kzalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX,
GFP_KERNEL);
- if (lcd_ext_init_off_table == NULL) {
+ if (lcd_extern_config.table_init_off == NULL) {
EXTERR("failed to alloc default init table\n");
- kfree(lcd_ext_init_on_table);
+ kfree(lcd_extern_config.table_init_on);
return -1;
}
- lcd_ext_init_on_table[0] = LCD_EXTERN_INIT_END;
- lcd_ext_init_off_table[0] = LCD_EXTERN_INIT_END;
+ lcd_extern_config.table_init_on[0] = LCD_EXTERN_INIT_END;
+ lcd_extern_config.table_init_off[0] = LCD_EXTERN_INIT_END;
- ret = of_property_read_string(lcd_extern_dev->of_node,
- "i2c_bus", &str);
+ ret = of_property_read_string(lcd_extern_dev->of_node, "i2c_bus", &str);
if (ret)
- lcd_ext_i2c_bus = LCD_EXTERN_I2C_BUS_INVALID;
+ lcd_extern_config.i2c_bus = LCD_EXTERN_I2C_BUS_INVALID;
else
- lcd_ext_i2c_bus = lcd_extern_get_i2c_bus_str(str);
- if (lcd_debug_print_flag)
- EXTPR("i2c_bus=%s[%d]\n", str, lcd_ext_i2c_bus);
+ lcd_extern_config.i2c_bus = lcd_extern_get_i2c_bus_str(str);
ret = of_property_read_u32_array(lcd_extern_dev->of_node,
- "i2c_gpio_off", &extern_para[0], 4);
+ "i2c_gpio_off", &extern_para[0], 4);
if (ret) {
- lcd_ext_i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX;
- lcd_ext_i2c_sck_gpio_off = 2;
- lcd_ext_i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX;
- lcd_ext_i2c_sda_gpio_off = 2;
+ lcd_extern_config.i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX;
+ lcd_extern_config.i2c_sck_gpio_off = 2;
+ lcd_extern_config.i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX;
+ lcd_extern_config.i2c_sda_gpio_off = 2;
} else {
- lcd_ext_i2c_sck_gpio = extern_para[0];
- lcd_ext_i2c_sck_gpio_off = extern_para[1];
- lcd_ext_i2c_sda_gpio = extern_para[2];
- lcd_ext_i2c_sda_gpio_off = extern_para[3];
+ lcd_extern_config.i2c_sck_gpio = (unsigned char)extern_para[0];
+ lcd_extern_config.i2c_sck_gpio_off =
+ (unsigned char) extern_para[1];
+ lcd_extern_config.i2c_sda_gpio = (unsigned char)extern_para[2];
+ lcd_extern_config.i2c_sda_gpio_off =
+ (unsigned char)extern_para[3];
}
+ ret = of_property_read_string(lcd_extern_dev->of_node,
+ "pinctrl-names", &str);
+ if (ret)
+ lcd_extern_config.pinmux_valid = 0;
+ else
+ lcd_extern_config.pinmux_valid = 1;
+
ret = of_property_read_u32(lcd_extern_dev->of_node,
- "key_valid", &lcd_ext_key_valid);
+ "key_valid", &extern_para[0]);
if (ret) {
if (lcd_debug_print_flag)
EXTPR("failed to get key_valid\n");
- lcd_ext_key_valid = 0;
+ lcd_extern_config.key_valid = 0;
+ } else {
+ lcd_extern_config.key_valid = (unsigned char)extern_para[0];
}
- EXTPR("key_valid: %d\n", lcd_ext_key_valid);
+ EXTPR("key_valid: %d\n", lcd_extern_config.key_valid);
- if (lcd_ext_key_valid) {
+ if (lcd_extern_config.key_valid) {
ret = lcd_unifykey_check("lcd_extern");
if (ret < 0)
load_id = 0;
else
load_id = 1;
}
- memset(&extconf, 0, sizeof(struct lcd_extern_config_s));
- extconf.table_init_on = lcd_ext_init_on_table;
- extconf.table_init_off = lcd_ext_init_off_table;
+
if (load_id) {
EXTPR("%s from unifykey\n", __func__);
lcd_ext_config_load = 1;
- ret = lcd_extern_get_config_unifykey(&extconf);
+ ret = lcd_extern_get_config_unifykey(&lcd_extern_config);
if (ret == 0)
- lcd_extern_add_driver(&extconf);
+ lcd_extern_add_driver(&lcd_extern_config);
} else {
#ifdef CONFIG_OF
- EXTPR("%s from dts\n", __func__);
+ aml_lcd_notifier_call_chain(LCD_EVENT_EXTERN_SEL, &ext_index);
+ if (ext_index == LCD_EXTERN_INDEX_INVALID) {
+ EXTERR("%s: invalid index\n", __func__);
+ return -1;
+ }
+ sprintf(ext_propname, "extern_%d", ext_index);
+ EXTPR("%s %s from dts\n", __func__, ext_propname);
lcd_ext_config_load = 0;
- for_each_child_of_node(lcd_extern_dev->of_node, child) {
- ret = lcd_extern_get_config_dts(child, &extconf);
- if (ret == 0)
- lcd_extern_add_driver(&extconf);
+ child = of_get_child_by_name(lcd_extern_dev->of_node,
+ ext_propname);
+ if (child == NULL) {
+ EXTERR("failed to get %s\n", ext_propname);
+ return -1;
}
+ ret = lcd_extern_get_config_dts(child, &lcd_extern_config);
+ if (ret == 0)
+ lcd_extern_add_driver(&lcd_extern_config);
#endif
}
- kfree(lcd_ext_init_on_table);
- kfree(lcd_ext_init_off_table);
return 0;
}
{
int ret = 0;
- if (strcmp(ext_drv->config.name, "ext_default") == 0) {
-#ifdef LCD_EXTERN_DEFAULT_ENABLE
+ if (strcmp(ext_drv->config->name, "ext_default") == 0) {
ret = aml_lcd_extern_default_probe(ext_drv);
-#endif
- } else if (strcmp(ext_drv->config.name, "i2c_T5800Q") == 0) {
+ } else if (strcmp(ext_drv->config->name, "i2c_T5800Q") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q
ret = aml_lcd_extern_i2c_T5800Q_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "i2c_tc101") == 0) {
+ } else if (strcmp(ext_drv->config->name, "i2c_tc101") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_TC101
ret = aml_lcd_extern_i2c_tc101_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "i2c_anx6345") == 0) {
+ } else if (strcmp(ext_drv->config->name, "i2c_anx6345") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6345
ret = aml_lcd_extern_i2c_anx6345_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "i2c_DLPC3439") == 0) {
+ } else if (strcmp(ext_drv->config->name, "i2c_DLPC3439") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439
ret = aml_lcd_extern_i2c_DLPC3439_probe(ext_drv);
#endif
} else {
- EXTERR("invalid driver name: %s\n", ext_drv->config.name);
+ EXTERR("invalid driver name: %s\n", ext_drv->config->name);
ret = -1;
}
return ret;
{
int ret = 0;
- if (strcmp(ext_drv->config.name, "ext_default") == 0) {
-#ifdef LCD_EXTERN_DEFAULT_ENABLE
+ if (strcmp(ext_drv->config->name, "ext_default") == 0) {
ret = aml_lcd_extern_default_probe(ext_drv);
-#endif
- } else if (strcmp(ext_drv->config.name, "spi_LD070WS2") == 0) {
+ } else if (strcmp(ext_drv->config->name, "spi_LD070WS2") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2
ret = aml_lcd_extern_spi_LD070WS2_probe(ext_drv);
#endif
} else {
- EXTERR("invalid driver name: %s\n", ext_drv->config.name);
+ EXTERR("invalid driver name: %s\n", ext_drv->config->name);
ret = -1;
}
return ret;
{
int ret = 0;
- if (strcmp(ext_drv->config.name, "mipi_default") == 0) {
+ if (strcmp(ext_drv->config->name, "mipi_default") == 0) {
ret = aml_lcd_extern_mipi_default_probe(ext_drv);
- } else if (strcmp(ext_drv->config.name, "mipi_N070ICN") == 0) {
+ } else if (strcmp(ext_drv->config->name, "mipi_N070ICN") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_N070ICN
ret = aml_lcd_extern_mipi_N070ICN_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "mipi_KD080D13") == 0) {
+ } else if (strcmp(ext_drv->config->name, "mipi_KD080D13") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13
ret = aml_lcd_extern_mipi_KD080D13_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "mipi_TV070WSM") == 0) {
+ } else if (strcmp(ext_drv->config->name, "mipi_TV070WSM") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_TV070WSM
ret = aml_lcd_extern_mipi_TV070WSM_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "mipi_ST7701") == 0) {
+ } else if (strcmp(ext_drv->config->name, "mipi_ST7701") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_ST7701
ret = aml_lcd_extern_mipi_st7701_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "mipi_P070ACB") == 0) {
+ } else if (strcmp(ext_drv->config->name, "mipi_P070ACB") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_P070ACB
ret = aml_lcd_extern_mipi_p070acb_probe(ext_drv);
#endif
- } else if (strcmp(ext_drv->config.name, "mipi_TL050FHV02CT") == 0) {
+ } else if (strcmp(ext_drv->config->name, "mipi_TL050FHV02CT") == 0) {
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_TL050FHV02CT
ret = aml_lcd_extern_mipi_tl050fhv02ct_probe(ext_drv);
#endif
} else {
- EXTERR("invalid driver name: %s\n", ext_drv->config.name);
+ EXTERR("invalid driver name: %s\n", ext_drv->config->name);
ret = -1;
}
return ret;
static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf)
{
struct aml_lcd_extern_driver_s *ext_drv;
- int i;
int ret = 0;
- if (lcd_ext_driver_num >= LCD_EXT_DRIVER_MAX) {
- EXTERR("driver num is out of support\n");
- return -1;
- }
if (extconf->status == 0) {
EXTERR("driver %s[%d] status is disabled\n",
extconf->name, extconf->index);
return -1;
}
- i = lcd_ext_driver_num;
- lcd_ext_driver[i] =
- kmalloc(sizeof(struct aml_lcd_extern_driver_s), GFP_KERNEL);
- if (lcd_ext_driver[i] == NULL) {
+ lcd_ext_driver =
+ kzalloc(sizeof(struct aml_lcd_extern_driver_s), GFP_KERNEL);
+ if (lcd_ext_driver == NULL) {
EXTERR("failed to alloc driver %s[%d], not enough memory\n",
extconf->name, extconf->index);
return -1;
}
- lcd_ext_driver[i]->pinmux_flag = 0;
- ext_drv = lcd_ext_driver[i];
- /* fill config parameters */
- ext_drv->config.index = extconf->index;
- strcpy(ext_drv->config.name, extconf->name);
- ext_drv->config.type = extconf->type;
- ext_drv->config.status = extconf->status;
- ext_drv->config.cmd_size = extconf->cmd_size;
- ext_drv->config.table_init_on = NULL;
- ext_drv->config.table_init_off = NULL;
- ext_drv->config.table_init_loaded = extconf->table_init_loaded;
- ext_drv->config.table_init_on_cnt = extconf->table_init_on_cnt;
- if (ext_drv->config.table_init_loaded) {
- ext_drv->config.table_init_on =
- kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX,
- GFP_KERNEL);
- if (ext_drv->config.table_init_on == NULL) {
- EXTERR("failed to alloc driver %s[%d] init table\n",
- extconf->name, extconf->index);
- return -1;
- }
- ext_drv->config.table_init_off =
- kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX,
- GFP_KERNEL);
- if (ext_drv->config.table_init_off == NULL) {
- EXTERR("failed to alloc driver %s[%d] init table\n",
- extconf->name, extconf->index);
- return -1;
- }
- memcpy(ext_drv->config.table_init_on, extconf->table_init_on,
- LCD_EXTERN_INIT_ON_MAX);
- memcpy(ext_drv->config.table_init_off, extconf->table_init_off,
- LCD_EXTERN_INIT_OFF_MAX);
- }
+ ext_drv = lcd_ext_driver;
- /* fill config parameters by different type */
- switch (ext_drv->config.type) {
+ ext_drv->config = extconf;
+ ext_drv->pinmux_flag = 0;
+
+ switch (ext_drv->config->type) {
case LCD_EXTERN_I2C:
- ext_drv->config.i2c_addr = extconf->i2c_addr;
- ext_drv->config.i2c_addr2 = extconf->i2c_addr2;
- ext_drv->config.i2c_bus = extconf->i2c_bus;
- ext_drv->config.i2c_sck_gpio = extconf->i2c_sck_gpio;
- ext_drv->config.i2c_sck_gpio_off = extconf->i2c_sck_gpio_off;
- ext_drv->config.i2c_sda_gpio = extconf->i2c_sda_gpio;
- ext_drv->config.i2c_sda_gpio_off = extconf->i2c_sda_gpio_off;
ret = lcd_extern_add_i2c(ext_drv);
break;
case LCD_EXTERN_SPI:
- ext_drv->config.spi_gpio_cs = extconf->spi_gpio_cs;
- ext_drv->config.spi_gpio_clk = extconf->spi_gpio_clk;
- ext_drv->config.spi_gpio_data = extconf->spi_gpio_data;
- ext_drv->config.spi_clk_freq = extconf->spi_clk_freq;
- ext_drv->config.spi_clk_pol = extconf->spi_clk_pol;
ret = lcd_extern_add_spi(ext_drv);
break;
case LCD_EXTERN_MIPI:
break;
default:
ret = lcd_extern_add_invalid(ext_drv);
- EXTERR("don't support type %d\n", ext_drv->config.type);
+ EXTERR("don't support type %d\n", ext_drv->config->type);
break;
}
if (ret) {
EXTERR("add driver failed\n");
- kfree(lcd_ext_driver[i]->config.table_init_on);
- kfree(lcd_ext_driver[i]->config.table_init_off);
- kfree(lcd_ext_driver[i]);
- lcd_ext_driver[i] = NULL;
+ kfree(lcd_ext_driver->config->table_init_on);
+ kfree(lcd_ext_driver->config->table_init_off);
+ lcd_ext_driver->config->table_init_on = NULL;
+ lcd_ext_driver->config->table_init_off = NULL;
+ kfree(lcd_ext_driver);
+ lcd_ext_driver = NULL;
return -1;
}
- lcd_ext_driver_num++;
+
EXTPR("add driver %s(%d)\n",
- ext_drv->config.name, ext_drv->config.index);
+ ext_drv->config->name, ext_drv->config->index);
return 0;
}
* debug function
* *********************************************************
*/
-#define EXT_LEN_MAX 2000
+#define EXT_LEN_MAX 300
static void lcd_extern_init_table_dynamic_size_print(
struct lcd_extern_config_s *econf, int flag)
{
char *str;
unsigned char *init_table;
- str = kmalloc(EXT_LEN_MAX*sizeof(char), GFP_KERNEL);
+ str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL);
if (str == NULL) {
EXTERR("lcd_extern_dynamic_size str malloc error\n");
return;
k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,",
init_table[i], cmd_size);
if (cmd_size > 0) {
- for (j = 0; j < cmd_size; j++) {
+ for (j = 0; j < (cmd_size - 1); j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,",
init_table[i+2+j]);
}
+ snprintf(str+k, EXT_LEN_MAX,
+ "%d,", init_table[i+cmd_size+1]);
}
pr_info("%s\n", str);
i += (cmd_size + 2);
char *str;
unsigned char *init_table;
- str = kmalloc(EXT_LEN_MAX*sizeof(char), GFP_KERNEL);
+ str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL);
if (str == NULL) {
EXTERR("lcd_extern_fixed_size str malloc error\n");
return;
i = 0;
while (i < max_len) {
k = snprintf(str, EXT_LEN_MAX, " ");
- for (j = 0; j < cmd_size; j++) {
+ for (j = 0; j < (cmd_size - 1); j++) {
k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x",
init_table[i+j]);
}
+ snprintf(str+k, EXT_LEN_MAX, " %d",
+ init_table[i+cmd_size-1]);
pr_info("%s\n", str);
if (init_table[i] == LCD_EXTERN_INIT_END)
kfree(str);
}
-static void lcd_extern_config_dump(struct aml_lcd_extern_driver_s *ext_drv)
+static ssize_t lcd_extern_info_show(struct class *class,
+ struct class_attribute *attr, char *buf)
{
struct lcd_extern_config_s *econf;
- if (ext_drv == NULL)
- return;
+ if (lcd_ext_driver == NULL)
+ return sprintf(buf, "lcd extern driver is NULL\n");
- econf = &ext_drv->config;
- EXTPR("driver %s(%d) info:\n", econf->name, econf->index);
+ econf = lcd_ext_driver->config;
+ pr_info("lcd extern driver %s(%d) info:\n", econf->name, econf->index);
pr_info("status: %d\n", econf->status);
switch (econf->type) {
case LCD_EXTERN_I2C:
pr_info("not support extern_type\n");
break;
}
- pr_info("\n");
-}
-
-static const char *lcd_extern_debug_usage_str = {
-"Usage:\n"
-" echo index <n> > info ; dump specified index driver config\n"
-" echo all > info ; dump all driver config\n"
-};
-static ssize_t lcd_extern_debug_help(struct class *class,
- struct class_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", lcd_extern_debug_usage_str);
+ return sprintf(buf, "\n");
}
-static ssize_t lcd_extern_info_dump(struct class *class,
- struct class_attribute *attr, const char *buf, size_t count)
-{
- unsigned int ret = 0;
- int i, index;
- struct aml_lcd_extern_driver_s *ext_drv;
-
- index = LCD_EXTERN_INDEX_INVALID;
- switch (buf[0]) {
- case 'i':
- ret = sscanf(buf, "index %d", &index);
- if (ret == 1) {
- ext_drv = aml_lcd_extern_get_driver(index);
- lcd_extern_config_dump(ext_drv);
- } else {
- EXTERR("invalid parameters\n");
- }
- break;
- case 'a':
- for (i = 0; i < lcd_ext_driver_num; i++)
- lcd_extern_config_dump(lcd_ext_driver[i]);
- break;
- default:
- EXTERR("invalid command\n");
- break;
- }
-
- return count;
-}
-
-static ssize_t lcd_extern_debug_key_valid_show(struct class *class,
+static ssize_t lcd_extern_key_valid_show(struct class *class,
struct class_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", lcd_ext_key_valid);
+ return sprintf(buf, "%d\n", lcd_extern_config.key_valid);
}
-static ssize_t lcd_extern_debug_config_load_show(struct class *class,
+static ssize_t lcd_extern_config_load_show(struct class *class,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", lcd_ext_config_load);
}
-static const char *lcd_extern_debug_test_usage_str = {
+static const char *lcd_extern_debug_usage_str = {
"Usage:\n"
-" echo <index> <on/off> > test ; test power on/off for index extern device\n"
+" echo test <on/off> > debug ; test power on/off for extern device\n"
" <on/off>: 1 for power on, 0 for power off\n"
+" echo r <addr_sel> <reg> > debug ; read reg for extern device\n"
+" echo d <addr_sel> <reg> <cnt> > debug ; dump regs for extern device\n"
+" echo w <addr_sel> <reg> <value> > debug ; write reg for extern device\n"
};
-static ssize_t lcd_extern_debug_test_show(struct class *class,
+static ssize_t lcd_extern_debug_show(struct class *class,
struct class_attribute *attr, char *buf)
{
- return sprintf(buf, "%s\n", lcd_extern_debug_test_usage_str);
+ return sprintf(buf, "%s\n", lcd_extern_debug_usage_str);
}
-static ssize_t lcd_extern_debug_test_store(struct class *class,
+static ssize_t lcd_extern_debug_store(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
unsigned int ret;
- int index, flag = 0;
- struct aml_lcd_extern_driver_s *ext_drv;
+ unsigned int val[3], i;
+ unsigned char reg, value;
- index = LCD_EXTERN_INDEX_INVALID;
- ret = sscanf(buf, "%d %d", &index, &flag);
- ext_drv = aml_lcd_extern_get_driver(index);
- if (ext_drv) {
- if (flag) {
- if (ext_drv->power_on)
- ext_drv->power_on(ext_drv);
+ if (lcd_ext_driver == NULL) {
+ pr_info("lcd_extern_driver is null\n");
+ return count;
+ }
+
+ switch (buf[0]) {
+ case 't':
+ ret = sscanf(buf, "test %d", &val[0]);
+ if (ret == 1) {
+ if (val[0]) {
+ if (lcd_ext_driver->power_on)
+ lcd_ext_driver->power_on();
+ } else {
+ if (lcd_ext_driver->power_off)
+ lcd_ext_driver->power_off();
+ }
+ } else {
+ pr_info("invalid data\n");
+ return -EINVAL;
+ }
+ break;
+ case 'r':
+ ret = sscanf(buf, "r %d %x", &val[0], &val[1]);
+ if (ret == 2) {
+ lcd_ext_driver->config->addr_sel =
+ (unsigned char)val[0];
+ reg = (unsigned char)val[1];
+ if (lcd_ext_driver->reg_read) {
+ lcd_ext_driver->reg_read(reg, &value);
+ pr_info("reg read: 0x%02x = 0x%02x\n",
+ reg, value);
+ }
} else {
- if (ext_drv->power_off)
- ext_drv->power_off(ext_drv);
+ pr_info("invalid data\n");
+ return -EINVAL;
}
+ break;
+ case 'd':
+ ret = sscanf(buf, "d %d %x %d", &val[0], &val[1], &val[2]);
+ if (ret == 3) {
+ lcd_ext_driver->config->addr_sel =
+ (unsigned char)val[0];
+ reg = (unsigned char)val[1];
+ if (lcd_ext_driver->reg_read) {
+ pr_info("reg dump:\n");
+ for (i = 0; i < val[2]; i++) {
+ lcd_ext_driver->reg_read(reg+i, &value);
+ pr_info(" 0x%02x = 0x%02x\n",
+ reg, value);
+ }
+ }
+ } else {
+ pr_info("invalid data\n");
+ return -EINVAL;
+ }
+ break;
+ case 'w':
+ ret = sscanf(buf, "w %d %x %x", &val[0], &val[1], &val[2]);
+ if (ret == 2) {
+ lcd_ext_driver->config->addr_sel =
+ (unsigned char)val[0];
+ reg = (unsigned char)val[1];
+ value = (unsigned char)val[2];
+ if (lcd_ext_driver->reg_write) {
+ lcd_ext_driver->reg_write(reg, value);
+ if (lcd_ext_driver->reg_read) {
+ lcd_ext_driver->reg_read(reg, &value);
+ pr_info(
+ "reg write 0x%02x = 0x%02x, readback: 0x%02x\n",
+ reg, val[2], value);
+ } else {
+ pr_info("reg write 0x%02x = 0x%02x\n",
+ reg, value);
+ }
+ }
+ } else {
+ pr_info("invalid data\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_info("invalid data\n");
+ break;
}
return count;
static struct class_attribute lcd_extern_class_attrs[] = {
__ATTR(info, 0644,
- lcd_extern_debug_help, lcd_extern_info_dump),
+ lcd_extern_info_show, NULL),
__ATTR(key_valid, 0444,
- lcd_extern_debug_key_valid_show, NULL),
+ lcd_extern_key_valid_show, NULL),
__ATTR(config_load, 0444,
- lcd_extern_debug_config_load_show, NULL),
- __ATTR(test, 0644,
- lcd_extern_debug_test_show, lcd_extern_debug_test_store),
+ lcd_extern_config_load_show, NULL),
+ __ATTR(debug, 0644,
+ lcd_extern_debug_show, lcd_extern_debug_store),
};
static struct class *debug_class;
static int aml_lcd_extern_probe(struct platform_device *pdev)
{
lcd_extern_dev = &pdev->dev;
- lcd_ext_driver_num = 0;
+
lcd_extern_get_config(); /* also add ext_driver */
creat_lcd_extern_class();
static int aml_lcd_extern_remove(struct platform_device *pdev)
{
- int i;
-
remove_lcd_extern_class();
- for (i = 0; i < lcd_ext_driver_num; i++) {
- kfree(lcd_ext_driver[i]->config.table_init_on);
- kfree(lcd_ext_driver[i]->config.table_init_off);
- kfree(lcd_ext_driver[i]);
- lcd_ext_driver[i] = NULL;
- }
+ kfree(lcd_ext_driver->config->table_init_on);
+ kfree(lcd_ext_driver->config->table_init_off);
+ lcd_ext_driver->config->table_init_on = NULL;
+ lcd_ext_driver->config->table_init_off = NULL;
+ kfree(lcd_ext_driver);
+ lcd_ext_driver = NULL;
return 0;
}
+++ /dev/null
-/*
- * drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- *
- */
-
-lcd_extern{
- compatible = "amlogic, lcd_extern";
- dev_name = "lcd_extern";
- status = "okay";
-
- extern-gpios = <&gpio GPIODV_1 GPIO_ACTIVE_HIGH
- &gpio GPIODV_16 GPIO_ACTIVE_HIGH
- &gpio GPIODV_17 GPIO_ACTIVE_HIGH>;
- extern_gpio_names = "GPIODV_1","GPIODV_16","GPIODV_17";
-
- extern_0{
- index = <0>;
- extern_name = "i2c_T5800Q";
- status = "disabled";
-
- type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
- i2c_address = <0x1c>; /** 7bit i2c address */
- i2c_bus = "i2c_bus_d";
- };
-
- extern_1{
- index = <1>;
- extern_name = "i2c_tc101";
- status = "disabled";
-
- type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
- i2c_address = <0x7e>; /** 7bit i2c address */
- i2c_bus = "i2c_bus_a";
- };
-
- extern_2{
- index = <2>;
- extern_name = "i2c_anx6345";
- status = "disabled";
-
- type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
- i2c_address = <0x38>; /** 7bit i2c address */
- i2c_bus = "i2c_bus_b";
- lane_num = <1>; /** edp lane_num: 1/2/4 */
- bits = <0>; /** lcd_bits(0=6bit, 1=8bit) */
- link_rate = <1>; /** edp link rate: (0=1.62G, 1=27G, 2=5.4G) */
- };
-
- extern_3{
- index = <3>;
- extern_name = "spi_LD070WS2";
- status = "disabled";
-
- type = <1>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
-
- gpio_spi_cs = <0>; /* index in extern-gpios */
- gpio_spi_clk = <1>; /* index in extern-gpios */
- gpio_spi_data = <2>; /* index in extern-gpios */
- };
-
- extern_4{
- index = <4>;
- extern_name = "mipi_N070ICN";
- status = "disabled";
-
- type = <2>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
- };
-
- extern_5{
- index = <5>;
- extern_name = "mipi_KD080D13";
- status = "disabled";
-
- type = <2>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
- };
-
- extern_6{
- index = <6>;
- extern_name = "i2c_DLPC3439";
- status = "disabled";
-
- type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
- i2c_address = <0x1b>; /** 7bit i2c address */
- i2c_bus = "i2c_bus_a";
- };
-};
-
extern void lcd_extern_gpio_probe(unsigned char index);
extern void lcd_extern_gpio_set(unsigned char index, int value);
extern unsigned int lcd_extern_gpio_get(unsigned char index);
-extern void lcd_extern_pinmux_set(
- struct aml_lcd_extern_driver_s *ext_drv, int status);
+extern void lcd_extern_pinmux_set(int status);
-#define LCD_EXTERN_DEFAULT_ENABLE
+/* common API */
+extern struct aml_lcd_extern_i2c_dev_s *lcd_extern_get_i2c_device(
+ unsigned char addr);
+extern int lcd_extern_i2c_write(struct i2c_client *i2client,
+ unsigned char *buff, unsigned int len);
+extern int lcd_extern_i2c_read(struct i2c_client *i2client,
+ unsigned char *buff, unsigned int len);
-#ifdef LCD_EXTERN_DEFAULT_ENABLE
+
+/* specific API */
extern int aml_lcd_extern_default_probe(
struct aml_lcd_extern_driver_s *ext_drv);
-#endif
+extern int aml_lcd_extern_mipi_default_probe(
+ struct aml_lcd_extern_driver_s *ext_drv);
+
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q
extern int aml_lcd_extern_i2c_T5800Q_probe(
struct aml_lcd_extern_driver_s *ext_drv);
extern int aml_lcd_extern_mipi_tl050fhv02ct_probe(
struct aml_lcd_extern_driver_s *ext_drv);
#endif
-extern int aml_lcd_extern_mipi_default_probe(
- struct aml_lcd_extern_driver_s *ext_drv);
#endif
int ret = 0;
if (ext_drv) {
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
int ret = 0;
if (ext_drv) {
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
int ret = 0;
if (ext_drv) {
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
int ret = 0;
if (ext_drv) {
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
int ret = 0;
if (ext_drv) {
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
int ret = 0;
if (ext_drv) {
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
- if (ext_drv->config.type == LCD_EXTERN_MAX) { //default for no dt
- ext_drv->config.index = LCD_EXTERN_INDEX;
- ext_drv->config.type = LCD_EXTERN_TYPE;
- strcpy(ext_drv->config.name, LCD_EXTERN_NAME);
+ if (ext_drv->config->type == LCD_EXTERN_MAX) { //default for no dt
+ ext_drv->config->index = LCD_EXTERN_INDEX;
+ ext_drv->config->type = LCD_EXTERN_TYPE;
+ strcpy(ext_drv->config->name, LCD_EXTERN_NAME);
- ext_drv->config.table_init_on = &mipi_init_on_table[0];
- ext_drv->config.table_init_off = &mipi_init_off_table[0];
+ ext_drv->config->table_init_on = &mipi_init_on_table[0];
+ ext_drv->config->table_init_off = &mipi_init_off_table[0];
}
#define LCD_EXTERN_NAME "lcd_spi_LD070WS2"
-#define SPI_DELAY 30 /* unit: us */
+#define SPI_DELAY 30 /* unit: us */
+#define SPI_GPIO_CS 0 /* index */
+#define SPI_GPIO_CLK 1 /* index */
+#define SPI_GPIO_DATA 2 /* index */
+#define SPI_CLK_FREQ 10000 /* Hz */
+#define SPI_CLK_POL 1
#define LCD_EXTERN_CMD_SIZE 4
static unsigned char init_on_table[] = {
return -1;
}
- if (ext_drv->config.table_init_loaded == 0) {
- ext_drv->config.table_init_on = init_on_table;
- ext_drv->config.table_init_off = init_off_table;
+ if (ext_drv->config->table_init_loaded == 0) {
+ ext_drv->config->table_init_on = init_on_table;
+ ext_drv->config->table_init_off = init_off_table;
}
- ext_drv->config.spi_delay_us = SPI_DELAY;
+ ext_drv->config->spi_delay_us = SPI_DELAY;
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
{
int ret = 0;
- ext_config = &ext_drv->config;
+ ext_config = ext_drv->config;
ret = lcd_extern_driver_update(ext_drv);
if (lcd_debug_print_flag)
EXTPR("%s: %d\n", __func__, ret);
return ret;
}
+
+int aml_lcd_extern_spi_LD070WS2_remove(void)
+{
+ ext_config = NULL;
+
+ return 0;
+}
if (lcd_ext == NULL) {
LCDPR("no lcd_extern driver\n");
} else {
- if (lcd_ext->config.table_init_on) {
- dsi_write_cmd(lcd_ext->config.table_init_on);
+ if (lcd_ext->config->table_init_on) {
+ dsi_write_cmd(lcd_ext->config->table_init_on);
LCDPR("[extern]%s dsi init on\n",
- lcd_ext->config.name);
+ lcd_ext->config->name);
}
}
}
if (lcd_ext == NULL) {
LCDPR("no lcd_extern driver\n");
} else {
- if (lcd_ext->config.table_init_off) {
- dsi_write_cmd(lcd_ext->config.table_init_off);
+ if (lcd_ext->config->table_init_off) {
+ dsi_write_cmd(lcd_ext->config->table_init_off);
LCDPR("[extern]%s dsi init off\n",
- lcd_ext->config.name);
+ lcd_ext->config->name);
}
}
}
.change_flag = 0,
.retry_enable_flag = 0,
.retry_enable_cnt = 0,
+
+ .backlight_index = 0xff,
+ .extern_index = 0xff,
};
static struct vinfo_s lcd_vinfo = {
if (ext_drv) {
if (status) {
if (ext_drv->power_on)
- ext_drv->power_on(ext_drv);
+ ext_drv->power_on();
else
LCDERR("no ext power on\n");
} else {
if (ext_drv->power_off)
- ext_drv->power_off(ext_drv);
+ ext_drv->power_off();
else
LCDERR("no ext power off\n");
}
.notifier_call = lcd_bl_select_notifier,
};
+static int lcd_extern_select_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ unsigned int *index;
+ struct lcd_config_s *pconf = lcd_driver->lcd_config;
+
+ if ((event & LCD_EVENT_EXTERN_SEL) == 0)
+ return NOTIFY_DONE;
+ /* LCDPR("%s: 0x%lx\n", __func__, event); */
+
+ index = (unsigned int *)data;
+ *index = pconf->extern_index;
+ if (pconf->lcd_basic.lcd_type == LCD_MIPI) {
+ if (*index == LCD_EXTERN_INDEX_INVALID)
+ *index = pconf->lcd_control.mipi_config->extern_init;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block lcd_extern_select_nb = {
+ .notifier_call = lcd_extern_select_notifier,
+};
+
static int lcd_notifier_register(void)
{
int ret = 0;
- ret = aml_lcd_notifier_register(&lcd_bl_select_nb);
- if (ret)
- LCDERR("register aml_bl_select_notifier failed\n");
-
ret = aml_lcd_notifier_register(&lcd_power_encl_on_nb);
if (ret)
LCDERR("register lcd_power_encl_on_nb failed\n");
if (ret)
LCDERR("register lcd_power_screen_restore_nb failed\n");
+ ret = aml_lcd_notifier_register(&lcd_bl_select_nb);
+ if (ret)
+ LCDERR("register aml_bl_select_notifier failed\n");
+ ret = aml_lcd_notifier_register(&lcd_extern_select_nb);
+ if (ret)
+ LCDERR("register lcd_extern_select_nb failed\n");
+
return 0;
}
aml_lcd_notifier_unregister(&lcd_power_encl_on_nb);
aml_lcd_notifier_unregister(&lcd_bl_select_nb);
+ aml_lcd_notifier_unregister(&lcd_extern_select_nb);
}
/* **************************************** */
LCD_EXTERN_MAX,
};
-enum lcd_extern_i2c_bus_e {
- LCD_EXTERN_I2C_BUS_AO = 0,
- LCD_EXTERN_I2C_BUS_A,
- LCD_EXTERN_I2C_BUS_B,
- LCD_EXTERN_I2C_BUS_C,
- LCD_EXTERN_I2C_BUS_D,
- LCD_EXTERN_I2C_BUS_MAX,
-};
+#define LCD_EXTERN_I2C_BUS_0 0
+#define LCD_EXTERN_I2C_BUS_1 1
+#define LCD_EXTERN_I2C_BUS_2 2
+#define LCD_EXTERN_I2C_BUS_3 3
+#define LCD_EXTERN_I2C_BUS_4 4
+#define LCD_EXTERN_I2C_BUS_MAX 0xff
+
#define LCD_EXTERN_I2C_BUS_INVALID 0xff
+#define LCD_EXTERN_I2C_ADDR_INVALID 0xff
#define LCD_EXTERN_SPI_CLK_FREQ_DFT 10000 /* default 10k */
char name[LCD_EXTERN_NAME_LEN_MAX];
enum lcd_extern_type_e type;
unsigned char status;
+ unsigned char pinmux_valid;
+ unsigned char key_valid;
+ unsigned char addr_sel; /* internal used */
+
unsigned char i2c_addr;
unsigned char i2c_addr2;
unsigned char i2c_bus;
unsigned char i2c_sck_gpio_off;
unsigned char i2c_sda_gpio;
unsigned char i2c_sda_gpio_off;
+
unsigned char spi_gpio_cs;
unsigned char spi_gpio_clk;
unsigned char spi_gpio_data;
unsigned int spi_clk_freq;
unsigned int spi_delay_us;
unsigned char spi_clk_pol;
+
unsigned char cmd_size;
- unsigned char table_init_loaded; /* internal use */
unsigned char *table_init_on;
unsigned char *table_init_off;
- unsigned int table_init_on_cnt;
+ unsigned char table_init_loaded; /* internal use */
+ unsigned int table_init_on_cnt; /* internal use */
};
/* global API */
-#define LCD_EXT_DRIVER_MAX 10
struct aml_lcd_extern_driver_s {
- struct lcd_extern_config_s config;
+ struct lcd_extern_config_s *config;
int (*reg_read)(unsigned char reg, unsigned char *buf);
int (*reg_write)(unsigned char reg, unsigned char value);
- int (*power_on)(struct aml_lcd_extern_driver_s *ext_drv);
- int (*power_off)(struct aml_lcd_extern_driver_s *ext_drv);
+ int (*power_on)(void);
+ int (*power_off)(void);
struct pinctrl *pin;
unsigned int pinmux_flag;
};
+#define LCD_EXT_I2C_DEV_MAX 10
struct aml_lcd_extern_i2c_dev_s {
char name[30];
struct i2c_client *client;
#define LCD_EVENT_BACKLIGHT_UPDATE (1 << 9)
#define LCD_EVENT_GAMMA_UPDATE (1 << 10)
+#define LCD_EVENT_EXTERN_SEL (1 << 11)
/* lcd frame rate change occurred */
#define LCD_EVENT_FRAME_RATE_ADJUST (1 << 12)
struct lcd_config_s {
char *lcd_propname;
unsigned int backlight_index;
+ unsigned int extern_index;
struct lcd_basic_s lcd_basic;
struct lcd_timing_s lcd_timing;
struct lcd_hdr_info_s hdr_info;