177 lines
5.9 KiB
C
Executable file
177 lines
5.9 KiB
C
Executable file
/*
|
|
* Samsung Exynos5 SoC series FIMC-IS driver
|
|
*
|
|
* exynos5 fimc-is video functions
|
|
*
|
|
* Copyright (c) 2017 Samsung Electronics Co., Ltd
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/pinctrl/consumer.h>
|
|
#include "is-device-sensor-peri.h"
|
|
#include "is-i2c-config.h"
|
|
#include "is-core.h"
|
|
#include "is-vender-specific.h"
|
|
|
|
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
|
int is_i2c_pin_config(struct i2c_client *client, int state)
|
|
{
|
|
int ret = 0;
|
|
char pin_ctrl[10] = {0, };
|
|
struct device *i2c_dev = NULL;
|
|
struct pinctrl *pinctrl_i2c = NULL;
|
|
|
|
if (client == NULL) {
|
|
err("client is NULL.");
|
|
return ret;
|
|
}
|
|
|
|
switch (state) {
|
|
case I2C_PIN_STATE_ON:
|
|
sprintf(pin_ctrl, "on_i2c");
|
|
break;
|
|
case I2C_PIN_STATE_OFF:
|
|
sprintf(pin_ctrl, "off_i2c");
|
|
break;
|
|
default:
|
|
sprintf(pin_ctrl, "default");
|
|
break;
|
|
}
|
|
|
|
i2c_dev = client->dev.parent->parent;
|
|
pinctrl_i2c = devm_pinctrl_get_select(i2c_dev, pin_ctrl);
|
|
if (IS_ERR_OR_NULL(pinctrl_i2c))
|
|
pr_err("%s: Failed to configure i2c pin\n", __func__);
|
|
else
|
|
devm_pinctrl_put(pinctrl_i2c);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int is_i2c_pin_control(struct is_module_enum *module, u32 scenario, u32 value)
|
|
{
|
|
int ret = 0;
|
|
struct is_device_sensor_peri *sensor_peri;
|
|
struct is_device_sensor *device;
|
|
struct is_core *core;
|
|
int i2c_config_state = 0;
|
|
u32 i2c_channel = 0;
|
|
struct is_vender_specific *specific;
|
|
|
|
if (value)
|
|
i2c_config_state = I2C_PIN_STATE_ON;
|
|
else
|
|
i2c_config_state = I2C_PIN_STATE_OFF;
|
|
|
|
sensor_peri = (struct is_device_sensor_peri *)module->private_data;
|
|
device = v4l2_get_subdev_hostdata(module->subdev);
|
|
core = is_get_is_core();
|
|
|
|
FIMC_BUG(!core);
|
|
|
|
specific = core->vender.private_data;
|
|
|
|
switch (scenario) {
|
|
case SENSOR_SCENARIO_NORMAL:
|
|
case SENSOR_SCENARIO_VISION:
|
|
case SENSOR_SCENARIO_HW_INIT:
|
|
if (device->client) {
|
|
ret = is_i2c_pin_config(device->client, i2c_config_state);
|
|
}
|
|
if (sensor_peri->cis.client) {
|
|
info("%s[%d] cis i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret = is_i2c_pin_config(sensor_peri->cis.client, i2c_config_state);
|
|
}
|
|
if (device->ois) {
|
|
i2c_channel = module->pdata->ois_i2c_ch;
|
|
|
|
if (i2c_config_state == I2C_PIN_STATE_ON)
|
|
atomic_inc(&core->i2c_rsccount[i2c_channel]);
|
|
else if (i2c_config_state == I2C_PIN_STATE_OFF)
|
|
atomic_dec(&core->i2c_rsccount[i2c_channel]);
|
|
|
|
if (atomic_read(&core->i2c_rsccount[i2c_channel]) == value) {
|
|
info("%s[%d] ois i2c config(%d), position(%d), scenario(%d), i2c_channel(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario, i2c_channel);
|
|
ret |= is_i2c_pin_config(device->ois->client, i2c_config_state);
|
|
}
|
|
}
|
|
if (device->actuator[module->device]) {
|
|
i2c_channel = module->pdata->af_i2c_ch;
|
|
|
|
if (i2c_config_state == I2C_PIN_STATE_ON)
|
|
atomic_inc(&core->i2c_rsccount[i2c_channel]);
|
|
else if (i2c_config_state == I2C_PIN_STATE_OFF)
|
|
atomic_dec(&core->i2c_rsccount[i2c_channel]);
|
|
|
|
if (atomic_read(&core->i2c_rsccount[i2c_channel]) == value) {
|
|
info("%s[%d] actuator i2c config(%d), position(%d), scenario(%d), i2c_channel(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario, i2c_channel);
|
|
ret |= is_i2c_pin_config(device->actuator[module->device]->client, i2c_config_state);
|
|
}
|
|
}
|
|
if (device->aperture) {
|
|
info("%s[%d] aperture i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret |= is_i2c_pin_config(device->aperture->client, i2c_config_state);
|
|
}
|
|
if (device->mcu && scenario != SENSOR_SCENARIO_HW_INIT && device->mcu->name != MCU_NAME_INTERNAL) {
|
|
info("%s[%d] mcu i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret |= is_i2c_pin_config(device->mcu->client, i2c_config_state);
|
|
}
|
|
break;
|
|
case SENSOR_SCENARIO_OIS_FACTORY:
|
|
if (device->ois) {
|
|
info("%s[%d] ois i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret |= is_i2c_pin_config(device->ois->client, i2c_config_state);
|
|
}
|
|
if (device->mcu && device->mcu->name != MCU_NAME_INTERNAL) {
|
|
info("%s[%d] mcu i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret |= is_i2c_pin_config(device->mcu->client, i2c_config_state);
|
|
}
|
|
if (device->actuator[module->device]) {
|
|
info("%s[%d] actuator i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret |= is_i2c_pin_config(device->actuator[module->device]->client, i2c_config_state);
|
|
}
|
|
break;
|
|
case SENSOR_SCENARIO_READ_ROM:
|
|
if (module->pdata->rom_id < ROM_ID_MAX) {
|
|
info("%s[%d] eeprom i2c config(%d), rom_id(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->pdata->rom_id, scenario);
|
|
#if IS_REACHABLE(CONFIG_CAMERA_OTPROM_SUPPORT_REAR)
|
|
if (module->pdata->rom_type == ROM_TYPE_EEPROM) {
|
|
ret |= is_i2c_pin_config(specific->eeprom_client[module->pdata->rom_id], i2c_config_state);
|
|
}
|
|
else if (module->pdata->rom_type == ROM_TYPE_OTPROM) {
|
|
ret |= is_i2c_pin_config(specific->otprom_client[module->pdata->rom_id], i2c_config_state);
|
|
}
|
|
#else
|
|
ret |= is_i2c_pin_config(specific->eeprom_client[module->pdata->rom_id], i2c_config_state);
|
|
#endif
|
|
}
|
|
break;
|
|
case SENSOR_SCENARIO_SECURE:
|
|
if (module->client) {
|
|
info("%s[%d] cis i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
ret = is_i2c_pin_config(module->client, i2c_config_state);
|
|
}
|
|
break;
|
|
default:
|
|
err("%s[%d] undefined scenario, i2c config(%d), position(%d), scenario(%d)\n",
|
|
__func__, __LINE__, i2c_config_state, module->position, scenario);
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif
|