// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Lightning Mountain SoC LED Serial Shift Output Controller driver
 *
 * Copyright (c) 2020 Intel Corporation.
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/sizes.h>
#include <linux/uaccess.h>

#define SSO_DEV_NAME			"lgm-sso"

#define LED_BLINK_H8_0			0x0
#define LED_BLINK_H8_1			0x4
#define GET_FREQ_OFFSET(pin, src)	(((pin) * 6) + ((src) * 2))
#define GET_SRC_OFFSET(pinc)		(((pin) * 6) + 4)

#define DUTY_CYCLE(x)			(0x8 + ((x) * 4))
#define SSO_CON0			0x2B0
#define SSO_CON0_RZFL			BIT(26)
#define SSO_CON0_BLINK_R		BIT(30)
#define SSO_CON0_SWU			BIT(31)

#define SSO_CON1			0x2B4
#define SSO_CON1_FCDSC			GENMASK(21, 20) /* Fixed Divider Shift Clock */
#define SSO_CON1_FPID			GENMASK(24, 23)
#define SSO_CON1_GPTD			GENMASK(26, 25)
#define SSO_CON1_US			GENMASK(31, 30)

#define SSO_CPU				0x2B8
#define SSO_CON2			0x2C4
#define SSO_CON3			0x2C8

/* Driver MACRO */
#define MAX_PIN_NUM_PER_BANK		SZ_32
#define MAX_GROUP_NUM			SZ_4
#define PINS_PER_GROUP			SZ_8
#define FPID_FREQ_RANK_MAX		SZ_4
#define SSO_LED_MAX_NUM			SZ_32
#define MAX_FREQ_RANK			10
#define DEF_GPTC_CLK_RATE		200000000
#define SSO_DEF_BRIGHTNESS		LED_HALF
#define DATA_CLK_EDGE			0 /* 0-rising, 1-falling */

static const u32 freq_div_tbl[] = {4000, 2000, 1000, 800};
static const int freq_tbl[] = {2, 4, 8, 10, 50000, 100000, 200000, 250000};
static const int shift_clk_freq_tbl[] = {25000000, 12500000, 6250000, 3125000};

/*
 * Update Source to update the SOUTs
 * SW - Software has to update the SWU bit
 * GPTC - General Purpose timer is used as clock source
 * FPID - Divided FSC clock (FPID) is used as clock source
 */
enum {
	US_SW = 0,
	US_GPTC = 1,
	US_FPID = 2
};

enum {
	MAX_FPID_FREQ_RANK = 5, /* 1 to 4 */
	MAX_GPTC_FREQ_RANK = 9, /* 5 to 8 */
	MAX_GPTC_HS_FREQ_RANK = 10, /* 9 to 10 */
};

enum {
	LED_GRP0_PIN_MAX = 24,
	LED_GRP1_PIN_MAX = 29,
	LED_GRP2_PIN_MAX = 32,
};

enum {
	LED_GRP0_0_23,
	LED_GRP1_24_28,
	LED_GRP2_29_31,
	LED_GROUP_MAX,
};

enum {
	CLK_SRC_FPID = 0,
	CLK_SRC_GPTC = 1,
	CLK_SRC_GPTC_HS = 2,
};

struct sso_led_priv;

struct sso_led_desc {
	const char *name;
	const char *default_trigger;
	unsigned int brightness;
	unsigned int blink_rate;
	unsigned int retain_state_suspended:1;
	unsigned int retain_state_shutdown:1;
	unsigned int panic_indicator:1;
	unsigned int hw_blink:1;
	unsigned int hw_trig:1;
	unsigned int blinking:1;
	int freq_idx;
	u32 pin;
};

struct sso_led {
	struct list_head list;
	struct led_classdev cdev;
	struct gpio_desc *gpiod;
	struct sso_led_desc desc;
	struct sso_led_priv *priv;
};

struct sso_gpio {
	struct gpio_chip chip;
	int shift_clk_freq;
	int edge;
	int freq;
	u32 pins;
	u32 alloc_bitmap;
};

struct sso_led_priv {
	struct regmap *mmap;
	struct device *dev;
	struct platform_device *pdev;
	struct clk_bulk_data clocks[2];
	u32 fpid_clkrate;
	u32 gptc_clkrate;
	u32 freq[MAX_FREQ_RANK];
	struct list_head led_list;
	struct sso_gpio gpio;
};

static int sso_get_blink_rate_idx(struct sso_led_priv *priv, u32 rate)
{
	int i;

	for (i = 0; i < MAX_FREQ_RANK; i++) {
		if (rate <= priv->freq[i])
			return i;
	}

	return -1;
}

static unsigned int sso_led_pin_to_group(u32 pin)
{
	if (pin < LED_GRP0_PIN_MAX)
		return LED_GRP0_0_23;
	else if (pin < LED_GRP1_PIN_MAX)
		return LED_GRP1_24_28;
	else
		return LED_GRP2_29_31;
}

static u32 sso_led_get_freq_src(int freq_idx)
{
	if (freq_idx < MAX_FPID_FREQ_RANK)
		return CLK_SRC_FPID;
	else if (freq_idx < MAX_GPTC_FREQ_RANK)
		return CLK_SRC_GPTC;
	else
		return CLK_SRC_GPTC_HS;
}

static u32 sso_led_pin_blink_off(u32 pin, unsigned int group)
{
	if (group == LED_GRP2_29_31)
		return pin - LED_GRP1_PIN_MAX;
	else if (group == LED_GRP1_24_28)
		return pin - LED_GRP0_PIN_MAX;
	else	/* led 0 - 23 in led 32 location */
		return SSO_LED_MAX_NUM - LED_GRP1_PIN_MAX;
}

static struct sso_led
*cdev_to_sso_led_data(struct led_classdev *led_cdev)
{
	return container_of(led_cdev, struct sso_led, cdev);
}

static void sso_led_freq_set(struct sso_led_priv *priv, u32 pin, int freq_idx)
{
	u32 reg, off, freq_src, val_freq;
	u32 low, high, val;
	unsigned int group;

	if (!freq_idx)
		return;

	group = sso_led_pin_to_group(pin);
	freq_src = sso_led_get_freq_src(freq_idx);
	off = sso_led_pin_blink_off(pin, group);

	if (group == LED_GRP0_0_23)
		return;
	else if (group == LED_GRP1_24_28)
		reg = LED_BLINK_H8_0;
	else
		reg = LED_BLINK_H8_1;

	if (freq_src == CLK_SRC_FPID)
		val_freq = freq_idx - 1;
	else if (freq_src == CLK_SRC_GPTC)
		val_freq = freq_idx - MAX_FPID_FREQ_RANK;

	/* set blink rate idx */
	if (freq_src != CLK_SRC_GPTC_HS) {
		low = GET_FREQ_OFFSET(off, freq_src);
		high = low + 2;
		val = val_freq << high;
		regmap_update_bits(priv->mmap, reg, GENMASK(high, low), val);
	}

	/* select clock source */
	low = GET_SRC_OFFSET(off);
	high = low + 2;
	val = freq_src << high;
	regmap_update_bits(priv->mmap, reg, GENMASK(high, low), val);
}

static void sso_led_brightness_set(struct led_classdev *led_cdev,
				   enum led_brightness brightness)
{
	struct sso_led_priv *priv;
	struct sso_led_desc *desc;
	struct sso_led *led;
	int val;

	led = cdev_to_sso_led_data(led_cdev);
	priv = led->priv;
	desc = &led->desc;

	desc->brightness = brightness;
	regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), brightness);

	if (brightness == LED_OFF)
		val = 0;
	else
		val = 1;

	/* HW blink off */
	if (desc->hw_blink && !val && desc->blinking) {
		desc->blinking = 0;
		regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin), 0);
	} else if (desc->hw_blink && val && !desc->blinking) {
		desc->blinking = 1;
		regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin),
				   1 << desc->pin);
	}

	if (!desc->hw_trig)
		gpiod_set_value(led->gpiod, val);
}

static enum led_brightness sso_led_brightness_get(struct led_classdev *led_cdev)
{
	struct sso_led *led = cdev_to_sso_led_data(led_cdev);

	return (enum led_brightness)led->desc.brightness;
}

static int
delay_to_freq_idx(struct sso_led *led, unsigned long *delay_on,
		  unsigned long *delay_off)
{
	struct sso_led_priv *priv = led->priv;
	unsigned long delay;
	int freq_idx;
	u32 freq;

	if (!*delay_on && !*delay_off) {
		*delay_on = *delay_off = (1000 / priv->freq[0]) / 2;
		return 0;
	}

	delay = *delay_on + *delay_off;
	freq = 1000 / delay;

	freq_idx = sso_get_blink_rate_idx(priv, freq);
	if (freq_idx == -1)
		freq_idx = MAX_FREQ_RANK - 1;

	delay = 1000 / priv->freq[freq_idx];
	*delay_on = *delay_off = delay / 2;

	if (!*delay_on)
		*delay_on = *delay_off = 1;

	return freq_idx;
}

static int
sso_led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on,
		  unsigned long *delay_off)
{
	struct sso_led_priv *priv;
	struct sso_led *led;
	int freq_idx;

	led = cdev_to_sso_led_data(led_cdev);
	priv = led->priv;
	freq_idx = delay_to_freq_idx(led, delay_on, delay_off);

	sso_led_freq_set(priv, led->desc.pin, freq_idx);
	regmap_update_bits(priv->mmap, SSO_CON2, BIT(led->desc.pin),
			   1 << led->desc.pin);
	led->desc.freq_idx = freq_idx;
	led->desc.blink_rate = priv->freq[freq_idx];
	led->desc.blinking = 1;

	return 1;
}

static void sso_led_hw_cfg(struct sso_led_priv *priv, struct sso_led *led)
{
	struct sso_led_desc *desc = &led->desc;

	/* set freq */
	if (desc->hw_blink) {
		sso_led_freq_set(priv, desc->pin, desc->freq_idx);
		regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin),
				   1 << desc->pin);
	}

	if (desc->hw_trig)
		regmap_update_bits(priv->mmap, SSO_CON3, BIT(desc->pin),
				   1 << desc->pin);

	/* set brightness */
	regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), desc->brightness);

	/* enable output */
	if (!desc->hw_trig && desc->brightness)
		gpiod_set_value(led->gpiod, 1);
}

static int sso_create_led(struct sso_led_priv *priv, struct sso_led *led,
			  struct fwnode_handle *child)
{
	struct sso_led_desc *desc = &led->desc;
	struct led_init_data init_data;
	int err;

	init_data.fwnode = child;
	init_data.devicename = SSO_DEV_NAME;
	init_data.default_label = ":";

	led->cdev.default_trigger = desc->default_trigger;
	led->cdev.brightness_set = sso_led_brightness_set;
	led->cdev.brightness_get = sso_led_brightness_get;
	led->cdev.brightness = desc->brightness;
	led->cdev.max_brightness = LED_FULL;

	if (desc->retain_state_shutdown)
		led->cdev.flags |= LED_RETAIN_AT_SHUTDOWN;
	if (desc->retain_state_suspended)
		led->cdev.flags |= LED_CORE_SUSPENDRESUME;
	if (desc->panic_indicator)
		led->cdev.flags |= LED_PANIC_INDICATOR;

	if (desc->hw_blink)
		led->cdev.blink_set = sso_led_blink_set;

	sso_led_hw_cfg(priv, led);

	err = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
	if (err)
		return err;

	list_add(&led->list, &priv->led_list);

	return 0;
}

static void sso_init_freq(struct sso_led_priv *priv)
{
	int i;

	priv->freq[0] = 0;
	for (i = 1; i < MAX_FREQ_RANK; i++) {
		if (i < MAX_FPID_FREQ_RANK) {
			priv->freq[i] = priv->fpid_clkrate / freq_div_tbl[i - 1];
		} else if (i < MAX_GPTC_FREQ_RANK) {
			priv->freq[i] = priv->gptc_clkrate /
				freq_div_tbl[i - MAX_FPID_FREQ_RANK];
		} else if (i < MAX_GPTC_HS_FREQ_RANK) {
			priv->freq[i] = priv->gptc_clkrate;
		}
	}
}

static int sso_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
	struct sso_led_priv *priv = gpiochip_get_data(chip);

	if (priv->gpio.alloc_bitmap & BIT(offset))
		return -EINVAL;

	priv->gpio.alloc_bitmap |= BIT(offset);
	regmap_write(priv->mmap, DUTY_CYCLE(offset), 0xFF);

	return 0;
}

static void sso_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
	struct sso_led_priv *priv = gpiochip_get_data(chip);

	priv->gpio.alloc_bitmap &= ~BIT(offset);
	regmap_write(priv->mmap, DUTY_CYCLE(offset), 0x0);
}

static int sso_gpio_get_dir(struct gpio_chip *chip, unsigned int offset)
{
	return GPIO_LINE_DIRECTION_OUT;
}

static int
sso_gpio_dir_out(struct gpio_chip *chip, unsigned int offset, int value)
{
	struct sso_led_priv *priv = gpiochip_get_data(chip);
	bool bit = !!value;

	regmap_update_bits(priv->mmap, SSO_CPU, BIT(offset), bit << offset);
	if (!priv->gpio.freq)
		regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_SWU,
				   SSO_CON0_SWU);

	return 0;
}

static int sso_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct sso_led_priv *priv = gpiochip_get_data(chip);
	u32 reg_val;

	regmap_read(priv->mmap, SSO_CPU, &reg_val);

	return !!(reg_val & BIT(offset));
}

static void sso_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
	struct sso_led_priv *priv = gpiochip_get_data(chip);

	regmap_update_bits(priv->mmap, SSO_CPU, BIT(offset), value << offset);
	if (!priv->gpio.freq)
		regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_SWU,
				   SSO_CON0_SWU);
}

static int sso_gpio_gc_init(struct device *dev, struct sso_led_priv *priv)
{
	struct gpio_chip *gc = &priv->gpio.chip;

	gc->request             = sso_gpio_request;
	gc->free                = sso_gpio_free;
	gc->get_direction       = sso_gpio_get_dir;
	gc->direction_output    = sso_gpio_dir_out;
	gc->get                 = sso_gpio_get;
	gc->set                 = sso_gpio_set;

	gc->label               = "lgm-sso";
	gc->base                = -1;
	/* To exclude pins from control, use "gpio-reserved-ranges" */
	gc->ngpio               = priv->gpio.pins;
	gc->parent              = dev;
	gc->owner               = THIS_MODULE;
	gc->of_node             = dev->of_node;

	return devm_gpiochip_add_data(dev, gc, priv);
}

static int sso_gpio_get_freq_idx(int freq)
{
	int idx;

	for (idx = 0; idx < ARRAY_SIZE(freq_tbl); idx++) {
		if (freq <= freq_tbl[idx])
			return idx;
	}

	return -1;
}

static void sso_register_shift_clk(struct sso_led_priv *priv)
{
	int idx, size = ARRAY_SIZE(shift_clk_freq_tbl);
	u32 val = 0;

	for (idx = 0; idx < size; idx++) {
		if (shift_clk_freq_tbl[idx] <= priv->gpio.shift_clk_freq) {
			val = idx;
			break;
		}
	}

	if (idx == size)
		dev_warn(priv->dev, "%s: Invalid freq %d\n",
			 __func__, priv->gpio.shift_clk_freq);

	regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_FCDSC,
			   FIELD_PREP(SSO_CON1_FCDSC, val));
}

static int sso_gpio_freq_set(struct sso_led_priv *priv)
{
	int freq_idx;
	u32 val;

	freq_idx = sso_gpio_get_freq_idx(priv->gpio.freq);
	if (freq_idx == -1)
		freq_idx = ARRAY_SIZE(freq_tbl) - 1;

	val = freq_idx % FPID_FREQ_RANK_MAX;

	if (!priv->gpio.freq) {
		regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R, 0);
		regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US,
				   FIELD_PREP(SSO_CON1_US, US_SW));
	} else if (freq_idx < FPID_FREQ_RANK_MAX) {
		regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R,
				   SSO_CON0_BLINK_R);
		regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US,
				   FIELD_PREP(SSO_CON1_US, US_FPID));
		regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_FPID,
				   FIELD_PREP(SSO_CON1_FPID, val));
	} else {
		regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R,
				   SSO_CON0_BLINK_R);
		regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US,
				   FIELD_PREP(SSO_CON1_US, US_GPTC));
		regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_GPTD,
				   FIELD_PREP(SSO_CON1_GPTD, val));
	}

	return 0;
}

static int sso_gpio_hw_init(struct sso_led_priv *priv)
{
	u32 activate;
	int i, err;

	/* Clear all duty cycles */
	for (i = 0; i < priv->gpio.pins; i++) {
		err = regmap_write(priv->mmap, DUTY_CYCLE(i), 0);
		if (err)
			return err;
	}

	/* 4 groups for total 32 pins */
	for (i = 1; i <= MAX_GROUP_NUM; i++) {
		activate = !!(i * PINS_PER_GROUP <= priv->gpio.pins ||
			      priv->gpio.pins > (i - 1) * PINS_PER_GROUP);
		err = regmap_update_bits(priv->mmap, SSO_CON1, BIT(i - 1),
					 activate << (i - 1));
		if (err)
			return err;
	}

	/* NO HW directly controlled pin by default */
	err = regmap_write(priv->mmap, SSO_CON3, 0);
	if (err)
		return err;

	/* NO BLINK for all pins */
	err = regmap_write(priv->mmap, SSO_CON2, 0);
	if (err)
		return err;

	/* OUTPUT 0 by default */
	err = regmap_write(priv->mmap, SSO_CPU, 0);
	if (err)
		return err;

	/* update edge */
	err = regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_RZFL,
				 FIELD_PREP(SSO_CON0_RZFL, priv->gpio.edge));
	if (err)
		return err;

	/* Set GPIO update rate */
	sso_gpio_freq_set(priv);

	/* Register shift clock */
	sso_register_shift_clk(priv);

	return 0;
}

static void sso_led_shutdown(struct sso_led *led)
{
	struct sso_led_priv *priv = led->priv;

	/* unregister led */
	devm_led_classdev_unregister(priv->dev, &led->cdev);

	/* clear HW control bit */
	if (led->desc.hw_trig)
		regmap_update_bits(priv->mmap, SSO_CON3, BIT(led->desc.pin), 0);

	led->priv = NULL;
}

static int
__sso_led_dt_parse(struct sso_led_priv *priv, struct fwnode_handle *fw_ssoled)
{
	struct fwnode_handle *fwnode_child;
	struct device *dev = priv->dev;
	struct sso_led_desc *desc;
	struct sso_led *led;
	const char *tmp;
	u32 prop;
	int ret;

	fwnode_for_each_child_node(fw_ssoled, fwnode_child) {
		led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
		if (!led) {
			ret = -ENOMEM;
			goto __dt_err;
		}

		INIT_LIST_HEAD(&led->list);
		led->priv = priv;
		desc = &led->desc;

		led->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL,
							      fwnode_child,
							      GPIOD_ASIS, NULL);
		if (IS_ERR(led->gpiod)) {
			ret = dev_err_probe(dev, PTR_ERR(led->gpiod), "led: get gpio fail!\n");
			goto __dt_err;
		}

		fwnode_property_read_string(fwnode_child,
					    "linux,default-trigger",
					    &desc->default_trigger);

		if (fwnode_property_present(fwnode_child,
					    "retain-state-suspended"))
			desc->retain_state_suspended = 1;

		if (fwnode_property_present(fwnode_child,
					    "retain-state-shutdown"))
			desc->retain_state_shutdown = 1;

		if (fwnode_property_present(fwnode_child, "panic-indicator"))
			desc->panic_indicator = 1;

		ret = fwnode_property_read_u32(fwnode_child, "reg", &prop);
		if (ret)
			goto __dt_err;
		if (prop >= SSO_LED_MAX_NUM) {
			dev_err(dev, "invalid LED pin:%u\n", prop);
			ret = -EINVAL;
			goto __dt_err;
		}
		desc->pin = prop;

		if (fwnode_property_present(fwnode_child, "intel,sso-hw-blink"))
			desc->hw_blink = 1;

		desc->hw_trig = fwnode_property_read_bool(fwnode_child,
							  "intel,sso-hw-trigger");
		if (desc->hw_trig) {
			desc->default_trigger = NULL;
			desc->retain_state_shutdown = 0;
			desc->retain_state_suspended = 0;
			desc->panic_indicator = 0;
			desc->hw_blink = 0;
		}

		if (fwnode_property_read_u32(fwnode_child,
					     "intel,sso-blink-rate-hz", &prop)) {
			/* default first freq rate */
			desc->freq_idx = 0;
			desc->blink_rate = priv->freq[desc->freq_idx];
		} else {
			desc->freq_idx = sso_get_blink_rate_idx(priv, prop);
			if (desc->freq_idx == -1)
				desc->freq_idx = MAX_FREQ_RANK - 1;

			desc->blink_rate = priv->freq[desc->freq_idx];
		}

		if (!fwnode_property_read_string(fwnode_child, "default-state", &tmp)) {
			if (!strcmp(tmp, "on"))
				desc->brightness = LED_FULL;
		}

		ret = sso_create_led(priv, led, fwnode_child);
		if (ret)
			goto __dt_err;
	}

	return 0;

__dt_err:
	fwnode_handle_put(fwnode_child);
	/* unregister leds */
	list_for_each_entry(led, &priv->led_list, list)
		sso_led_shutdown(led);

	return ret;
}

static int sso_led_dt_parse(struct sso_led_priv *priv)
{
	struct fwnode_handle *fwnode = dev_fwnode(priv->dev);
	struct fwnode_handle *fw_ssoled;
	struct device *dev = priv->dev;
	int count;
	int ret;

	count = device_get_child_node_count(dev);
	if (!count)
		return 0;

	fw_ssoled = fwnode_get_named_child_node(fwnode, "ssoled");
	if (fw_ssoled) {
		ret = __sso_led_dt_parse(priv, fw_ssoled);
		fwnode_handle_put(fw_ssoled);
		if (ret)
			return ret;
	}

	return 0;
}

static int sso_probe_gpios(struct sso_led_priv *priv)
{
	struct device *dev = priv->dev;
	int ret;

	if (device_property_read_u32(dev, "ngpios", &priv->gpio.pins))
		priv->gpio.pins = MAX_PIN_NUM_PER_BANK;

	if (priv->gpio.pins > MAX_PIN_NUM_PER_BANK)
		return -EINVAL;

	if (device_property_read_u32(dev, "intel,sso-update-rate-hz",
				     &priv->gpio.freq))
		priv->gpio.freq = 0;

	priv->gpio.edge = DATA_CLK_EDGE;
	priv->gpio.shift_clk_freq = -1;

	ret = sso_gpio_hw_init(priv);
	if (ret)
		return ret;

	return sso_gpio_gc_init(dev, priv);
}

static void sso_clock_disable_unprepare(void *data)
{
	struct sso_led_priv *priv = data;

	clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
}

static int intel_sso_led_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sso_led_priv *priv;
	int ret;

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

	priv->pdev = pdev;
	priv->dev = dev;

	/* gate clock */
	priv->clocks[0].id = "sso";

	/* fpid clock */
	priv->clocks[1].id = "fpid";

	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), priv->clocks);
	if (ret) {
		dev_err(dev, "Getting clocks failed!\n");
		return ret;
	}

	ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
	if (ret) {
		dev_err(dev, "Failed to prepare and enable clocks!\n");
		return ret;
	}

	ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv);
	if (ret)
		return ret;

	priv->fpid_clkrate = clk_get_rate(priv->clocks[1].clk);

	priv->mmap = syscon_node_to_regmap(dev->of_node);

	priv->mmap = syscon_node_to_regmap(dev->of_node);
	if (IS_ERR(priv->mmap)) {
		dev_err(dev, "Failed to map iomem!\n");
		return PTR_ERR(priv->mmap);
	}

	ret = sso_probe_gpios(priv);
	if (ret) {
		regmap_exit(priv->mmap);
		return ret;
	}

	INIT_LIST_HEAD(&priv->led_list);

	platform_set_drvdata(pdev, priv);
	sso_init_freq(priv);

	priv->gptc_clkrate = DEF_GPTC_CLK_RATE;

	ret = sso_led_dt_parse(priv);
	if (ret) {
		regmap_exit(priv->mmap);
		return ret;
	}
	dev_info(priv->dev, "sso LED init success!\n");

	return 0;
}

static int intel_sso_led_remove(struct platform_device *pdev)
{
	struct sso_led_priv *priv;
	struct sso_led *led, *n;

	priv = platform_get_drvdata(pdev);

	list_for_each_entry_safe(led, n, &priv->led_list, list) {
		list_del(&led->list);
		sso_led_shutdown(led);
	}

	regmap_exit(priv->mmap);

	return 0;
}

static const struct of_device_id of_sso_led_match[] = {
	{ .compatible = "intel,lgm-ssoled" },
	{}
};

MODULE_DEVICE_TABLE(of, of_sso_led_match);

static struct platform_driver intel_sso_led_driver = {
	.probe		= intel_sso_led_probe,
	.remove		= intel_sso_led_remove,
	.driver		= {
			.name = "lgm-ssoled",
			.of_match_table = of_sso_led_match,
	},
};

module_platform_driver(intel_sso_led_driver);

MODULE_DESCRIPTION("Intel SSO LED/GPIO driver");
MODULE_LICENSE("GPL v2");
