Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13ca4f66 authored by Paul Parsons's avatar Paul Parsons Committed by Samuel Ortiz
Browse files

mfd: Add ASIC3 LED support



Add LED support for the HTC ASIC3. Underlying support is provided by the mfd/asic3 and leds/leds-asic3 drivers. An example configuration is provided by the pxa/hx4700 platform.

Signed-off-by: default avatarPaul Parsons <lost.distance@yahoo.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 7d9e7e9f
Loading
Loading
Loading
Loading
+68 −6
Original line number Diff line number Diff line
@@ -88,19 +88,19 @@ struct asic3 {

static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset);

static inline void asic3_write_register(struct asic3 *asic,
				 unsigned int reg, u32 value)
void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 value)
{
	iowrite16(value, asic->mapping +
		  (reg >> asic->bus_shift));
}
EXPORT_SYMBOL_GPL(asic3_write_register);

static inline u32 asic3_read_register(struct asic3 *asic,
			       unsigned int reg)
u32 asic3_read_register(struct asic3 *asic, unsigned int reg)
{
	return ioread16(asic->mapping +
			(reg >> asic->bus_shift));
}
EXPORT_SYMBOL_GPL(asic3_read_register);

static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set)
{
@@ -784,7 +784,55 @@ static struct mfd_cell asic3_cell_mmc = {
	.resources     = asic3_mmc_resources,
};

static const int clock_ledn[ASIC3_NUM_LEDS] = {
	[0] = ASIC3_CLOCK_LED0,
	[1] = ASIC3_CLOCK_LED1,
	[2] = ASIC3_CLOCK_LED2,
};

static int asic3_leds_enable(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);

	asic3_clk_enable(asic, &asic->clocks[clock_ledn[cell->id]]);

	return 0;
}

static int asic3_leds_disable(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);

	asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]);

	return 0;
}

static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = {
	[0] = {
		.name          = "leds-asic3",
		.id            = 0,
		.enable        = asic3_leds_enable,
		.disable       = asic3_leds_disable,
	},
	[1] = {
		.name          = "leds-asic3",
		.id            = 1,
		.enable        = asic3_leds_enable,
		.disable       = asic3_leds_disable,
	},
	[2] = {
		.name          = "leds-asic3",
		.id            = 2,
		.enable        = asic3_leds_enable,
		.disable       = asic3_leds_disable,
	},
};

static int __init asic3_mfd_probe(struct platform_device *pdev,
				  struct asic3_platform_data *pdata,
				  struct resource *mem)
{
	struct asic3 *asic = platform_get_drvdata(pdev);
@@ -822,9 +870,23 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
	if (ret < 0)
		goto out;

	if (mem_sdio && (irq >= 0))
	if (mem_sdio && (irq >= 0)) {
		ret = mfd_add_devices(&pdev->dev, pdev->id,
			&asic3_cell_mmc, 1, mem_sdio, irq);
		if (ret < 0)
			goto out;
	}

	if (pdata->leds) {
		int i;

		for (i = 0; i < ASIC3_NUM_LEDS; ++i) {
			asic3_cell_leds[i].platform_data = &pdata->leds[i];
			asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);
		}
		ret = mfd_add_devices(&pdev->dev, 0,
			asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0);
	}

 out:
	return ret;
@@ -905,7 +967,7 @@ static int __init asic3_probe(struct platform_device *pdev)
	 */
	memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init));

	asic3_mfd_probe(pdev, mem);
	asic3_mfd_probe(pdev, pdata, mem);

	dev_info(asic->dev, "ASIC3 Core driver\n");