lineage_kernel_xcoverpro/drivers/media/isdbt/fc8180_spi/fc8180_i2c.c

327 lines
7.9 KiB
C
Raw Permalink Normal View History

2023-06-18 22:53:49 +00:00
/*****************************************************************************
Copyright(c) 2014 FCI Inc. All Rights Reserved
File name : fc8180_i2c.c
Description : source of I2C interface
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
History :
----------------------------------------------------------------------
*******************************************************************************/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include "fci_types.h"
#include "fc8180_regs.h"
#include "fci_oal.h"
#include "fci_hal.h"
#include "fc8180_spi.h"
#define I2C_READ 0x01 /* read command */
#define I2C_WRITE 0x02 /* write command */
#define I2C_AINC 0x04 /* address increment */
#define CHIP_ADDR 0x58
#define I2C_M_FCIRD 1
#define I2C_M_FCIWR 0
#define I2C_MAX_SEND_LENGTH 256
struct i2c_ts_driver {
struct i2c_client *client;
struct input_dev *input_dev;
struct work_struct work;
};
struct i2c_client *fc8180_i2c;
struct i2c_driver fc8180_i2c_driver;
static DEFINE_MUTEX(fci_i2c_lock);
static int fc8180_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
fc8180_i2c = i2c_client;
i2c_set_clientdata(i2c_client, NULL);
return 0;
}
static int fc8180_remove(struct i2c_client *client)
{
return 0;
}
static const struct i2c_device_id fc8180_id[] = {
{ "isdbt_i2c", 0 },
{ },
};
struct i2c_driver fc8180_i2c_driver = {
.driver = {
.name = "isdbt_i2c",
.owner = THIS_MODULE,
},
.probe = fc8180_i2c_probe,
.remove = fc8180_remove,
.id_table = fc8180_id,
};
static s32 i2c_bulkread(HANDLE handle, u8 chip, u8 addr, u8 *data, u16 length)
{
struct i2c_msg rmsg[2];
unsigned char i2c_data[2];
rmsg[0].addr = chip;
rmsg[0].flags = I2C_M_FCIWR;
rmsg[0].len = 2;
rmsg[0].buf = i2c_data;
i2c_data[0] = (addr >> 8) & 0xff;
i2c_data[1] = addr & 0xff;
rmsg[1].addr = chip;
rmsg[1].flags = I2C_M_FCIRD;
rmsg[1].len = length;
rmsg[1].buf = data;
i2c_transfer(fc8180_i2c->adapter, &rmsg[0], 2);
return BBM_OK;
}
static s32 i2c_bulkwrite(HANDLE handle, u8 chip, u8 addr, u8 *data, u16 length)
{
struct i2c_msg wmsg;
unsigned char i2c_data[I2C_MAX_SEND_LENGTH];
if ((length + 2) > I2C_MAX_SEND_LENGTH)
return -ENODEV;
wmsg.addr = chip;
wmsg.flags = I2C_M_FCIWR;
wmsg.len = length + 2;
wmsg.buf = i2c_data;
i2c_data[0] = (addr >> 8) & 0xff;
i2c_data[1] = addr & 0xff;
memcpy(&i2c_data[2], data, length);
i2c_transfer(fc8180_i2c->adapter, &wmsg, 1);
return BBM_OK;
}
static s32 i2c_dataread(HANDLE handle, u8 chip, u8 addr, u8 *data, u32 length)
{
return i2c_bulkread(handle, chip, addr, data, length);
}
s32 fc8180_bypass_read(HANDLE handle, u8 chip, u8 addr, u8 *data, u16 length)
{
s32 res;
u8 bypass_addr = 0x03;
u8 bypass_data = 1;
u8 bypass_len = 1;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, bypass_addr, &bypass_data,
bypass_len);
res |= i2c_bulkread(handle, chip, addr, data, length);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_bypass_write(HANDLE handle, u8 chip, u8 addr, u8 *data, u16 length)
{
s32 res;
u8 bypass_addr = 0x03;
u8 bypass_data = 1;
u8 bypass_len = 1;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, bypass_addr, &bypass_data,
bypass_len);
res |= i2c_bulkwrite(handle, chip, addr, data, length);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_init(HANDLE handle, u16 param1, u16 param2)
{
#ifdef BBM_I2C_SPI
fc8180_spi_init(handle, 0, 0);
#else
/* ts_initialize(); */
#endif
return BBM_OK;
}
s32 fc8180_i2c_byteread(HANDLE handle, u16 addr, u8 *data)
{
s32 res;
u8 command = I2C_READ;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkread(handle, CHIP_ADDR, BBM_DATA_REG, data, 1);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_wordread(HANDLE handle, u16 addr, u16 *data)
{
s32 res;
u8 command = I2C_READ | I2C_AINC;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkread(handle, CHIP_ADDR, BBM_DATA_REG, (u8 *)data, 2);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_longread(HANDLE handle, u16 addr, u32 *data)
{
s32 res;
u8 command = I2C_READ | I2C_AINC;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkread(handle, CHIP_ADDR, BBM_DATA_REG, (u8 *)data, 4);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_bulkread(HANDLE handle, u16 addr, u8 *data, u16 length)
{
s32 res;
u8 command = I2C_READ | I2C_AINC;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkread(handle, CHIP_ADDR, BBM_DATA_REG, data, length);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_bytewrite(HANDLE handle, u16 addr, u8 data)
{
s32 res;
u8 command = I2C_WRITE;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_DATA_REG, (u8 *)&data, 1);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_wordwrite(HANDLE handle, u16 addr, u16 data)
{
s32 res;
u8 command = I2C_WRITE | I2C_AINC;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_DATA_REG, (u8 *)&data, 2);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_longwrite(HANDLE handle, u16 addr, u32 data)
{
s32 res;
u8 command = I2C_WRITE | I2C_AINC;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_DATA_REG, (u8 *)&data, 4);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_bulkwrite(HANDLE handle, u16 addr, u8 *data, u16 length)
{
s32 res;
u8 command = I2C_WRITE | I2C_AINC;
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_DATA_REG, data, length);
mutex_unlock(&fci_i2c_lock);
return res;
}
s32 fc8180_i2c_dataread(HANDLE handle, u16 addr, u8 *data, u32 length)
{
s32 res;
u8 command = I2C_READ;
#ifdef BBM_I2C_SPI
res = fc8180_spi_dataread(handle, addr, data, length);
#else
mutex_lock(&fci_i2c_lock);
res = i2c_bulkwrite(handle, CHIP_ADDR, BBM_ADDRESS_REG,
(u8 *) &addr, 2);
res |= i2c_bulkwrite(handle, CHIP_ADDR, BBM_COMMAND_REG, &command, 1);
res |= i2c_dataread(handle, CHIP_ADDR, BBM_DATA_REG, data, length);
mutex_unlock(&fci_i2c_lock);
#endif
return res;
}
s32 fc8180_i2c_deinit(HANDLE handle)
{
#ifdef BBM_I2C_SPI
fc8180_spi_deinit(handle);
#else
bbm_write(handle, BBM_TS_SEL, 0x00);
/* ts_receiver_disable(); */
#endif
return BBM_OK;
}