/*
 * Google LWIS PHY Interface
 *
 * Copyright (c) 2018 Google, LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#define pr_fmt(fmt) KBUILD_MODNAME "-phy: " fmt

#include "lwis_phy.h"

#include <linux/kernel.h>
#include <linux/slab.h>

struct lwis_phy_list *lwis_phy_list_alloc(int count)
{
	struct lwis_phy_list *list;

	/* No need to allocate if count is invalid */
	if (count <= 0) {
		return ERR_PTR(-EINVAL);
	}

	list = kmalloc(sizeof(struct lwis_phy_list), GFP_KERNEL);
	if (!list) {
		pr_err("Failed to allocate PHY list\n");
		return ERR_PTR(-ENOMEM);
	}

	list->phy = kzalloc(count * sizeof(struct phy), GFP_KERNEL);
	if (!list->phy) {
		pr_err("Failed to allocate PHY instances\n");
		kfree(list);
		return ERR_PTR(-ENOMEM);
	}

	list->count = count;

	return list;
}

void lwis_phy_list_free(struct lwis_phy_list *list)
{
	if (!list) {
		return;
	}

	if (list->phy) {
		kfree(list->phy);
	}

	kfree(list);
}

int lwis_phy_get(struct lwis_phy_list *list, char *name, struct device *dev)
{
	struct phy *phy;
	int i;
	int index = -1;

	if (!list || !dev) {
		return -EINVAL;
	}

	/* Look for empty slot and duplicate entries */
	for (i = 0; i < list->count; ++i) {
		if (list->phy[i].phy == NULL) {
			index = i;
		} else if (!strcmp(list->phy[i].name, name)) {
			pr_info("PHY %s already allocated\n", name);
			return i;
		}
	}

	/* No empty slots */
	if (index < 0) {
		pr_err("No empty slots in the lwis_phy struct\n");
		return -ENOMEM;
	}

	/* Make sure PHY exists */
	phy = devm_phy_get(dev, name);
	if (IS_ERR(phy)) {
		pr_err("PHY %s not found\n", name);
		return PTR_ERR(phy);
	}

	list->phy[index].phy = phy;
	list->phy[index].name = name;

	return index;
}

int lwis_phy_put_by_idx(struct lwis_phy_list *list, int index, struct device *dev)
{
	if (!list || index < 0 || index >= list->count) {
		return -EINVAL;
	}

	if (IS_ERR_OR_NULL(list->phy[index].phy)) {
		return -EINVAL;
	}

	devm_phy_put(dev, list->phy[index].phy);
	memset(list->phy + index, 0, sizeof(struct lwis_phy));

	return 0;
}

int lwis_phy_put_by_name(struct lwis_phy_list *list, char *name, struct device *dev)
{
	int i;

	if (!dev || !list) {
		return -EINVAL;
	}

	/* Find entry by name */
	for (i = 0; i < list->count; ++i) {
		if (!strcmp(list->phy[i].name, name)) {
			if (IS_ERR_OR_NULL(list->phy[i].phy)) {
				return -EINVAL;
			}
			devm_phy_put(dev, list->phy[i].phy);
			memset(list->phy + i, 0, sizeof(struct lwis_phy));
			return 0;
		}
	}

	pr_err("PHY %s not found\n", name);
	return -EINVAL;
}

int lwis_phy_set_power_by_idx(struct lwis_phy_list *list, int index, bool power_on)
{
	if (!list || index < 0 || index >= list->count) {
		return -EINVAL;
	}

	if (power_on) {
		return phy_power_on(list->phy[index].phy);
	}

	return phy_power_off(list->phy[index].phy);
}

int lwis_phy_set_power_by_name(struct lwis_phy_list *list, char *name, bool power_on)
{
	int i;

	if (!list) {
		return -EINVAL;
	}

	/* Find entry by name */
	for (i = 0; i < list->count; ++i) {
		if (!strcmp(list->phy[i].name, name)) {
			return lwis_phy_set_power_by_idx(list, i, power_on);
		}
	}

	/* Entry not found */
	pr_err("PHY %s not found\n", name);
	return -ENOENT;
}

int lwis_phy_set_power_all(struct lwis_phy_list *list, bool power_on)
{
	int i;
	int ret;

	if (!list) {
		return -EINVAL;
	}

	for (i = 0; i < list->count; ++i) {
		ret = lwis_phy_set_power_by_idx(list, i, power_on);
		if (ret) {
			pr_err("Failed to set PHY power\n");
			return ret;
		}
	}

	return 0;
}

void lwis_phy_print(struct lwis_phy_list *list)
{
	int i;

	for (i = 0; i < list->count; ++i) {
		pr_info("%s: PHY: %s\n", __func__, list->phy[i].name);
	}
}
