mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
69cacc04bf
PD#SWPL-108141 Problem: 5. 15 no camera driver Solution: porting camera driver to kernel-5.15 Verify: ok Change-Id: I92789c946a8f2456f6bb68adc52ece77cd730f81 Signed-off-by: junwei.ma <junwei.ma@amlogic.com>
212 lines
5.1 KiB
C
212 lines
5.1 KiB
C
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
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;
|
|
}
|
|
|