Commit a6b396f4 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

media: ccs: Add CCS static data parser library

Add a parser library for parsing the CCS static data format.

The library may be also compiled in user space as the format has uses also
in the user space. Therefore it is dual licensed under the 3-clause BSD
license as well.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 9f65192d
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
ccs-objs += ccs-core.o ccs-reg-access.o \ ccs-objs += ccs-core.o ccs-reg-access.o \
ccs-quirk.o ccs-limits.o ccs-quirk.o ccs-limits.o ccs-data.o
obj-$(CONFIG_VIDEO_CCS) += ccs.o obj-$(CONFIG_VIDEO_CCS) += ccs.o
ccflags-y += -I $(srctree)/drivers/media/i2c ccflags-y += -I $(srctree)/drivers/media/i2c
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* CCS static data binary format definitions
*
* Copyright 2019--2020 Intel Corporation
*/
#ifndef __CCS_DATA_DEFS_H__
#define __CCS_DATA_DEFS_H__
#include "ccs-data.h"
#define CCS_STATIC_DATA_VERSION 0
enum __ccs_data_length_specifier_id {
CCS_DATA_LENGTH_SPECIFIER_1 = 0,
CCS_DATA_LENGTH_SPECIFIER_2 = 1,
CCS_DATA_LENGTH_SPECIFIER_3 = 2
};
#define CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT 6
struct __ccs_data_length_specifier {
u8 length;
} __packed;
struct __ccs_data_length_specifier2 {
u8 length[2];
} __packed;
struct __ccs_data_length_specifier3 {
u8 length[3];
} __packed;
struct __ccs_data_block {
u8 id;
struct __ccs_data_length_specifier length;
} __packed;
#define CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT 5
struct __ccs_data_block3 {
u8 id;
struct __ccs_data_length_specifier2 length;
} __packed;
struct __ccs_data_block4 {
u8 id;
struct __ccs_data_length_specifier3 length;
} __packed;
enum __ccs_data_block_id {
CCS_DATA_BLOCK_ID_DUMMY = 1,
CCS_DATA_BLOCK_ID_DATA_VERSION = 2,
CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS = 3,
CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS = 4,
CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS = 5,
CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS = 6,
CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK = 32,
CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK = 33,
CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION = 36,
CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION = 37,
CCS_DATA_BLOCK_ID_LICENSE = 40,
CCS_DATA_BLOCK_ID_END = 127,
};
struct __ccs_data_block_version {
u8 static_data_version_major[2];
u8 static_data_version_minor[2];
u8 year[2];
u8 month;
u8 day;
} __packed;
struct __ccs_data_block_regs {
u8 reg_len;
} __packed;
#define CCS_DATA_BLOCK_REGS_ADDR_MASK 0x07
#define CCS_DATA_BLOCK_REGS_LEN_SHIFT 3
#define CCS_DATA_BLOCK_REGS_LEN_MASK 0x38
#define CCS_DATA_BLOCK_REGS_SEL_SHIFT 6
enum ccs_data_block_regs_sel {
CCS_DATA_BLOCK_REGS_SEL_REGS = 0,
CCS_DATA_BLOCK_REGS_SEL_REGS2 = 1,
CCS_DATA_BLOCK_REGS_SEL_REGS3 = 2,
};
struct __ccs_data_block_regs2 {
u8 reg_len;
u8 addr;
} __packed;
#define CCS_DATA_BLOCK_REGS_2_ADDR_MASK 0x01
#define CCS_DATA_BLOCK_REGS_2_LEN_SHIFT 1
#define CCS_DATA_BLOCK_REGS_2_LEN_MASK 0x3e
struct __ccs_data_block_regs3 {
u8 reg_len;
u8 addr[2];
} __packed;
#define CCS_DATA_BLOCK_REGS_3_LEN_MASK 0x3f
enum __ccs_data_ffd_pixelcode {
CCS_DATA_BLOCK_FFD_PIXELCODE_EMBEDDED = 1,
CCS_DATA_BLOCK_FFD_PIXELCODE_DUMMY = 2,
CCS_DATA_BLOCK_FFD_PIXELCODE_BLACK = 3,
CCS_DATA_BLOCK_FFD_PIXELCODE_DARK = 4,
CCS_DATA_BLOCK_FFD_PIXELCODE_VISIBLE = 5,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_0 = 8,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_1 = 9,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_2 = 10,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_3 = 11,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_4 = 12,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_5 = 13,
CCS_DATA_BLOCK_FFD_PIXELCODE_MS_6 = 14,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_OB = 16,
CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_OB = 17,
CCS_DATA_BLOCK_FFD_PIXELCODE_LEFT_OB = 18,
CCS_DATA_BLOCK_FFD_PIXELCODE_RIGHT_OB = 19,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_LEFT_OB = 20,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_RIGHT_OB = 21,
CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_LEFT_OB = 22,
CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_RIGHT_OB = 23,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOTAL = 24,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_PDAF = 32,
CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_PDAF = 33,
CCS_DATA_BLOCK_FFD_PIXELCODE_LEFT_PDAF = 34,
CCS_DATA_BLOCK_FFD_PIXELCODE_RIGHT_PDAF = 35,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_LEFT_PDAF = 36,
CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_RIGHT_PDAF = 37,
CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_LEFT_PDAF = 38,
CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_RIGHT_PDAF = 39,
CCS_DATA_BLOCK_FFD_PIXELCODE_SEPARATED_PDAF = 40,
CCS_DATA_BLOCK_FFD_PIXELCODE_ORIGINAL_ORDER_PDAF = 41,
CCS_DATA_BLOCK_FFD_PIXELCODE_VENDOR_PDAF = 41,
};
struct __ccs_data_block_ffd_entry {
u8 pixelcode;
u8 reserved;
u8 value[2];
} __packed;
struct __ccs_data_block_ffd {
u8 num_column_descs;
u8 num_row_descs;
} __packed;
enum __ccs_data_block_rule_id {
CCS_DATA_BLOCK_RULE_ID_IF = 1,
CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS = 2,
CCS_DATA_BLOCK_RULE_ID_FFD = 3,
CCS_DATA_BLOCK_RULE_ID_MSR = 4,
CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT = 5,
};
struct __ccs_data_block_rule_if {
u8 addr[2];
u8 value;
u8 mask;
} __packed;
enum __ccs_data_block_pdaf_readout_order {
CCS_DATA_BLOCK_PDAF_READOUT_ORDER_ORIGINAL = 1,
CCS_DATA_BLOCK_PDAF_READOUT_ORDER_SEPARATE_WITHIN_LINE = 2,
CCS_DATA_BLOCK_PDAF_READOUT_ORDER_SEPARATE_TYPES_SEPARATE_LINES = 3,
};
struct __ccs_data_block_pdaf_readout {
u8 pdaf_readout_info_reserved;
u8 pdaf_readout_info_order;
} __packed;
struct __ccs_data_block_pdaf_pix_loc_block_desc {
u8 block_type_id;
u8 repeat_x[2];
} __packed;
struct __ccs_data_block_pdaf_pix_loc_block_desc_group {
u8 num_block_descs[2];
u8 repeat_y;
} __packed;
enum __ccs_data_block_pdaf_pix_loc_pixel_type {
CCS_DATA_PDAF_PIXEL_TYPE_LEFT_SEPARATED = 0,
CCS_DATA_PDAF_PIXEL_TYPE_RIGHT_SEPARATED = 1,
CCS_DATA_PDAF_PIXEL_TYPE_TOP_SEPARATED = 2,
CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_SEPARATED = 3,
CCS_DATA_PDAF_PIXEL_TYPE_LEFT_SIDE_BY_SIDE = 4,
CCS_DATA_PDAF_PIXEL_TYPE_RIGHT_SIDE_BY_SIDE = 5,
CCS_DATA_PDAF_PIXEL_TYPE_TOP_SIDE_BY_SIDE = 6,
CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_SIDE_BY_SIDE = 7,
CCS_DATA_PDAF_PIXEL_TYPE_TOP_LEFT = 8,
CCS_DATA_PDAF_PIXEL_TYPE_TOP_RIGHT = 9,
CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_LEFT = 10,
CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_RIGHT = 11,
};
struct __ccs_data_block_pdaf_pix_loc_pixel_desc {
u8 pixel_type;
u8 small_offset_x;
u8 small_offset_y;
} __packed;
struct __ccs_data_block_pdaf_pix_loc {
u8 main_offset_x[2];
u8 main_offset_y[2];
u8 global_pdaf_type;
u8 block_width;
u8 block_height;
u8 num_block_desc_groups[2];
} __packed;
struct __ccs_data_block_end {
u8 crc[4];
} __packed;
#endif /* __CCS_DATA_DEFS_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* CCS static data in-memory data structure definitions
*
* Copyright 2019--2020 Intel Corporation
*/
#ifndef __CCS_DATA_H__
#define __CCS_DATA_H__
#include <linux/types.h>
/**
* struct ccs_data_block_version - CCS static data version
* @version_major: Major version number
* @version_minor: Minor version number
* @date_year: Year
* @date_month: Month
* @date_day: Day
*/
struct ccs_data_block_version {
u16 version_major;
u16 version_minor;
u16 date_year;
u8 date_month;
u8 date_day;
};
/**
* struct ccs_reg - CCS register value
* @addr: The 16-bit address of the register
* @len: Length of the data
* @value: Data
*/
struct ccs_reg {
u16 addr;
u16 len;
u8 *value;
};
/**
* struct ccs_if_rule - CCS static data if rule
* @addr: Register address
* @value: Register value
* @mask: Value applied to both actual register value and @value
*/
struct ccs_if_rule {
u16 addr;
u8 value;
u8 mask;
};
/**
* struct ccs_frame_format_desc - CCS frame format descriptor
* @pixelcode: The pixelcode; CCS_DATA_BLOCK_FFD_PIXELCODE_*
* @value: Value related to the pixelcode
*/
struct ccs_frame_format_desc {
u8 pixelcode;
u16 value;
};
/**
* struct ccs_frame_format_descs - A series of CCS frame format descriptors
* @num_column_descs: Number of column descriptors
* @num_row_descs: Number of row descriptors
* @column_descs: Column descriptors
* @row_descs: Row descriptors
*/
struct ccs_frame_format_descs {
u8 num_column_descs;
u8 num_row_descs;
struct ccs_frame_format_desc *column_descs;
struct ccs_frame_format_desc *row_descs;
};
/**
* struct ccs_pdaf_readout - CCS PDAF data readout descriptor
* @pdaf_readout_info_order: PDAF readout order
* @ffd: Frame format of PDAF data
*/
struct ccs_pdaf_readout {
u8 pdaf_readout_info_order;
struct ccs_frame_format_descs *ffd;
};
/**
* struct ccs_rule - A CCS static data rule
* @num_if_rules: Number of if rules
* @if_rules: If rules
* @num_read_only_regs: Number of read-only registers
* @read_only_regs: Read-only registers
* @num_manufacturer_regs: Number of manufacturer-specific registers
* @manufacturer_regs: Manufacturer-specific registers
* @frame_format: Frame format
* @pdaf_readout: PDAF readout
*/
struct ccs_rule {
size_t num_if_rules;
struct ccs_if_rule *if_rules;
size_t num_read_only_regs;
struct ccs_reg *read_only_regs;
size_t num_manufacturer_regs;
struct ccs_reg *manufacturer_regs;
struct ccs_frame_format_descs *frame_format;
struct ccs_pdaf_readout *pdaf_readout;
};
/**
* struct ccs_pdaf_pix_loc_block_desc - PDAF pixel location block descriptor
* @block_type_id: Block type identifier, from 0 to n
* @repeat_x: Number of times this block is repeated to right
*/
struct ccs_pdaf_pix_loc_block_desc {
u8 block_type_id;
u16 repeat_x;
};
/**
* struct ccs_pdaf_pix_loc_block_desc_group - PDAF pixel location block
* descriptor group
* @repeat_y: Number of times the group is repeated down
* @num_block_descs: Number of block descriptors in @block_descs
* @block_descs: Block descriptors
*/
struct ccs_pdaf_pix_loc_block_desc_group {
u8 repeat_y;
u16 num_block_descs;
struct ccs_pdaf_pix_loc_block_desc *block_descs;
};
/**
* struct ccs_pdaf_pix_loc_block_desc - PDAF pixel location block descriptor
* @pixel_type: Type of the pixel; CCS_DATA_PDAF_PIXEL_TYPE_*
* @small_offset_x: offset X coordinate
* @small_offset_y: offset Y coordinate
*/
struct ccs_pdaf_pix_loc_pixel_desc {
u8 pixel_type;
u8 small_offset_x;
u8 small_offset_y;
};
/**
* struct ccs_pdaf_pix_loc_pixel_desc_group - PDAF pixel location pixel
* descriptor group
* @num_descs: Number of descriptors in @descs
* @descs: PDAF pixel location pixel descriptors
*/
struct ccs_pdaf_pix_loc_pixel_desc_group {
u8 num_descs;
struct ccs_pdaf_pix_loc_pixel_desc *descs;
};
/**
* struct ccs_pdaf_pix_loc - PDAF pixel locations
* @main_offset_x: Start X coordinate of PDAF pixel blocks
* @main_offset_y: Start Y coordinate of PDAF pixel blocks
* @global_pdaf_type: PDAF pattern type
* @block_width: Width of a block in pixels
* @block_height: Heigth of a block in pixels
* @num_block_desc_groups: Number of block descriptor groups
* @block_desc_groups: Block descriptor groups
* @num_pixel_desc_grups: Number of pixel descriptor groups
* @pixel_desc_groups: Pixel descriptor groups
*/
struct ccs_pdaf_pix_loc {
u16 main_offset_x;
u16 main_offset_y;
u8 global_pdaf_type;
u8 block_width;
u8 block_height;
u16 num_block_desc_groups;
struct ccs_pdaf_pix_loc_block_desc_group *block_desc_groups;
u8 num_pixel_desc_grups;
struct ccs_pdaf_pix_loc_pixel_desc_group *pixel_desc_groups;
};
/**
* struct ccs_data_container - In-memory CCS static data
* @version: CCS static data version
* @num_sensor_read_only_regs: Number of the read-only registers for the sensor
* @sensor_read_only_regs: Read-only registers for the sensor
* @num_sensor_manufacturer_regs: Number of the manufacturer-specific registers
* for the sensor
* @sensor_manufacturer_regs: Manufacturer-specific registers for the sensor
* @num_sensor_rules: Number of rules for the sensor
* @sensor_rules: Rules for the sensor
* @num_module_read_only_regs: Number of the read-only registers for the module
* @module_read_only_regs: Read-only registers for the module
* @num_module_manufacturer_regs: Number of the manufacturer-specific registers
* for the module
* @module_manufacturer_regs: Manufacturer-specific registers for the module
* @num_module_rules: Number of rules for the module
* @module_rules: Rules for the module
* @sensor_pdaf: PDAF data for the sensor
* @module_pdaf: PDAF data for the module
* @license_length: Lenght of the license data
* @license: License data
* @end: Whether or not there's an end block
* @backing: Raw data, pointed to from elsewhere so keep it around
*/
struct ccs_data_container {
struct ccs_data_block_version *version;
size_t num_sensor_read_only_regs;
struct ccs_reg *sensor_read_only_regs;
size_t num_sensor_manufacturer_regs;
struct ccs_reg *sensor_manufacturer_regs;
size_t num_sensor_rules;
struct ccs_rule *sensor_rules;
size_t num_module_read_only_regs;
struct ccs_reg *module_read_only_regs;
size_t num_module_manufacturer_regs;
struct ccs_reg *module_manufacturer_regs;
size_t num_module_rules;
struct ccs_rule *module_rules;
struct ccs_pdaf_pix_loc *sensor_pdaf;
struct ccs_pdaf_pix_loc *module_pdaf;
size_t license_length;
char *license;
bool end;
void *backing;
};
int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data,
size_t len, struct device *dev, bool verbose);
#endif /* __CCS_DATA_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment