blob: f53fd99e8af02f5e17fed4962841633c0e1f5a91 [file] [log] [blame]
/*
* drivers/display/lcd/bl_extern/bl_extern_i2c_dev.c
*
* 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 named License,
* or 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 <common.h>
#include <malloc.h>
#include <asm/arch/gpio.h>
#ifdef CONFIG_OF_LIBFDT
#include <libfdt.h>
#endif
#ifdef CONFIG_SYS_I2C_AML
#include <aml_i2c.h>
#else
#include <i2c.h>
#include <dm/device.h>
#endif
#include <amlogic/aml_lcd.h>
#include <amlogic/aml_bl_extern.h>
#include "bl_extern.h"
#include "../aml_lcd_common.h"
#include "../aml_lcd_reg.h"
#ifdef CONFIG_SYS_I2C_AML
static unsigned int aml_i2c_bus_tmp = BL_EXTERN_I2C_BUS_MAX;
#endif
struct aml_bl_extern_i2c_match_s {
unsigned char bus_id;
unsigned char bus_sys;
char *bus_str;
};
static struct aml_bl_extern_i2c_match_s aml_bl_extern_i2c_match_table[] = {
{BL_EXTERN_I2C_BUS_0, LCD_EXT_I2C_BUS_0, "i2c_0/a"},
{BL_EXTERN_I2C_BUS_1, LCD_EXT_I2C_BUS_1, "i2c_1/b"},
{BL_EXTERN_I2C_BUS_2, LCD_EXT_I2C_BUS_2, "i2c_2/c"},
{BL_EXTERN_I2C_BUS_3, LCD_EXT_I2C_BUS_3, "i2c_3/d"},
{BL_EXTERN_I2C_BUS_4, LCD_EXT_I2C_BUS_4, "i2c_4/ao"},
{BL_EXTERN_I2C_BUS_MAX, LCD_EXT_I2C_BUS_MAX, "i2c_invalid"},
};
void aml_bl_extern_i2c_bus_print(unsigned char i2c_bus)
{
int i, temp = ARRAY_SIZE(aml_bl_extern_i2c_match_table) - 1;
for (i = 0; i < ARRAY_SIZE(aml_bl_extern_i2c_match_table); i++) {
if (aml_bl_extern_i2c_match_table[i].bus_id == i2c_bus) {
temp = i;
break;
}
}
BLEX("i2c_bus = %s(%d)\n",
aml_bl_extern_i2c_match_table[temp].bus_str, temp);
}
unsigned char aml_bl_extern_i2c_bus_get_sys(unsigned char i2c_bus)
{
int i, ret = LCD_EXT_I2C_BUS_MAX;
for (i = 0; i < ARRAY_SIZE(aml_bl_extern_i2c_match_table); i++) {
if (aml_bl_extern_i2c_match_table[i].bus_id == i2c_bus) {
ret = aml_bl_extern_i2c_match_table[i].bus_sys;
break;
}
}
if (lcd_debug_print_flag)
BLEX("%s: %d->%d\n", __func__, i2c_bus, ret);
return ret;
}
#ifdef CONFIG_SYS_I2C_AML
int aml_bl_extern_i2c_bus_change(unsigned int i2c_bus)
{
unsigned char aml_i2c_bus;
int ret = 0;
aml_i2c_bus_tmp = g_aml_i2c_plat.master_no;
aml_i2c_bus = aml_bl_extern_i2c_bus_get_sys(i2c_bus);
if (aml_i2c_bus == LCD_EXT_I2C_BUS_MAX) {
BLEXERR("%s: invalid sys aml_i2c_bus %d\n", __func__, aml_i2c_bus);
return -1;
}
g_aml_i2c_plat.master_no = aml_i2c_bus;
ret = aml_i2c_init();
return ret;
}
int aml_bl_extern_i2c_bus_recovery(void)
{
int ret = 0;
g_aml_i2c_plat.master_no = aml_i2c_bus_tmp;
ret = aml_i2c_init();
return ret;
}
#else
int aml_bl_extern_i2c_bus_change(unsigned int i2c_bus)
{
return 0;
}
int aml_bl_extern_i2c_bus_recovery(void)
{
return 0;
}
#endif
#ifdef CONFIG_SYS_I2C_AML
int aml_bl_extern_i2c_write(unsigned char i2c_bus, unsigned i2c_addr,
unsigned char *buff, unsigned len)
{
struct i2c_msg msg;
int i, ret = 0;
msg.addr = i2c_addr;
msg.flags = 0;
msg.len = len;
msg.buf = buff;
if (lcd_debug_print_flag) {
printf("%s:", __func__);
for (i = 0; i < len; i++)
printf(" 0x%02x", buff[i]);
printf(" [addr 0x%02x]\n", i2c_addr);
}
ret = aml_i2c_xfer(&msg, 1);
if (ret < 0)
BLEXERR("i2c write failed [addr 0x%02x]\n", i2c_addr);
return ret;
}
int aml_bl_extern_i2c_read(unsigned char i2c_bus, unsigned i2c_addr,
unsigned char *buff, unsigned int len)
{
struct i2c_msg msgs[2];
int ret = 0;
msgs[0].addr = i2c_addr;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = buff;
msgs[1].addr = i2c_addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = len;
msgs[1].buf = buff;
ret = aml_i2c_xfer(msgs, 2);
if (ret < 0)
BLEXERR("i2c read failed [addr 0x%02x]\n", i2c_addr);
return ret;
}
#else
int aml_bl_extern_i2c_write(unsigned char i2c_bus, unsigned i2c_addr,
unsigned char *buff, unsigned len)
{
unsigned char aml_i2c_bus;
struct udevice *i2c_dev;
int i, ret = 0;
aml_i2c_bus = aml_bl_extern_i2c_bus_get_sys(i2c_bus);
ret = i2c_get_chip_for_busnum(aml_i2c_bus, i2c_addr, &i2c_dev);
if (ret) {
BLEXERR("no sys aml_i2c_bus %d find\n", aml_i2c_bus);
return ret;
}
if (lcd_debug_print_flag) {
printf("%s:", __func__);
for (i = 0; i < len; i++)
printf(" 0x%02x", buff[i]);
printf(" [addr 0x%02x]\n", i2c_addr);
}
ret = i2c_write(i2c_dev, i2c_addr, buff, len);
if (ret) {
BLEXERR("i2c write failed [addr 0x%02x]\n", i2c_addr);
return ret;
}
return 0;
}
int aml_bl_extern_i2c_read(unsigned char i2c_bus, unsigned i2c_addr,
unsigned char *buff, unsigned int len)
{
unsigned char aml_i2c_bus;
struct udevice *i2c_dev;
int ret = 0;
aml_i2c_bus = aml_bl_extern_i2c_bus_get_sys(i2c_bus);
ret = i2c_get_chip_for_busnum(aml_i2c_bus, i2c_addr, &i2c_dev);
if (ret) {
BLEXERR("no sys aml_i2c_bus %d find\n", aml_i2c_bus);
return ret;
}
ret = i2c_write(i2c_dev, i2c_addr, buff, 1);
if (ret) {
BLEXERR("i2c write failed [addr 0x%02x]\n", i2c_addr);
return ret;
}
ret = i2c_read(i2c_dev, i2c_addr, buff, len);
if (ret) {
BLEXERR("i2c read failed [addr 0x%02x]\n", i2c_addr);
return ret;
}
return 0;
}
#endif