/*
 * inv_mpu_acpi: ACPI processing for creating client devices
 * Copyright (c) 2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#ifdef CONFIG_ACPI

#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include "inv_mpu_iio.h"

enum inv_mpu_product_name {
	INV_MPU_NOT_MATCHED,
	INV_MPU_ASUS_T100TA,
};

static enum inv_mpu_product_name matched_product_name;

static int __init asus_t100_matched(const struct dmi_system_id *d)
{
	matched_product_name = INV_MPU_ASUS_T100TA;

	return 0;
}

static const struct dmi_system_id inv_mpu_dev_list[] = {
	{
	.callback = asus_t100_matched,
	.ident = "Asus Transformer Book T100",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC"),
			DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
		},
	},
	/* Add more matching tables here..*/
	{}
};

static int asus_acpi_get_sensor_info(struct acpi_device *adev,
				     struct i2c_client *client,
				     struct i2c_board_info *info)
{
	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	int i;
	acpi_status status;
	union acpi_object *cpm;
	int ret;

	status = acpi_evaluate_object(adev->handle, "CNF0", NULL, &buffer);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	cpm = buffer.pointer;
	for (i = 0; i < cpm->package.count; ++i) {
		union acpi_object *elem;
		int j;

		elem = &cpm->package.elements[i];
		for (j = 0; j < elem->package.count; ++j) {
			union acpi_object *sub_elem;

			sub_elem = &elem->package.elements[j];
			if (sub_elem->type == ACPI_TYPE_STRING)
				strlcpy(info->type, sub_elem->string.pointer,
					sizeof(info->type));
			else if (sub_elem->type == ACPI_TYPE_INTEGER) {
				if (sub_elem->integer.value != client->addr) {
					info->addr = sub_elem->integer.value;
					break; /* Not a MPU6500 primary */
				}
			}
		}
	}
	ret = cpm->package.count;
	kfree(buffer.pointer);

	return ret;
}

static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data)
{
	struct acpi_resource_i2c_serialbus *sb;
	u32 *addr = data;

	if (i2c_acpi_get_i2c_resource(ares, &sb)) {
		if (*addr)
			*addr |= (sb->slave_address << 16);
		else
			*addr = sb->slave_address;
	}

	/* Tell the ACPI core that we already copied this address */
	return 1;
}

static int inv_mpu_process_acpi_config(struct i2c_client *client,
				       unsigned short *primary_addr,
				       unsigned short *secondary_addr)
{
	const struct acpi_device_id *id;
	struct acpi_device *adev;
	u32 i2c_addr = 0;
	LIST_HEAD(resources);
	int ret;

	id = acpi_match_device(client->dev.driver->acpi_match_table,
			       &client->dev);
	if (!id)
		return -ENODEV;

	adev = ACPI_COMPANION(&client->dev);
	if (!adev)
		return -ENODEV;

	ret = acpi_dev_get_resources(adev, &resources,
				     acpi_i2c_check_resource, &i2c_addr);
	if (ret < 0)
		return ret;

	acpi_dev_free_resource_list(&resources);
	*primary_addr = i2c_addr & 0x0000ffff;
	*secondary_addr = (i2c_addr & 0xffff0000) >> 16;

	return 0;
}

int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
{
	struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));

	st->mux_client = NULL;
	if (ACPI_HANDLE(&client->dev)) {
		struct i2c_board_info info;
		struct acpi_device *adev;
		int ret = -1;

		adev = ACPI_COMPANION(&client->dev);
		memset(&info, 0, sizeof(info));

		dmi_check_system(inv_mpu_dev_list);
		switch (matched_product_name) {
		case INV_MPU_ASUS_T100TA:
			ret = asus_acpi_get_sensor_info(adev, client,
							&info);
			break;
		/* Add more matched product processing here */
		default:
			break;
		}

		if (ret < 0) {
			/* No matching DMI, so create device on INV6XX type */
			unsigned short primary, secondary;

			ret = inv_mpu_process_acpi_config(client, &primary,
							  &secondary);
			if (!ret && secondary) {
				char *name;

				info.addr = secondary;
				strlcpy(info.type, dev_name(&adev->dev),
					sizeof(info.type));
				name = strchr(info.type, ':');
				if (name)
					*name = '\0';
				strlcat(info.type, "-client",
					sizeof(info.type));
			} else
				return 0; /* no secondary addr, which is OK */
		}
		st->mux_client = i2c_new_device(st->muxc->adapter[0], &info);
		if (!st->mux_client)
			return -ENODEV;
	}

	return 0;
}

void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
{
	struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));

	i2c_unregister_device(st->mux_client);
}
#else

#include "inv_mpu_iio.h"

int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
{
	return 0;
}

void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
{
}
#endif
