Unverified Commit 5a043fd5 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: rt5677: Refactor GPIO and use

Merge series from Andy Shevchenko <andriy.shevchenko@linux.intel.com>:

The code can be simplified with refactored GPIO parts and with use of
device_get_match_data(). Besides that couple of additional changes,
one for maintenance and one for making IRQ domain agnostic (not being
pinned to OF).
parents 92f33bf1 ea1c1019
Loading
Loading
Loading
Loading
+38 −79
Original line number Diff line number Diff line
@@ -6,23 +6,21 @@
 * Author: Oder Chiou <oder_chiou@realtek.com>
 */

#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/firmware.h>
#include <linux/of_device.h>
#include <linux/property.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/workqueue.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -4717,50 +4715,34 @@ static int rt5677_set_bias_level(struct snd_soc_component *component,
	return 0;
}

static int rt5677_update_gpio_bits(struct rt5677_priv *rt5677, unsigned offset, int m, int v)
{
	unsigned int bank = offset / 5;
	unsigned int shift = (offset % 5) * 3;
	unsigned int reg = bank ? RT5677_GPIO_CTRL3 : RT5677_GPIO_CTRL2;

	return regmap_update_bits(rt5677->regmap, reg, m << shift, v << shift);
}

#ifdef CONFIG_GPIOLIB
static void rt5677_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct rt5677_priv *rt5677 = gpiochip_get_data(chip);
	int level = value ? RT5677_GPIOx_OUT_HI : RT5677_GPIOx_OUT_LO;
	int m = RT5677_GPIOx_OUT_MASK;

	switch (offset) {
	case RT5677_GPIO1 ... RT5677_GPIO5:
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
			0x1 << (offset * 3 + 1), !!value << (offset * 3 + 1));
		break;

	case RT5677_GPIO6:
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3,
			RT5677_GPIO6_OUT_MASK, !!value << RT5677_GPIO6_OUT_SFT);
		break;

	default:
		break;
	}
	rt5677_update_gpio_bits(rt5677, offset, m, level);
}

static int rt5677_gpio_direction_out(struct gpio_chip *chip,
				     unsigned offset, int value)
{
	struct rt5677_priv *rt5677 = gpiochip_get_data(chip);
	int level = value ? RT5677_GPIOx_OUT_HI : RT5677_GPIOx_OUT_LO;
	int m = RT5677_GPIOx_DIR_MASK | RT5677_GPIOx_OUT_MASK;
	int v = RT5677_GPIOx_DIR_OUT | level;

	switch (offset) {
	case RT5677_GPIO1 ... RT5677_GPIO5:
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
			0x3 << (offset * 3 + 1),
			(0x2 | !!value) << (offset * 3 + 1));
		break;

	case RT5677_GPIO6:
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3,
			RT5677_GPIO6_DIR_MASK | RT5677_GPIO6_OUT_MASK,
			RT5677_GPIO6_DIR_OUT | !!value << RT5677_GPIO6_OUT_SFT);
		break;

	default:
		break;
	}

	return 0;
	return rt5677_update_gpio_bits(rt5677, offset, m, v);
}

static int rt5677_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -4778,26 +4760,14 @@ static int rt5677_gpio_get(struct gpio_chip *chip, unsigned offset)
static int rt5677_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
	struct rt5677_priv *rt5677 = gpiochip_get_data(chip);
	int m = RT5677_GPIOx_DIR_MASK;
	int v = RT5677_GPIOx_DIR_IN;

	switch (offset) {
	case RT5677_GPIO1 ... RT5677_GPIO5:
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
			0x1 << (offset * 3 + 2), 0x0);
		break;

	case RT5677_GPIO6:
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3,
			RT5677_GPIO6_DIR_MASK, RT5677_GPIO6_DIR_IN);
		break;

	default:
		break;
	return rt5677_update_gpio_bits(rt5677, offset, m, v);
}

	return 0;
}

/** Configures the gpio as
/*
 * Configures the GPIO as
 *   0 - floating
 *   1 - pull down
 *   2 - pull up
@@ -5539,7 +5509,7 @@ static int rt5677_init_irq(struct i2c_client *i2c)
			RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);

	/* Ready to listen for interrupts */
	rt5677->domain = irq_domain_add_linear(i2c->dev.of_node,
	rt5677->domain = irq_domain_create_linear(dev_fwnode(&i2c->dev),
			RT5677_IRQ_NUM, &rt5677_domain_ops, rt5677);
	if (!rt5677->domain) {
		dev_err(&i2c->dev, "Failed to create IRQ domain\n");
@@ -5559,6 +5529,7 @@ static int rt5677_init_irq(struct i2c_client *i2c)

static int rt5677_i2c_probe(struct i2c_client *i2c)
{
	struct device *dev = &i2c->dev;
	struct rt5677_priv *rt5677;
	int ret;
	unsigned int val;
@@ -5573,21 +5544,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
	INIT_DELAYED_WORK(&rt5677->dsp_work, rt5677_dsp_work);
	i2c_set_clientdata(i2c, rt5677);

	if (i2c->dev.of_node) {
		const struct of_device_id *match_id;

		match_id = of_match_device(rt5677_of_match, &i2c->dev);
		if (match_id)
			rt5677->type = (enum rt5677_type)match_id->data;
	} else if (ACPI_HANDLE(&i2c->dev)) {
		const struct acpi_device_id *acpi_id;

		acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev);
		if (acpi_id)
			rt5677->type = (enum rt5677_type)acpi_id->driver_data;
	} else {
	rt5677->type = (enum rt5677_type)(uintptr_t)device_get_match_data(dev);
	if (rt5677->type == 0)
		return -EINVAL;
	}

	rt5677_read_device_properties(rt5677, &i2c->dev);

@@ -5673,9 +5632,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
		regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL2,
					RT5677_GPIO5_FUNC_MASK,
					RT5677_GPIO5_FUNC_DMIC);
		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
					RT5677_GPIO5_DIR_MASK,
					RT5677_GPIO5_DIR_OUT);
		rt5677_update_gpio_bits(rt5677, RT5677_GPIO5,
					RT5677_GPIOx_DIR_MASK,
					RT5677_GPIOx_DIR_OUT);
	}

	if (rt5677->pdata.micbias1_vdd_3v3)
@@ -5702,7 +5661,7 @@ static struct i2c_driver rt5677_i2c_driver = {
	.driver = {
		.name = RT5677_DRV_NAME,
		.of_match_table = rt5677_of_match,
		.acpi_match_table = ACPI_PTR(rt5677_acpi_match),
		.acpi_match_table = rt5677_acpi_match,
	},
	.probe    = rt5677_i2c_probe,
	.remove   = rt5677_i2c_remove,
+15 −77
Original line number Diff line number Diff line
@@ -1587,81 +1587,19 @@
#define RT5677_FUNC_MODE_DMIC_GPIO		(0x0 << 13)
#define RT5677_FUNC_MODE_JTAG			(0x1 << 13)

/* GPIO Control 2 (0xc1) */
#define RT5677_GPIO5_DIR_MASK			(0x1 << 14)
#define RT5677_GPIO5_DIR_SFT			14
#define RT5677_GPIO5_DIR_IN			(0x0 << 14)
#define RT5677_GPIO5_DIR_OUT			(0x1 << 14)
#define RT5677_GPIO5_OUT_MASK			(0x1 << 13)
#define RT5677_GPIO5_OUT_SFT			13
#define RT5677_GPIO5_OUT_LO			(0x0 << 13)
#define RT5677_GPIO5_OUT_HI			(0x1 << 13)
#define RT5677_GPIO5_P_MASK			(0x1 << 12)
#define RT5677_GPIO5_P_SFT			12
#define RT5677_GPIO5_P_NOR			(0x0 << 12)
#define RT5677_GPIO5_P_INV			(0x1 << 12)
#define RT5677_GPIO4_DIR_MASK			(0x1 << 11)
#define RT5677_GPIO4_DIR_SFT			11
#define RT5677_GPIO4_DIR_IN			(0x0 << 11)
#define RT5677_GPIO4_DIR_OUT			(0x1 << 11)
#define RT5677_GPIO4_OUT_MASK			(0x1 << 10)
#define RT5677_GPIO4_OUT_SFT			10
#define RT5677_GPIO4_OUT_LO			(0x0 << 10)
#define RT5677_GPIO4_OUT_HI			(0x1 << 10)
#define RT5677_GPIO4_P_MASK			(0x1 << 9)
#define RT5677_GPIO4_P_SFT			9
#define RT5677_GPIO4_P_NOR			(0x0 << 9)
#define RT5677_GPIO4_P_INV			(0x1 << 9)
#define RT5677_GPIO3_DIR_MASK			(0x1 << 8)
#define RT5677_GPIO3_DIR_SFT			8
#define RT5677_GPIO3_DIR_IN			(0x0 << 8)
#define RT5677_GPIO3_DIR_OUT			(0x1 << 8)
#define RT5677_GPIO3_OUT_MASK			(0x1 << 7)
#define RT5677_GPIO3_OUT_SFT			7
#define RT5677_GPIO3_OUT_LO			(0x0 << 7)
#define RT5677_GPIO3_OUT_HI			(0x1 << 7)
#define RT5677_GPIO3_P_MASK			(0x1 << 6)
#define RT5677_GPIO3_P_SFT			6
#define RT5677_GPIO3_P_NOR			(0x0 << 6)
#define RT5677_GPIO3_P_INV			(0x1 << 6)
#define RT5677_GPIO2_DIR_MASK			(0x1 << 5)
#define RT5677_GPIO2_DIR_SFT			5
#define RT5677_GPIO2_DIR_IN			(0x0 << 5)
#define RT5677_GPIO2_DIR_OUT			(0x1 << 5)
#define RT5677_GPIO2_OUT_MASK			(0x1 << 4)
#define RT5677_GPIO2_OUT_SFT			4
#define RT5677_GPIO2_OUT_LO			(0x0 << 4)
#define RT5677_GPIO2_OUT_HI			(0x1 << 4)
#define RT5677_GPIO2_P_MASK			(0x1 << 3)
#define RT5677_GPIO2_P_SFT			3
#define RT5677_GPIO2_P_NOR			(0x0 << 3)
#define RT5677_GPIO2_P_INV			(0x1 << 3)
#define RT5677_GPIO1_DIR_MASK			(0x1 << 2)
#define RT5677_GPIO1_DIR_SFT			2
#define RT5677_GPIO1_DIR_IN			(0x0 << 2)
#define RT5677_GPIO1_DIR_OUT			(0x1 << 2)
#define RT5677_GPIO1_OUT_MASK			(0x1 << 1)
#define RT5677_GPIO1_OUT_SFT			1
#define RT5677_GPIO1_OUT_LO			(0x0 << 1)
#define RT5677_GPIO1_OUT_HI			(0x1 << 1)
#define RT5677_GPIO1_P_MASK			(0x1 << 0)
#define RT5677_GPIO1_P_SFT			0
#define RT5677_GPIO1_P_NOR			(0x0 << 0)
#define RT5677_GPIO1_P_INV			(0x1 << 0)

/* GPIO Control 3 (0xc2) */
#define RT5677_GPIO6_DIR_MASK			(0x1 << 2)
#define RT5677_GPIO6_DIR_SFT			2
#define RT5677_GPIO6_DIR_IN			(0x0 << 2)
#define RT5677_GPIO6_DIR_OUT			(0x1 << 2)
#define RT5677_GPIO6_OUT_MASK			(0x1 << 1)
#define RT5677_GPIO6_OUT_SFT			1
#define RT5677_GPIO6_OUT_LO			(0x0 << 1)
#define RT5677_GPIO6_OUT_HI			(0x1 << 1)
#define RT5677_GPIO6_P_MASK			(0x1 << 0)
#define RT5677_GPIO6_P_SFT			0
#define RT5677_GPIO6_P_NOR			(0x0 << 0)
#define RT5677_GPIO6_P_INV			(0x1 << 0)
/* GPIO Control 2 (0xc1) & 3 (0xc2) common bits */
#define RT5677_GPIOx_DIR_MASK			(0x1 << 2)
#define RT5677_GPIOx_DIR_SFT			2
#define RT5677_GPIOx_DIR_IN			(0x0 << 2)
#define RT5677_GPIOx_DIR_OUT			(0x1 << 2)
#define RT5677_GPIOx_OUT_MASK			(0x1 << 1)
#define RT5677_GPIOx_OUT_SFT			1
#define RT5677_GPIOx_OUT_LO			(0x0 << 1)
#define RT5677_GPIOx_OUT_HI			(0x1 << 1)
#define RT5677_GPIOx_P_MASK			(0x1 << 0)
#define RT5677_GPIOx_P_SFT			0
#define RT5677_GPIOx_P_NOR			(0x0 << 0)
#define RT5677_GPIOx_P_INV			(0x1 << 0)

/* General Control (0xfa) */
#define RT5677_IRQ_DEBOUNCE_SEL_MASK		(0x3 << 3)
@@ -1753,8 +1691,8 @@ enum {
};

enum rt5677_type {
	RT5677,
	RT5676,
	RT5677 = 1,
	RT5676 = 2,
};

/* ASRC clock source selection */