/*
 * Driver for SMSC USB4604 USB HSIC 4-port 2.0 hub controller driver
 * Based on usb3503 driver
 *
 * Copyright (c) 2012-2013 Dongjin Kim (tobetter@gmail.com)
 * Copyright (c) 2016 Linaro Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that 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.
 */

#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>

enum usb4604_mode {
	USB4604_MODE_UNKNOWN,
	USB4604_MODE_HUB,
	USB4604_MODE_STANDBY,
};

struct usb4604 {
	enum usb4604_mode	mode;
	struct device		*dev;
	struct gpio_desc	*gpio_reset;
};

static void usb4604_reset(struct usb4604 *hub, int state)
{
	gpiod_set_value_cansleep(hub->gpio_reset, state);

	/* Wait for i2c logic to come up */
	if (state)
		msleep(250);
}

static int usb4604_connect(struct usb4604 *hub)
{
	struct device *dev = hub->dev;
	struct i2c_client *client = to_i2c_client(dev);
	int err;
	u8 connect_cmd[] = { 0xaa, 0x55, 0x00 };

	usb4604_reset(hub, 1);

	err = i2c_master_send(client, connect_cmd, ARRAY_SIZE(connect_cmd));
	if (err < 0) {
		usb4604_reset(hub, 0);
		return err;
	}

	hub->mode = USB4604_MODE_HUB;
	dev_dbg(dev, "switched to HUB mode\n");

	return 0;
}

static int usb4604_switch_mode(struct usb4604 *hub, enum usb4604_mode mode)
{
	struct device *dev = hub->dev;
	int err = 0;

	switch (mode) {
	case USB4604_MODE_HUB:
		err = usb4604_connect(hub);
		break;

	case USB4604_MODE_STANDBY:
		usb4604_reset(hub, 0);
		dev_dbg(dev, "switched to STANDBY mode\n");
		break;

	default:
		dev_err(dev, "unknown mode is requested\n");
		err = -EINVAL;
		break;
	}

	return err;
}

static int usb4604_probe(struct usb4604 *hub)
{
	struct device *dev = hub->dev;
	struct device_node *np = dev->of_node;
	struct gpio_desc *gpio;
	u32 mode = USB4604_MODE_HUB;

	gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(gpio))
		return PTR_ERR(gpio);
	hub->gpio_reset = gpio;

	if (of_property_read_u32(np, "initial-mode", &hub->mode))
		hub->mode = mode;

	return usb4604_switch_mode(hub, hub->mode);
}

static int usb4604_i2c_probe(struct i2c_client *i2c,
			     const struct i2c_device_id *id)
{
	struct usb4604 *hub;

	hub = devm_kzalloc(&i2c->dev, sizeof(*hub), GFP_KERNEL);
	if (!hub)
		return -ENOMEM;

	i2c_set_clientdata(i2c, hub);
	hub->dev = &i2c->dev;

	return usb4604_probe(hub);
}

#ifdef CONFIG_PM_SLEEP
static int usb4604_i2c_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct usb4604 *hub = i2c_get_clientdata(client);

	usb4604_switch_mode(hub, USB4604_MODE_STANDBY);

	return 0;
}

static int usb4604_i2c_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct usb4604 *hub = i2c_get_clientdata(client);

	usb4604_switch_mode(hub, hub->mode);

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(usb4604_i2c_pm_ops, usb4604_i2c_suspend,
		usb4604_i2c_resume);

static const struct i2c_device_id usb4604_id[] = {
	{ "usb4604", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, usb4604_id);

#ifdef CONFIG_OF
static const struct of_device_id usb4604_of_match[] = {
	{ .compatible = "smsc,usb4604" },
	{}
};
MODULE_DEVICE_TABLE(of, usb4604_of_match);
#endif

static struct i2c_driver usb4604_i2c_driver = {
	.driver = {
		.name = "usb4604",
		.pm = &usb4604_i2c_pm_ops,
		.of_match_table = of_match_ptr(usb4604_of_match),
	},
	.probe		= usb4604_i2c_probe,
	.id_table	= usb4604_id,
};
module_i2c_driver(usb4604_i2c_driver);

MODULE_DESCRIPTION("USB4604 USB HUB driver");
MODULE_LICENSE("GPL v2");
