}
}
+void atomisp_free_all_shading_tables(struct atomisp_device *isp)
+{
+ int i;
+
+ for (i = 0; i < isp->input_cnt; i++) {
+ if (isp->inputs[i].shading_table == NULL)
+ continue;
+ sh_css_shading_table_free(isp->inputs[i].shading_table);
+ isp->inputs[i].shading_table = NULL;
+ }
+}
+
+int atomisp_set_shading_table(struct atomisp_device *isp,
+ struct atomisp_shading_table *user_shading_table)
+{
+ struct sh_css_shading_table *shading_table;
+ struct sh_css_shading_table *free_table;
+ unsigned int len_table;
+ int i;
+ int ret = 0;
+
+ if (!user_shading_table)
+ return -EINVAL;
+
+ if (user_shading_table->flags & ATOMISP_SC_FLAG_QUERY) {
+ user_shading_table->enable = isp->params.sc_en;
+ return 0;
+ }
+
+ if (!user_shading_table->enable) {
+ mutex_lock(&isp->isp_lock);
+ sh_css_set_shading_table(NULL);
+ isp->params.sc_en = 0;
+ mutex_unlock(&isp->isp_lock);
+ return 0;
+ }
+
+ /* If enabling, all tables must be set */
+ for (i = 0; i < ATOMISP_NUM_SC_COLORS; i++) {
+ if (!user_shading_table->data[i])
+ return -EINVAL;
+ }
+
+ /* Shading table size per color */
+ if (user_shading_table->width > SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
+ user_shading_table->height > SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR)
+ return -EINVAL;
+
+ shading_table = sh_css_shading_table_alloc(user_shading_table->width,
+ user_shading_table->height);
+ if (!shading_table)
+ return -ENOMEM;
+
+ len_table = user_shading_table->width * user_shading_table->height *
+ ATOMISP_SC_TYPE_SIZE;
+ for (i = 0; i < ATOMISP_NUM_SC_COLORS; i++) {
+ ret = copy_from_user(shading_table->data[i],
+ user_shading_table->data[i], len_table);
+ if (ret) {
+ free_table = shading_table;
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+ shading_table->sensor_width = user_shading_table->sensor_width;
+ shading_table->sensor_height = user_shading_table->sensor_height;
+ shading_table->fraction_bits = user_shading_table->fraction_bits;
+
+ mutex_lock(&isp->isp_lock);
+
+ free_table = isp->inputs[isp->input_curr].shading_table;
+ isp->inputs[isp->input_curr].shading_table = shading_table;
+ sh_css_set_shading_table(shading_table);
+ isp->params.sc_en = 1;
+
+ mutex_unlock(&isp->isp_lock);
+
+out:
+ if (free_table != NULL)
+ sh_css_shading_table_free(free_table);
+
+ return ret;
+}
+
/*
* atomisp_acc_get_fw - Search for firmware with given handle
*
int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f);
int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f);
+void atomisp_free_all_shading_tables(struct atomisp_device *isp);
+int atomisp_set_shading_table(struct atomisp_device *isp,
+ struct atomisp_shading_table *shading_table);
+
int atomisp_save_iunit_reg(struct atomisp_device *isp);
int atomisp_restore_iunit_reg(struct atomisp_device *isp);
atomisp_free_3a_buffers(isp);
atomisp_free_dis_buffers(isp);
+ atomisp_free_all_shading_tables(isp);
atomisp_free_internal_buffers(isp);
sh_css_uninit();
hrt_isp_css_mm_clear();
.default_value = 0,
},
{
- .id = V4L2_CID_ATOMISP_SHADING_CORRECTION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Lens Shading Correction",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
.id = V4L2_CID_REQUEST_FLASH,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Request flash frames",
case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
ret = atomisp_false_color(isp, 0, &control->value);
break;
- case V4L2_CID_ATOMISP_SHADING_CORRECTION:
- ret = atomisp_shading_correction(isp, 0, &control->value);
- break;
case V4L2_CID_ATOMISP_LOW_LIGHT:
ret = atomisp_low_light(isp, 0, &control->value);
break;
case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
ret = atomisp_false_color(isp, 1, &control->value);
break;
- case V4L2_CID_ATOMISP_SHADING_CORRECTION:
- ret = atomisp_shading_correction(isp, 1, &control->value);
- break;
case V4L2_CID_REQUEST_FLASH:
ret = atomisp_flash_enable(isp, control->value);
break;
return BC_Camera_Bridge((BC_Video_ioctl_package *)arg,
(unsigned long) NULL);
+ case ATOMISP_IOC_S_ISP_SHD_TAB:
+ return atomisp_set_shading_table(isp, arg);
+
default:
return -EINVAL;
}
(HIVE_ISP_DDR_WORD_BYTES/SH_CSS_MORPH_TABLE_ELEM_BYTES)
#define SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR (SH_CSS_MAX_BQ_GRID_WIDTH + 1)
+#define SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR (SH_CSS_MAX_BQ_GRID_HEIGHT + 1)
#define SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR \
CEIL_MUL(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
#define ATOM_ISP_MAX_INPUTS 4
#define ATOMISP_ACC_FW_MAX 8
+#define ATOMISP_SC_TYPE_SIZE 2
+
int atomisp_video_init(struct atomisp_video_pipe *video, const char *name);
void atomisp_video_unregister(struct atomisp_video_pipe *video);
int atomisp_video_register(struct atomisp_video_pipe *video,
unsigned short *coordinates_y[atomisp_morph_table_num_planes];
};
-#define atomisp_num_sc_colors 4
+#define ATOMISP_NUM_SC_COLORS 4
+
+#define ATOMISP_SC_FLAG_QUERY (1 << 0)
+
struct atomisp_shading_table {
+ /*
+ * If flag ATOMISP_SC_FLAG_QUERY is set, IOCTL will only query current
+ * LSC status and return, otherwise it will set LSC according to
+ * userspace's input.
+ */
+ __u8 flags;
+ /*
+ * If ATOMISP_SC_FLAG_QUERY is set, enable is output parameter,
+ * otherwise it is an input parameter and will enable/disable LSC
+ * engine
+ */
+ __u8 enable;
/* native sensor resolution */
- unsigned int sensor_width;
- unsigned int sensor_height;
+ __u32 sensor_width;
+ __u32 sensor_height;
/* number of data points per line per color (bayer quads) */
- unsigned int width;
+ __u32 width;
/* number of lines of data points per color (bayer quads) */
- unsigned int height;
+ __u32 height;
/* bits of fraction part for shading table values */
- unsigned int fraction_bits;
+ __u32 fraction_bits;
/* one table for each color (use sh_css_sc_color to index) */
- unsigned short *data[atomisp_num_sc_colors];
+ __u16 __user *data[ATOMISP_NUM_SC_COLORS];
};
struct atomisp_makernote_info {
#define ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA \
_IOWR('v', BASE_VIDIOC_PRIVATE + 51, struct v4l2_private_int_data)
+/* LCS (shading) table write */
+#define ATOMISP_IOC_S_ISP_SHD_TAB \
+ _IOWR('v', BASE_VIDIOC_PRIVATE + 52, struct atomisp_shading_table)
+
/* ISP Private control IDs */
#define V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION \
(V4L2_CID_PRIVATE_BASE + 0)
(V4L2_CID_PRIVATE_BASE + 3)
#define V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION \
(V4L2_CID_PRIVATE_BASE + 4)
+
+/* Deprecated. Use ATOMISP_IOC_S_ISP_SHD_TAB instead. */
#define V4L2_CID_ATOMISP_SHADING_CORRECTION \
(V4L2_CID_PRIVATE_BASE + 5)
#define V4L2_CID_ATOMISP_LOW_LIGHT \