// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * CCS static data binary parser library
 *
 * Copyright 2019--2020 Intel Corporation
 */

#include <linux/device.h>
#include <linux/errno.h>
#include <linux/limits.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/types.h>

#include "ccs-data-defs.h"

struct bin_container {
	void *base;
	void *now;
	void *end;
	size_t size;
};

static void *bin_alloc(struct bin_container *bin, size_t len)
{
	void *ptr;

	len = ALIGN(len, 8);

	if (bin->end - bin->now < len)
		return NULL;

	ptr = bin->now;
	bin->now += len;

	return ptr;
}

static void bin_reserve(struct bin_container *bin, size_t len)
{
	bin->size += ALIGN(len, 8);
}

static int bin_backing_alloc(struct bin_container *bin)
{
	bin->base = bin->now = kvzalloc(bin->size, GFP_KERNEL);
	if (!bin->base)
		return -ENOMEM;

	bin->end = bin->base + bin->size;

	return 0;
}

#define is_contained(var, endp)				\
	(sizeof(*var) <= (endp) - (void *)(var))
#define has_headroom(ptr, headroom, endp)	\
	((headroom) <= (endp) - (void *)(ptr))
#define is_contained_with_headroom(var, headroom, endp)		\
	(sizeof(*var) + (headroom) <= (endp) - (void *)(var))

static int
ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier *__len,
				size_t *__hlen, size_t *__plen,
				const void *endp)
{
	size_t hlen, plen;

	if (!is_contained(__len, endp))
		return -ENODATA;

	switch (__len->length >> CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) {
	case CCS_DATA_LENGTH_SPECIFIER_1:
		hlen = sizeof(*__len);
		plen = __len->length &
			((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1);
		break;
	case CCS_DATA_LENGTH_SPECIFIER_2: {
		struct __ccs_data_length_specifier2 *__len2 = (void *)__len;

		if (!is_contained(__len2, endp))
			return -ENODATA;

		hlen = sizeof(*__len2);
		plen = ((size_t)
			(__len2->length[0] &
			 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1))
			<< 8) + __len2->length[1];
		break;
	}
	case CCS_DATA_LENGTH_SPECIFIER_3: {
		struct __ccs_data_length_specifier3 *__len3 = (void *)__len;

		if (!is_contained(__len3, endp))
			return -ENODATA;

		hlen = sizeof(*__len3);
		plen = ((size_t)
			(__len3->length[0] &
			 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1))
			<< 16) + (__len3->length[0] << 8) + __len3->length[1];
		break;
	}
	default:
		return -EINVAL;
	}

	if (!has_headroom(__len, hlen + plen, endp))
		return -ENODATA;

	*__hlen = hlen;
	*__plen = plen;

	return 0;
}

static u8
ccs_data_parse_format_version(const struct __ccs_data_block *block)
{
	return block->id >> CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT;
}

static u8 ccs_data_parse_block_id(const struct __ccs_data_block *block,
				       bool is_first)
{
	if (!is_first)
		return block->id;

	return block->id & ((1 << CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT) - 1);
}

static int ccs_data_parse_version(struct bin_container *bin,
				  struct ccs_data_container *ccsdata,
				  const void *payload, const void *endp)
{
	const struct __ccs_data_block_version *v = payload;
	struct ccs_data_block_version *vv;

	if (v + 1 != endp)
		return -ENODATA;

	if (!bin->base) {
		bin_reserve(bin, sizeof(*ccsdata->version));
		return 0;
	}

	ccsdata->version = bin_alloc(bin, sizeof(*ccsdata->version));
	if (!ccsdata->version)
		return -ENOMEM;

	vv = ccsdata->version;
	vv->version_major = ((u16)v->static_data_version_major[0] << 8) +
		v->static_data_version_major[1];
	vv->version_minor = ((u16)v->static_data_version_minor[0] << 8) +
		v->static_data_version_major[1];
	vv->date_year =  ((u16)v->year[0] << 8) + v->year[1];
	vv->date_month = v->month;
	vv->date_day = v->day;

	return 0;
}

static void print_ccs_data_version(struct device *dev,
				   struct ccs_data_block_version *v)
{
	dev_dbg(dev,
		"static data version %4.4x.%4.4x, date %4.4u-%2.2u-%2.2u\n",
		v->version_major, v->version_minor,
		v->date_year, v->date_month, v->date_day);
}

static int ccs_data_block_parse_header(const struct __ccs_data_block *block,
				       bool is_first, unsigned int *__block_id,
				       const void **payload,
				       const struct __ccs_data_block **next_block,
				       const void *endp, struct device *dev,
				       bool verbose)
{
	size_t plen, hlen;
	u8 block_id;
	int rval;

	if (!is_contained(block, endp))
		return -ENODATA;

	rval = ccs_data_parse_length_specifier(&block->length, &hlen, &plen,
					       endp);
	if (rval < 0)
		return rval;

	block_id = ccs_data_parse_block_id(block, is_first);

	if (verbose)
		dev_dbg(dev,
			"Block ID 0x%2.2x, header length %zu, payload length %zu\n",
			block_id, hlen, plen);

	if (!has_headroom(&block->length, hlen + plen, endp))
		return -ENODATA;

	if (__block_id)
		*__block_id = block_id;

	if (payload)
		*payload = (void *)&block->length + hlen;

	if (next_block)
		*next_block = (void *)&block->length + hlen + plen;

	return 0;
}

static int ccs_data_parse_regs(struct bin_container *bin,
			       struct ccs_reg **__regs,
			       size_t *__num_regs, const void *payload,
			       const void *endp, struct device *dev)
{
	struct ccs_reg *regs_base, *regs;
	size_t num_regs = 0;
	u16 addr = 0;

	if (bin->base && __regs) {
		regs = regs_base = bin_alloc(bin, sizeof(*regs) * *__num_regs);
		if (!regs)
			return -ENOMEM;
	}

	while (payload < endp && num_regs < INT_MAX) {
		const struct __ccs_data_block_regs *r = payload;
		size_t len;
		const void *data;

		if (!is_contained(r, endp))
			return -ENODATA;

		switch (r->reg_len >> CCS_DATA_BLOCK_REGS_SEL_SHIFT) {
		case CCS_DATA_BLOCK_REGS_SEL_REGS:
			addr += r->reg_len & CCS_DATA_BLOCK_REGS_ADDR_MASK;
			len = ((r->reg_len & CCS_DATA_BLOCK_REGS_LEN_MASK)
			       >> CCS_DATA_BLOCK_REGS_LEN_SHIFT) + 1;

			if (!is_contained_with_headroom(r, len, endp))
				return -ENODATA;

			data = r + 1;
			break;
		case CCS_DATA_BLOCK_REGS_SEL_REGS2: {
			const struct __ccs_data_block_regs2 *r2 = payload;

			if (!is_contained(r2, endp))
				return -ENODATA;

			addr += ((u16)(r2->reg_len &
				       CCS_DATA_BLOCK_REGS_2_ADDR_MASK) << 8)
				+ r2->addr;
			len = ((r2->reg_len & CCS_DATA_BLOCK_REGS_2_LEN_MASK)
			       >> CCS_DATA_BLOCK_REGS_2_LEN_SHIFT) + 1;

			if (!is_contained_with_headroom(r2, len, endp))
				return -ENODATA;

			data = r2 + 1;
			break;
		}
		case CCS_DATA_BLOCK_REGS_SEL_REGS3: {
			const struct __ccs_data_block_regs3 *r3 = payload;

			if (!is_contained(r3, endp))
				return -ENODATA;

			addr = ((u16)r3->addr[0] << 8) + r3->addr[1];
			len = (r3->reg_len & CCS_DATA_BLOCK_REGS_3_LEN_MASK) + 1;

			if (!is_contained_with_headroom(r3, len, endp))
				return -ENODATA;

			data = r3 + 1;
			break;
		}
		default:
			return -EINVAL;
		}

		num_regs++;

		if (!bin->base) {
			bin_reserve(bin, len);
		} else if (__regs) {
			regs->addr = addr;
			regs->len = len;
			regs->value = bin_alloc(bin, len);
			if (!regs->value)
				return -ENOMEM;

			memcpy(regs->value, data, len);
			regs++;
		}

		addr += len;
		payload = data + len;
	}

	if (!bin->base)
		bin_reserve(bin, sizeof(*regs) * num_regs);

	if (__num_regs)
		*__num_regs = num_regs;

	if (bin->base && __regs)
		*__regs = regs_base;

	return 0;
}

static int ccs_data_parse_reg_rules(struct bin_container *bin,
				    struct ccs_reg **__regs,
				    size_t *__num_regs,
				    const void *payload,
				    const void *endp, struct device *dev)
{
	int rval;

	if (!bin->base)
		return ccs_data_parse_regs(bin, NULL, NULL, payload, endp, dev);

	rval = ccs_data_parse_regs(bin, NULL, __num_regs, payload, endp, dev);
	if (rval)
		return rval;

	return ccs_data_parse_regs(bin, __regs, __num_regs, payload, endp,
				   dev);
}

static void assign_ffd_entry(struct ccs_frame_format_desc *desc,
			     const struct __ccs_data_block_ffd_entry *ent)
{
	desc->pixelcode = ent->pixelcode;
	desc->value = ((u16)ent->value[0] << 8) + ent->value[1];
}

static int ccs_data_parse_ffd(struct bin_container *bin,
			      struct ccs_frame_format_descs **ffd,
			      const void *payload,
			      const void *endp, struct device *dev)
{
	const struct __ccs_data_block_ffd *__ffd = payload;
	const struct __ccs_data_block_ffd_entry *__entry;
	unsigned int i;

	if (!is_contained(__ffd, endp))
		return -ENODATA;

	if ((void *)__ffd + sizeof(*__ffd) +
	    ((u32)__ffd->num_column_descs +
	     (u32)__ffd->num_row_descs) *
	    sizeof(struct __ccs_data_block_ffd_entry) != endp)
		return -ENODATA;

	if (!bin->base) {
		bin_reserve(bin, sizeof(**ffd));
		bin_reserve(bin, __ffd->num_column_descs *
			    sizeof(struct ccs_frame_format_desc));
		bin_reserve(bin, __ffd->num_row_descs *
			    sizeof(struct ccs_frame_format_desc));

		return 0;
	}

	*ffd = bin_alloc(bin, sizeof(**ffd));
	if (!*ffd)
		return -ENOMEM;

	(*ffd)->num_column_descs = __ffd->num_column_descs;
	(*ffd)->num_row_descs = __ffd->num_row_descs;
	__entry = (void *)(__ffd + 1);

	(*ffd)->column_descs = bin_alloc(bin, __ffd->num_column_descs *
					 sizeof(*(*ffd)->column_descs));
	if (!(*ffd)->column_descs)
		return -ENOMEM;

	for (i = 0; i < __ffd->num_column_descs; i++, __entry++)
		assign_ffd_entry(&(*ffd)->column_descs[i], __entry);

	(*ffd)->row_descs = bin_alloc(bin, __ffd->num_row_descs *
				      sizeof(*(*ffd)->row_descs));
	if (!(*ffd)->row_descs)
		return -ENOMEM;

	for (i = 0; i < __ffd->num_row_descs; i++, __entry++)
		assign_ffd_entry(&(*ffd)->row_descs[i], __entry);

	if (__entry != endp)
		return -EPROTO;

	return 0;
}

static int ccs_data_parse_pdaf_readout(struct bin_container *bin,
				       struct ccs_pdaf_readout **pdaf_readout,
				       const void *payload,
				       const void *endp, struct device *dev)
{
	const struct __ccs_data_block_pdaf_readout *__pdaf = payload;

	if (!is_contained(__pdaf, endp))
		return -ENODATA;

	if (!bin->base) {
		bin_reserve(bin, sizeof(**pdaf_readout));
	} else {
		*pdaf_readout = bin_alloc(bin, sizeof(**pdaf_readout));
		if (!*pdaf_readout)
			return -ENOMEM;

		(*pdaf_readout)->pdaf_readout_info_order =
			__pdaf->pdaf_readout_info_order;
	}

	return ccs_data_parse_ffd(bin, !bin->base ? NULL : &(*pdaf_readout)->ffd,
				  __pdaf + 1, endp, dev);
}

static int ccs_data_parse_rules(struct bin_container *bin,
				struct ccs_rule **__rules,
				size_t *__num_rules, const void *payload,
				const void *endp, struct device *dev)
{
	struct ccs_rule *rules_base, *rules = NULL, *next_rule;
	size_t num_rules = 0;
	const void *__next_rule = payload;
	int rval;

	if (bin->base) {
		rules_base = next_rule =
			bin_alloc(bin, sizeof(*rules) * *__num_rules);
		if (!rules_base)
			return -ENOMEM;
	}

	while (__next_rule < endp) {
		size_t rule_hlen, rule_plen, rule_plen2;
		const u8 *__rule_type;
		const void *rule_payload;

		/* Size of a single rule */
		rval = ccs_data_parse_length_specifier(__next_rule, &rule_hlen,
						       &rule_plen, endp);

		if (rval < 0)
			return rval;

		__rule_type = __next_rule + rule_hlen;

		if (!is_contained(__rule_type, endp))
			return -ENODATA;

		rule_payload = __rule_type + 1;
		rule_plen2 = rule_plen - sizeof(*__rule_type);

		switch (*__rule_type) {
		case CCS_DATA_BLOCK_RULE_ID_IF: {
			const struct __ccs_data_block_rule_if *__if_rules =
				rule_payload;
			const size_t __num_if_rules =
				rule_plen2 / sizeof(*__if_rules);
			struct ccs_if_rule *if_rule;

			if (!has_headroom(__if_rules,
					  sizeof(*__if_rules) * __num_if_rules,
					  rule_payload + rule_plen2))
				return -ENODATA;

			/* Also check there is no extra data */
			if (__if_rules + __num_if_rules !=
			    rule_payload + rule_plen2)
				return -EINVAL;

			if (!bin->base) {
				bin_reserve(bin,
					    sizeof(*if_rule) *
					    __num_if_rules);
				num_rules++;
			} else {
				unsigned int i;

				rules = next_rule;
				next_rule++;

				if_rule = bin_alloc(bin,
						    sizeof(*if_rule) *
						    __num_if_rules);
				if (!if_rule)
					return -ENOMEM;

				for (i = 0; i < __num_if_rules; i++) {
					if_rule[i].addr =
						((u16)__if_rules[i].addr[0]
						 << 8) +
						__if_rules[i].addr[1];
					if_rule[i].value = __if_rules[i].value;
					if_rule[i].mask = __if_rules[i].mask;
				}

				rules->if_rules = if_rule;
				rules->num_if_rules = __num_if_rules;
			}
			break;
		}
		case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS:
			rval = ccs_data_parse_reg_rules(bin, &rules->read_only_regs,
							&rules->num_read_only_regs,
							rule_payload,
							rule_payload + rule_plen2,
							dev);
			if (rval)
				return rval;
			break;
		case CCS_DATA_BLOCK_RULE_ID_FFD:
			rval = ccs_data_parse_ffd(bin, &rules->frame_format,
						  rule_payload,
						  rule_payload + rule_plen2,
						  dev);
			if (rval)
				return rval;
			break;
		case CCS_DATA_BLOCK_RULE_ID_MSR:
			rval = ccs_data_parse_reg_rules(bin,
							&rules->manufacturer_regs,
							&rules->num_manufacturer_regs,
							rule_payload,
							rule_payload + rule_plen2,
							dev);
			if (rval)
				return rval;
			break;
		case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT:
			rval = ccs_data_parse_pdaf_readout(bin,
							   &rules->pdaf_readout,
							   rule_payload,
							   rule_payload + rule_plen2,
							   dev);
			if (rval)
				return rval;
			break;
		default:
			dev_dbg(dev,
				"Don't know how to handle rule type %u!\n",
				*__rule_type);
			return -EINVAL;
		}
		__next_rule = __next_rule + rule_hlen + rule_plen;
	}

	if (!bin->base) {
		bin_reserve(bin, sizeof(*rules) * num_rules);
		*__num_rules = num_rules;
	} else {
		*__rules = rules_base;
	}

	return 0;
}

static int ccs_data_parse_pdaf(struct bin_container *bin, struct ccs_pdaf_pix_loc **pdaf,
			       const void *payload, const void *endp,
			       struct device *dev)
{
	const struct __ccs_data_block_pdaf_pix_loc *__pdaf = payload;
	const struct __ccs_data_block_pdaf_pix_loc_block_desc_group *__bdesc_group;
	const struct __ccs_data_block_pdaf_pix_loc_pixel_desc *__pixel_desc;
	unsigned int i;
	u16 num_block_desc_groups;
	u8 max_block_type_id = 0;
	const u8 *__num_pixel_descs;

	if (!is_contained(__pdaf, endp))
		return -ENODATA;

	if (bin->base) {
		*pdaf = bin_alloc(bin, sizeof(**pdaf));
		if (!*pdaf)
			return -ENOMEM;
	} else {
		bin_reserve(bin, sizeof(**pdaf));
	}

	num_block_desc_groups =
		((u16)__pdaf->num_block_desc_groups[0] << 8) +
		__pdaf->num_block_desc_groups[1];

	if (bin->base) {
		(*pdaf)->main_offset_x =
			((u16)__pdaf->main_offset_x[0] << 8) +
			__pdaf->main_offset_x[1];
		(*pdaf)->main_offset_y =
			((u16)__pdaf->main_offset_y[0] << 8) +
			__pdaf->main_offset_y[1];
		(*pdaf)->global_pdaf_type = __pdaf->global_pdaf_type;
		(*pdaf)->block_width = __pdaf->block_width;
		(*pdaf)->block_height = __pdaf->block_height;
		(*pdaf)->num_block_desc_groups = num_block_desc_groups;
	}

	__bdesc_group = (const void *)(__pdaf + 1);

	if (bin->base) {
		(*pdaf)->block_desc_groups =
			bin_alloc(bin,
				  sizeof(struct ccs_pdaf_pix_loc_block_desc_group) *
				  num_block_desc_groups);
		if (!(*pdaf)->block_desc_groups)
			return -ENOMEM;
	} else {
		bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_block_desc_group) *
			    num_block_desc_groups);
	}

	for (i = 0; i < num_block_desc_groups; i++) {
		const struct __ccs_data_block_pdaf_pix_loc_block_desc *__bdesc;
		u16 num_block_descs;
		unsigned int j;

		if (!is_contained(__bdesc_group, endp))
			return -ENODATA;

		num_block_descs =
			((u16)__bdesc_group->num_block_descs[0] << 8) +
			__bdesc_group->num_block_descs[1];

		if (bin->base) {
			(*pdaf)->block_desc_groups[i].repeat_y =
				__bdesc_group->repeat_y;
			(*pdaf)->block_desc_groups[i].num_block_descs =
				num_block_descs;
		}

		__bdesc = (const void *)(__bdesc_group + 1);

		if (bin->base) {
			(*pdaf)->block_desc_groups[i].block_descs =
				bin_alloc(bin,
					  sizeof(struct ccs_pdaf_pix_loc_block_desc) *
					  num_block_descs);
			if (!(*pdaf)->block_desc_groups[i].block_descs)
				return -ENOMEM;
		} else {
			bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_block_desc) *
				    num_block_descs);
		}

		for (j = 0; j < num_block_descs; j++, __bdesc++) {
			struct ccs_pdaf_pix_loc_block_desc *bdesc;

			if (!is_contained(__bdesc, endp))
				return -ENODATA;

			if (max_block_type_id <= __bdesc->block_type_id)
				max_block_type_id = __bdesc->block_type_id + 1;

			if (!bin->base)
				continue;

			bdesc = &(*pdaf)->block_desc_groups[i].block_descs[j];

			bdesc->repeat_x = ((u16)__bdesc->repeat_x[0] << 8)
				+ __bdesc->repeat_x[1];

			if (__bdesc->block_type_id >= num_block_descs)
				return -EINVAL;

			bdesc->block_type_id = __bdesc->block_type_id;
		}

		__bdesc_group = (const void *)__bdesc;
	}

	__num_pixel_descs = (const void *)__bdesc_group;

	if (bin->base) {
		(*pdaf)->pixel_desc_groups =
			bin_alloc(bin,
				  sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group) *
				  max_block_type_id);
		if (!(*pdaf)->pixel_desc_groups)
			return -ENOMEM;
		(*pdaf)->num_pixel_desc_grups = max_block_type_id;
	} else {
		bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group) *
			    max_block_type_id);
	}

	for (i = 0; i < max_block_type_id; i++) {
		struct ccs_pdaf_pix_loc_pixel_desc_group *pdgroup;
		unsigned int j;

		if (!is_contained(__num_pixel_descs, endp))
			return -ENODATA;

		if (bin->base) {
			pdgroup = &(*pdaf)->pixel_desc_groups[i];
			pdgroup->descs =
				bin_alloc(bin,
					  sizeof(struct ccs_pdaf_pix_loc_pixel_desc) *
					  *__num_pixel_descs);
			if (!pdgroup->descs)
				return -ENOMEM;
			pdgroup->num_descs = *__num_pixel_descs;
		} else {
			bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_pixel_desc) *
				    *__num_pixel_descs);
		}

		__pixel_desc = (const void *)(__num_pixel_descs + 1);

		for (j = 0; j < *__num_pixel_descs; j++, __pixel_desc++) {
			struct ccs_pdaf_pix_loc_pixel_desc *pdesc;

			if (!is_contained(__pixel_desc, endp))
				return -ENODATA;

			if (!bin->base)
				continue;

			pdesc = &pdgroup->descs[j];
			pdesc->pixel_type = __pixel_desc->pixel_type;
			pdesc->small_offset_x = __pixel_desc->small_offset_x;
			pdesc->small_offset_y = __pixel_desc->small_offset_y;
		}

		__num_pixel_descs = (const void *)(__pixel_desc + 1);
	}

	return 0;
}

static int ccs_data_parse_license(struct bin_container *bin,
				  char **__license,
				  size_t *__license_length,
				  const void *payload, const void *endp)
{
	size_t size = endp - payload;
	char *license;

	if (!bin->base) {
		bin_reserve(bin, size);
		return 0;
	}

	license = bin_alloc(bin, size);
	if (!license)
		return -ENOMEM;

	memcpy(license, payload, size);

	*__license = license;
	*__license_length = size;

	return 0;
}

static int ccs_data_parse_end(bool *end, const void *payload, const void *endp,
			      struct device *dev)
{
	const struct __ccs_data_block_end *__end = payload;

	if (__end + 1 != endp) {
		dev_dbg(dev, "Invalid end block length %u\n",
			(unsigned int)(endp - payload));
		return -ENODATA;
	}

	*end = true;

	return 0;
}

static int __ccs_data_parse(struct bin_container *bin,
			    struct ccs_data_container *ccsdata,
			    const void *data, size_t len, struct device *dev,
			    bool verbose)
{
	const struct __ccs_data_block *block = data;
	const struct __ccs_data_block *endp = data + len;
	unsigned int version;
	bool is_first = true;
	int rval;

	version = ccs_data_parse_format_version(block);
	if (version != CCS_STATIC_DATA_VERSION) {
		dev_dbg(dev, "Don't know how to handle version %u\n", version);
		return -EINVAL;
	}

	if (verbose)
		dev_dbg(dev, "Parsing CCS static data version %u\n", version);

	if (!bin->base)
		*ccsdata = (struct ccs_data_container){ 0 };

	while (block < endp) {
		const struct __ccs_data_block *next_block;
		unsigned int block_id;
		const void *payload;

		rval = ccs_data_block_parse_header(block, is_first, &block_id,
						   &payload, &next_block, endp,
						   dev,
						   bin->base ? false : verbose);

		if (rval < 0)
			return rval;

		switch (block_id) {
		case CCS_DATA_BLOCK_ID_DUMMY:
			break;
		case CCS_DATA_BLOCK_ID_DATA_VERSION:
			rval = ccs_data_parse_version(bin, ccsdata, payload,
						      next_block);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->sensor_read_only_regs,
				&ccsdata->num_sensor_read_only_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->sensor_manufacturer_regs,
				&ccsdata->num_sensor_manufacturer_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->module_read_only_regs,
				&ccsdata->num_module_read_only_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->module_manufacturer_regs,
				&ccsdata->num_module_manufacturer_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION:
			rval = ccs_data_parse_pdaf(bin, &ccsdata->sensor_pdaf,
						   payload, next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION:
			rval = ccs_data_parse_pdaf(bin, &ccsdata->module_pdaf,
						   payload, next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK:
			rval = ccs_data_parse_rules(
				bin, &ccsdata->sensor_rules,
				&ccsdata->num_sensor_rules, payload, next_block,
				dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK:
			rval = ccs_data_parse_rules(
				bin, &ccsdata->module_rules,
				&ccsdata->num_module_rules, payload, next_block,
				dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_LICENSE:
			rval = ccs_data_parse_license(bin, &ccsdata->license,
						      &ccsdata->license_length,
						      payload, next_block);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_END:
			rval = ccs_data_parse_end(&ccsdata->end, payload,
						  next_block, dev);
			if (rval < 0)
				return rval;
			break;
		default:
			dev_dbg(dev, "WARNING: not handling block ID 0x%2.2x\n",
				block_id);
		}

		block = next_block;
		is_first = false;
	}

	return 0;
}

/**
 * ccs_data_parse - Parse a CCS static data file into a usable in-memory
 *		    data structure
 * @ccsdata:	CCS static data in-memory data structure
 * @data:	CCS static data binary
 * @len:	Length of @data
 * @dev:	Device the data is related to (used for printing debug messages)
 * @verbose:	Whether to be verbose or not
 */
int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data,
		   size_t len, struct device *dev, bool verbose)
{
	struct bin_container bin = { 0 };
	int rval;

	rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose);
	if (rval)
		return rval;

	rval = bin_backing_alloc(&bin);
	if (rval)
		return rval;

	rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false);
	if (rval)
		goto out_free;

	if (verbose && ccsdata->version)
		print_ccs_data_version(dev, ccsdata->version);

	if (bin.now != bin.end) {
		rval = -EPROTO;
		dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n",
			bin.base, bin.now, bin.end);
		goto out_free;
	}

	ccsdata->backing = bin.base;

	return 0;

out_free:
	kvfree(bin.base);

	return rval;
}
