// SPDX-License-Identifier: GPL-2.0
/*
 * Common code for Intel Cherry Trail ACPI INT33FE pseudo device drivers
 * (USB Micro-B and Type-C connector variants).
 *
 * Copyright (c) 2019 Yauhen Kharuzhy <jekhor@gmail.com>
 */

#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "intel_cht_int33fe_common.h"

#define EXPECTED_PTYPE		4

static int cht_int33fe_i2c_res_filter(struct acpi_resource *ares, void *data)
{
	struct acpi_resource_i2c_serialbus *sb;
	int *count = data;

	if (i2c_acpi_get_i2c_resource(ares, &sb))
		(*count)++;

	return 1;
}

static int cht_int33fe_count_i2c_clients(struct device *dev)
{
	struct acpi_device *adev = ACPI_COMPANION(dev);
	LIST_HEAD(resource_list);
	int count = 0;
	int ret;

	ret = acpi_dev_get_resources(adev, &resource_list,
				     cht_int33fe_i2c_res_filter, &count);
	acpi_dev_free_resource_list(&resource_list);
	if (ret < 0)
		return ret;

	return count;
}

static int cht_int33fe_check_hw_type(struct device *dev)
{
	unsigned long long ptyp;
	acpi_status status;
	int ret;

	status = acpi_evaluate_integer(ACPI_HANDLE(dev), "PTYP", NULL, &ptyp);
	if (ACPI_FAILURE(status)) {
		dev_err(dev, "Error getting PTYPE\n");
		return -ENODEV;
	}

	/*
	 * The same ACPI HID is used for different configurations check PTYP
	 * to ensure that we are dealing with the expected config.
	 */
	if (ptyp != EXPECTED_PTYPE)
		return -ENODEV;

	/* Check presence of INT34D3 (hardware-rev 3) expected for ptype == 4 */
	if (!acpi_dev_present("INT34D3", "1", 3)) {
		dev_err(dev, "Error PTYPE == %d, but no INT34D3 device\n",
			EXPECTED_PTYPE);
		return -ENODEV;
	}

	ret = cht_int33fe_count_i2c_clients(dev);
	if (ret < 0)
		return ret;

	switch (ret) {
	case 2:
		return INT33FE_HW_MICROB;
	case 4:
		return INT33FE_HW_TYPEC;
	default:
		return -ENODEV;
	}
}

static int cht_int33fe_probe(struct platform_device *pdev)
{
	struct cht_int33fe_data *data;
	struct device *dev = &pdev->dev;
	int ret;

	ret = cht_int33fe_check_hw_type(dev);
	if (ret < 0)
		return ret;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->dev = dev;

	switch (ret) {
	case INT33FE_HW_MICROB:
		data->probe = cht_int33fe_microb_probe;
		data->remove = cht_int33fe_microb_remove;
		break;

	case INT33FE_HW_TYPEC:
		data->probe = cht_int33fe_typec_probe;
		data->remove = cht_int33fe_typec_remove;
		break;
	}

	platform_set_drvdata(pdev, data);

	return data->probe(data);
}

static int cht_int33fe_remove(struct platform_device *pdev)
{
	struct cht_int33fe_data *data = platform_get_drvdata(pdev);

	return data->remove(data);
}

static const struct acpi_device_id cht_int33fe_acpi_ids[] = {
	{ "INT33FE", },
	{ }
};
MODULE_DEVICE_TABLE(acpi, cht_int33fe_acpi_ids);

static struct platform_driver cht_int33fe_driver = {
	.driver	= {
		.name = "Intel Cherry Trail ACPI INT33FE driver",
		.acpi_match_table = ACPI_PTR(cht_int33fe_acpi_ids),
	},
	.probe = cht_int33fe_probe,
	.remove = cht_int33fe_remove,
};

module_platform_driver(cht_int33fe_driver);

MODULE_DESCRIPTION("Intel Cherry Trail ACPI INT33FE pseudo device driver");
MODULE_AUTHOR("Yauhen Kharuzhy <jekhor@gmail.com>");
MODULE_LICENSE("GPL v2");
