blob: 44aa8bd8e8b92d1a630ebda770bde3dc36dbec05 [file] [log] [blame]
/*
* drivers/amlogic/media/camera/common/plat_ctrl.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/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/mutex.h>
#include <linux/videodev2.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/highmem.h>
#include <linux/freezer.h>
#include <media/videobuf-vmalloc.h>
#include <linux/i2c.h>
#include "plat_ctrl.h"
/****************************************************************
* i2c functions
* **************************************************************/
static int camera_read_buff(struct i2c_client *client, char *buf, int addr_len,
int data_len)
{
int i2c_flag = -1;
struct i2c_msg msgs[] = {{
.addr = client->addr, .flags = 0,
.len = addr_len, .buf = buf,
}, {
.addr = client->addr, .flags = I2C_M_RD,
.len = data_len, .buf = buf,
}
};
i2c_flag = i2c_transfer(client->adapter, msgs, 2);
return i2c_flag;
}
static int camera_write_buff(struct i2c_client *client, char *buf, int len)
{
struct i2c_msg msg[] = {{
.addr = client->addr, .flags = 0, /* |I2C_M_TEN, */
.len = len, .buf = buf,
}
};
if (i2c_transfer(client->adapter, msg, 1) < 0) {
pr_err("i2c error\n");
return -1;
} else
return 0;
}
int i2c_get_byte(struct i2c_client *client, unsigned short addr)
{
unsigned char buff[4];
buff[0] = (unsigned char)((addr >> 8) & 0xff);
buff[1] = (unsigned char)(addr & 0xff);
if (camera_read_buff(client, buff, 2, 1) < 0)
return -1;
return buff[0];
}
int i2c_get_byte_add8(struct i2c_client *client, unsigned char addr)
{
unsigned char buff[4];
buff[0] = (unsigned char)(addr & 0xff);
if (camera_read_buff(client, buff, 1, 1) < 0)
return -1;
return buff[0];
}
int i2c_get_word(struct i2c_client *client, unsigned short addr)
{
unsigned short data;
unsigned char buff[4];
buff[0] = (unsigned char)((addr >> 8) & 0xff);
buff[1] = (unsigned char)(addr & 0xff);
if (camera_read_buff(client, buff, 2, 2) < 0)
return -1;
data = buff[0];
data = (data << 8) | buff[1];
return data;
}
int i2c_put_byte(struct i2c_client *client, unsigned short addr,
unsigned char data)
{
unsigned char buff[4];
buff[0] = (unsigned char)((addr >> 8) & 0xff);
buff[1] = (unsigned char)(addr & 0xff);
buff[2] = data;
if (camera_write_buff(client, buff, 3) < 0)
return -1;
return 0;
}
int i2c_put_word(struct i2c_client *client, unsigned short addr,
unsigned short data)
{
unsigned char buff[4];
buff[0] = (unsigned char)((addr >> 8) & 0xff);
buff[1] = (unsigned char)(addr & 0xff);
buff[2] = (unsigned char)((data >> 8) & 0xff);
buff[3] = (unsigned char)(data & 0xff);
if (camera_write_buff(client, buff, 4) < 0)
return -1;
return 0;
}
int i2c_put_byte_add8_new(struct i2c_client *client, unsigned char addr,
unsigned char data)
{
unsigned char buff[4];
buff[0] = (unsigned char)(addr & 0xff);
buff[1] = (unsigned char)(data & 0xff);
if (camera_write_buff(client, buff, 2) < 0)
return -1;
return 0;
}
int i2c_put_byte_add8(struct i2c_client *client, char *buf, int len)
{
if (camera_write_buff(client, buf, len) < 0)
return -1;
return 0;
}
int cam_i2c_send_msg(struct i2c_client *client, struct cam_i2c_msg_s i2c_msg)
{
unsigned char buff[4];
switch (i2c_msg.type) {
case ADDR16_DATA16:
buff[0] = (unsigned char)((i2c_msg.addr >> 8) & 0xff);
buff[1] = (unsigned char)(i2c_msg.addr & 0xff);
buff[2] = (unsigned char)((i2c_msg.data >> 8) & 0xff);
buff[3] = (unsigned char)(i2c_msg.data & 0xff);
if (camera_write_buff(client, buff, 4) < 0)
return -1;
break;
case ADDR16_DATA8:
buff[0] = (unsigned char)((i2c_msg.addr >> 8) & 0xff);
buff[1] = (unsigned char)(i2c_msg.addr & 0xff);
buff[2] = (unsigned char)(i2c_msg.data & 0xff);
if (camera_write_buff(client, buff, 3) < 0)
return -1;
break;
case ADDR8_DATA16:
buff[0] = (unsigned char)(i2c_msg.addr & 0xff);
buff[1] = (unsigned char)((i2c_msg.data >> 8) & 0xff);
buff[2] = (unsigned char)(i2c_msg.data & 0xff);
if (camera_write_buff(client, buff, 3) < 0)
return -1;
break;
case ADDR8_DATA8:
buff[0] = (unsigned char)(i2c_msg.addr & 0xff);
buff[1] = (unsigned char)(i2c_msg.data & 0xff);
if (camera_write_buff(client, buff, 2) < 0)
return -1;
break;
case TIME_DELAY:
msleep(i2c_msg.data);
break;
default:
break;
}
return 0;
}