AMLOGIC G12A Audio DRIVER
M: Xing Wang <xing.wang@amlogic.com>
F: sound/soc/amlogic/auge/*
+
+AMLOGIC G12A BL_EXTERN LP8556 DRIVER
+M: Weiming Liu <weiming.liu@amlogic.com>
+F: drivers/amlogic/media/vout/backlight/bl_extern/bl_extern_i2c.c
reset_pin = <&gpio GPIOA_5 0>;
};
+ bl_extern_i2c {
+ compatible = "amlogic, bl_extern_i2c";
+ status = "disabled";
+ reg = <0x2c>; /*reg_address for lp8556*/
+ dev_name = "lp8556";
+ };
+
};
&audiobus {
};
};
- bl_pwm_on_pins: bl_pwm_on_pin {
- mux {
- groups = "pwm_f_h";
- function = "pwm_f";
- };
- };
}; /* end of pinctrl_periphs */
&pinctrl_aobus {
* power value:(0=output low, 1=output high, 2=input)
* power delay:(unit in ms)
*/
- lcd_cpu-gpios = <&gpio GPIOZ_8 GPIO_ACTIVE_HIGH>;
- lcd_cpu_gpio_names = "GPIOZ_8";
+ lcd_cpu-gpios = <&gpio GPIOZ_9 GPIO_ACTIVE_HIGH
+ &gpio GPIOZ_8 GPIO_ACTIVE_HIGH>;
+ lcd_cpu_gpio_names = "GPIOZ_9","GPIOZ_8";
lcd_0{
model_name = "B080XAN01";
/* power step: type, index, value, delay(ms) */
power_on_step = <
+ 0 1 0 100
0 0 0 10
0 0 1 20
2 0 0 0
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 50
- 0 0 0 100
+ 0 0 0 10
+ 0 1 1 100
0xff 0 0 0>; /*ending*/
backlight_index = <0>;
};
status = "okay";
key_valid = <0>;
pinctrl-names = "pwm_on";
- pinctrl-0 = <&bl_pwm_on_pins>; /*pwm_f_pins2*/
+ pinctrl-0 = <&pwm_f_pins2>;
pinctrl_version = <2>; /* for uboot */
/* pwm port: PWM_A, PWM_B, PWM_C, PWM_D, PWM_E, PWM_F, PWM_VS*/
/* power index:(point gpios_index, 0xff=invalid)
-obj-$(CONFIG_AMLOGIC_BL_EXTERN) += bl_extern.o
+obj-$(CONFIG_AMLOGIC_BL_EXTERN) += bl_extern.o bl_extern_i2c.o
obj-$(CONFIG_AMLOGIC_BL_EXTERN_I2C_LP8556) += i2c_lp8556.o
obj-$(CONFIG_AMLOGIC_BL_EXTERN_MIPI_LT070ME05) += mipi_lt070me05.o
static void bl_extern_config_print(void)
{
struct aml_bl_extern_driver_s *bl_extern = aml_bl_extern_get_driver();
+ struct aml_bl_extern_i2c_dev_s *i2c_dev = aml_bl_extern_i2c_get_dev();
BLEX("%s:\n", __func__);
switch (bl_extern->config.type) {
bl_extern->config.i2c_bus,
bl_extern->config.dim_min,
bl_extern->config.dim_max);
+ if (i2c_dev) {
+ pr_info("i2c_dev_name: %s\n"
+ "i2c_client_name: %s\n"
+ "i2c_client_addr: 0x%02x\n",
+ i2c_dev->name,
+ i2c_dev->client->name,
+ i2c_dev->client->addr);
+ } else {
+ pr_info("invalid i2c device\n");
+ }
break;
case BL_EXTERN_SPI:
break;
--- /dev/null
+/*
+ * drivers/amlogic/media/vout/backlight/bl_extern/bl_extern_i2c.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/i2c.h>
+#include <linux/slab.h>
+#include <linux/amlogic/i2c-amlogic.h>
+#include <linux/amlogic/media/vout/lcd/aml_bl_extern.h>
+#include "bl_extern.h"
+
+
+static struct aml_bl_extern_i2c_dev_s *i2c_device;
+struct aml_bl_extern_i2c_dev_s *aml_bl_extern_i2c_get_dev(void)
+{
+ return i2c_device;
+}
+
+static int bl_extern_i2c_config_from_dts(struct device *dev,
+ struct aml_bl_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) {
+ BLEXERR("failed to get dev_i2c_name\n");
+ str = "bl_extern_i2c_name";
+ }
+ strcpy(i2c_device->name, str);
+
+ return 0;
+}
+
+static int aml_bl_extern_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ BLEX("I2C Address: 0x%02x", client->addr);
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ BLEXERR("I2C check functionality failed.");
+ return -ENODEV;
+ }
+
+ i2c_device = kzalloc(sizeof(struct aml_bl_extern_i2c_dev_s),
+ GFP_KERNEL);
+ if (!i2c_device) {
+ BLEXERR("driver malloc error\n");
+ return -ENOMEM;
+ }
+ i2c_device->client = client;
+ bl_extern_i2c_config_from_dts(&client->dev, i2c_device);
+
+ return 0;
+}
+
+static int aml_bl_extern_i2c_remove(struct i2c_client *client)
+{
+ kfree(i2c_device);
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+static const struct i2c_device_id aml_bl_extern_i2c_id[] = {
+ {"bl_extern_i2c", 0},
+ {}
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id aml_bl_extern_i2c_dt_match[] = {
+ {
+ .compatible = "amlogic, bl_extern_i2c",
+ },
+ {},
+};
+#endif
+
+static struct i2c_driver aml_bl_extern_i2c_driver = {
+ .probe = aml_bl_extern_i2c_probe,
+ .remove = aml_bl_extern_i2c_remove,
+ .id_table = aml_bl_extern_i2c_id,
+ .driver = {
+ .name = "bl_extern_i2c",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = aml_bl_extern_i2c_dt_match,
+#endif
+ },
+};
+
+static int __init aml_bl_extern_i2c_init(void)
+{
+ int ret;
+
+ if (lcd_debug_print_flag)
+ BLEX("%s\n", __func__);
+
+ ret = i2c_add_driver(&aml_bl_extern_i2c_driver);
+ if (ret) {
+ BLEXERR("driver register failed\n");
+ return -ENODEV;
+ }
+ return ret;
+}
+
+static void __exit aml_bl_extern_i2c_exit(void)
+{
+ i2c_del_driver(&aml_bl_extern_i2c_driver);
+}
+
+
+module_init(aml_bl_extern_i2c_init);
+module_exit(aml_bl_extern_i2c_exit);
+
+MODULE_AUTHOR("AMLOGIC");
+MODULE_DESCRIPTION("bl extern driver");
+MODULE_LICENSE("GPL");
+
#define BL_EXTERN_CMD_SIZE 4
static unsigned int bl_status;
-static struct i2c_client *i2c_lp8556_client;
static unsigned char init_on_table[] = {
- 0x00, 0xa1, 0x76, 0x00,//hight bit(8~11)(0~0X66e set backlight)
- 0x00, 0xa0, 0x66, 0x00,//low bit(0~7) 20mA
- 0x00, 0x16, 0x1F, 0x00,// 5channel LED enable 0x1F
- 0x00, 0xa9, 0xA0, 0x00,//VBOOST_MAX 25V
- 0x00, 0x9e, 0x12, 0x00,
- 0x00, 0xa2, 0x23, 0x00,
- /*0x03 pwm+I2c set brightness,0x5 I2c set brightness*/
+ 0x00, 0xa2, 0x20, 0x00,
+ 0x00, 0xa5, 0x54, 0x00,
+ 0x00, 0x00, 0xff, 0x00,
0x00, 0x01, 0x05, 0x00,
+ 0x00, 0xa2, 0x20, 0x00,
+ 0x00, 0xa5, 0x54, 0x00,
+ 0x00, 0xa1, 0xb7, 0x00,
+ 0x00, 0xa0, 0xff, 0x00,
+ 0x00, 0x00, 0x80, 0x00,
0xff, 0x00, 0x00, 0x00, //ending
};
0xff, 0x00, 0x00, 0x00, //ending
};
-static int i2c_lp8556_write(struct i2c_client *i2client,
- unsigned char *buff, unsigned int len)
+static int i2c_lp8556_write(unsigned char *buff, unsigned int len)
{
int ret = 0;
+ struct aml_bl_extern_i2c_dev_s *i2c_dev = aml_bl_extern_i2c_get_dev();
+
struct i2c_msg msg[] = {
{
- .addr = i2client->addr,
+ .addr = i2c_dev->client->addr,
.flags = 0,
.len = len,
.buf = buff,
}
};
+ BLEX("%s\n", __func__);
+
+ if (i2c_dev == NULL) {
+ BLEXERR("invalid i2c device\n");
+ return -1;
+ }
- ret = i2c_transfer(i2client->adapter, msg, 1);
+ ret = i2c_transfer(i2c_dev->client->adapter, msg, 1);
if (ret < 0)
- BLEXERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
+ BLEXERR("i2c write failed [addr 0x%02x]\n",
+ i2c_dev->client->addr);
return ret;
}
int i = 0, len;
int ret = 0;
struct aml_bl_extern_driver_s *bl_extern = aml_bl_extern_get_driver();
+ BLEX("%s\n", __func__);
len = BL_EXTERN_CMD_SIZE;
while (i <= BL_EXTERN_INIT_TABLE_MAX) {
} else if (init_table[i] == BL_EXTERN_INIT_NONE) {
/* do nothing, only for delay */
} else if (init_table[i] == BL_EXTERN_INIT_CMD) {
- ret = i2c_lp8556_write(i2c_lp8556_client,
+ ret = i2c_lp8556_write(
&init_table[i+1], (len-2));
} else {
BLEXERR("%s(%d: %s): power_type %d is invalid\n",
{
int ret = 0;
struct aml_bl_extern_driver_s *bl_extern = aml_bl_extern_get_driver();
+ BLEX("%s\n", __func__);
if (flag)
ret = i2c_lp8556_power_cmd(init_on_table);
static int i2c_lp8556_power_on(void)
{
int ret;
+ BLEX("%s\n", __func__);
bl_status = 1;
ret = i2c_lp8556_power_ctrl(1);
if (bl_status) {
tData[0] = 0x0;
tData[1] = level;
- ret = i2c_lp8556_write(i2c_lp8556_client, tData, 2);
+ ret = i2c_lp8556_write(tData, 2);
}
return ret;
}
return 0;
}
-static int bl_extern_i2c_lp8556_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
- BLEXERR("%s: functionality check failed\n", __func__);
- else
- i2c_lp8556_client = client;
-
- BLEX("%s OK\n", __func__);
- return 0;
-}
-
-static int bl_extern_i2c_lp8556_remove(struct i2c_client *client)
-{
- return 0;
-}
-
-static const struct i2c_device_id bl_extern_i2c_lp8556_id[] = {
- {BL_EXTERN_NAME, 0},
- { }
-};
-
-static struct i2c_driver i2c_lp8556_driver = {
- .probe = bl_extern_i2c_lp8556_probe,
- .remove = bl_extern_i2c_lp8556_remove,
- .id_table = bl_extern_i2c_lp8556_id,
- .driver = {
- .name = BL_EXTERN_NAME,
- .owner = THIS_MODULE,
- },
-};
-
int i2c_lp8556_probe(void)
{
int ret = 0;
- struct i2c_board_info i2c_info;
- struct i2c_adapter *adapter;
- struct i2c_client *i2c_client;
- struct aml_bl_extern_driver_s *bl_extern = aml_bl_extern_get_driver();
-
- memset(&i2c_info, 0, sizeof(i2c_info));
- adapter = i2c_get_adapter(bl_extern->config.i2c_bus);
- if (!adapter) {
- BLEXERR("%s failed to get i2c adapter\n",
- bl_extern->config.name);
- return -1;
- }
-
- strncpy(i2c_info.type, bl_extern->config.name, I2C_NAME_SIZE);
- i2c_info.addr = bl_extern->config.i2c_addr;
- i2c_info.platform_data = &bl_extern->config;
- i2c_info.flags = 0;
- if (i2c_info.addr > 0x7f) {
- BLEXERR("%s invalid i2c address: 0x%02x\n",
- bl_extern->config.name, bl_extern->config.i2c_addr);
- return -1;
- }
- i2c_client = i2c_new_device(adapter, &i2c_info);
- if (!i2c_client) {
- BLEXERR("%s failed to new i2c device\n",
- bl_extern->config.name);
- } else {
- if (lcd_debug_print_flag) {
- BLEX("%s new i2c device succeed\n",
- bl_extern->config.name);
- }
- }
-
- if (!i2c_lp8556_client) {
- ret = i2c_add_driver(&i2c_lp8556_driver);
- if (ret) {
- BLEXERR("%s add i2c_driver failed\n",
- bl_extern->config.name);
- return -1;
- }
- }
ret = i2c_lp8556_update();
static void lcd_set_pll_g12a(struct lcd_clk_config_s *cConf)
{
- unsigned int pll_ctrl, pll_ctrl1;
+ unsigned int pll_ctrl, pll_ctrl1, pll_ctrl3, pll_ctrl4, pll_ctrl6;
int ret;
if (lcd_debug_print_flag == 2)
(cConf->pll_n << LCD_PLL_N_G12A) |
(cConf->pll_m << LCD_PLL_M_G12A) |
(cConf->pll_od1_sel << LCD_PLL_OD_G12A));
- pll_ctrl1 = 0x00;
- /*pll_ctrl1 |= ((1 << 19) | (cConf->pll_frac << 0));*/
+ pll_ctrl1 = (cConf->pll_frac << 0);
+ if (cConf->pll_frac) {
+ pll_ctrl |= (1 << 27);
+ pll_ctrl3 = 0x6a295c00;
+ pll_ctrl4 = 0x65771290;
+ pll_ctrl6 = 0x54540000;
+ } else {
+ pll_ctrl3 = 0x08691c00;
+ pll_ctrl4 = 0x33771290;
+ pll_ctrl6 = 0x50540000;
+ }
lcd_hiu_write(HHI_GP0_PLL_CNTL0_G12A, pll_ctrl);
lcd_hiu_write(HHI_GP0_PLL_CNTL1_G12A, pll_ctrl1);
lcd_hiu_write(HHI_GP0_PLL_CNTL2_G12A, 0x00);
- lcd_hiu_write(HHI_GP0_PLL_CNTL3_G12A, 0x08691c00);
- lcd_hiu_write(HHI_GP0_PLL_CNTL4_G12A, 0x33771290);
+ lcd_hiu_write(HHI_GP0_PLL_CNTL3_G12A, pll_ctrl3);
+ lcd_hiu_write(HHI_GP0_PLL_CNTL4_G12A, pll_ctrl4);
lcd_hiu_write(HHI_GP0_PLL_CNTL5_G12A, 0x39272000);
- lcd_hiu_write(HHI_GP0_PLL_CNTL6_G12A, 0x50540000);
+ lcd_hiu_write(HHI_GP0_PLL_CNTL6_G12A, pll_ctrl6);
lcd_hiu_setb(HHI_GP0_PLL_CNTL0_G12A, 1, LCD_PLL_RST_G12A, 1);
udelay(100);
lcd_hiu_setb(HHI_GP0_PLL_CNTL0_G12A, 0, LCD_PLL_RST_G12A, 1);
struct device *dev;
};
+struct aml_bl_extern_i2c_dev_s {
+ char name[20];
+ struct i2c_client *client;
+};
+
+extern struct aml_bl_extern_i2c_dev_s *aml_bl_extern_i2c_get_dev(void);
extern struct aml_bl_extern_driver_s *aml_bl_extern_get_driver(void);
extern int aml_bl_extern_device_load(int index);