Commit 5a043fd5 authored by Mark Brown's avatar Mark Brown

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
...@@ -6,23 +6,21 @@ ...@@ -6,23 +6,21 @@
* Author: Oder Chiou <oder_chiou@realtek.com> * 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/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/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/init.h> #include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/property.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.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 <linux/workqueue.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -4717,50 +4715,34 @@ static int rt5677_set_bias_level(struct snd_soc_component *component, ...@@ -4717,50 +4715,34 @@ static int rt5677_set_bias_level(struct snd_soc_component *component,
return 0; 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 #ifdef CONFIG_GPIOLIB
static void rt5677_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static void rt5677_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{ {
struct rt5677_priv *rt5677 = gpiochip_get_data(chip); 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) { rt5677_update_gpio_bits(rt5677, offset, m, level);
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;
}
} }
static int rt5677_gpio_direction_out(struct gpio_chip *chip, static int rt5677_gpio_direction_out(struct gpio_chip *chip,
unsigned offset, int value) unsigned offset, int value)
{ {
struct rt5677_priv *rt5677 = gpiochip_get_data(chip); 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) { return rt5677_update_gpio_bits(rt5677, offset, m, v);
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;
} }
static int rt5677_gpio_get(struct gpio_chip *chip, unsigned offset) 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) ...@@ -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) static int rt5677_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{ {
struct rt5677_priv *rt5677 = gpiochip_get_data(chip); struct rt5677_priv *rt5677 = gpiochip_get_data(chip);
int m = RT5677_GPIOx_DIR_MASK;
int v = RT5677_GPIOx_DIR_IN;
switch (offset) { return rt5677_update_gpio_bits(rt5677, offset, m, v);
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 0;
} }
/** Configures the gpio as /*
* Configures the GPIO as
* 0 - floating * 0 - floating
* 1 - pull down * 1 - pull down
* 2 - pull up * 2 - pull up
...@@ -5539,7 +5509,7 @@ static int rt5677_init_irq(struct i2c_client *i2c) ...@@ -5539,7 +5509,7 @@ static int rt5677_init_irq(struct i2c_client *i2c)
RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ); RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);
/* Ready to listen for interrupts */ /* 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); RT5677_IRQ_NUM, &rt5677_domain_ops, rt5677);
if (!rt5677->domain) { if (!rt5677->domain) {
dev_err(&i2c->dev, "Failed to create IRQ domain\n"); dev_err(&i2c->dev, "Failed to create IRQ domain\n");
...@@ -5559,6 +5529,7 @@ static int rt5677_init_irq(struct i2c_client *i2c) ...@@ -5559,6 +5529,7 @@ static int rt5677_init_irq(struct i2c_client *i2c)
static int rt5677_i2c_probe(struct i2c_client *i2c) static int rt5677_i2c_probe(struct i2c_client *i2c)
{ {
struct device *dev = &i2c->dev;
struct rt5677_priv *rt5677; struct rt5677_priv *rt5677;
int ret; int ret;
unsigned int val; unsigned int val;
...@@ -5573,21 +5544,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c) ...@@ -5573,21 +5544,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
INIT_DELAYED_WORK(&rt5677->dsp_work, rt5677_dsp_work); INIT_DELAYED_WORK(&rt5677->dsp_work, rt5677_dsp_work);
i2c_set_clientdata(i2c, rt5677); i2c_set_clientdata(i2c, rt5677);
if (i2c->dev.of_node) { rt5677->type = (enum rt5677_type)(uintptr_t)device_get_match_data(dev);
const struct of_device_id *match_id; if (rt5677->type == 0)
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 {
return -EINVAL; return -EINVAL;
}
rt5677_read_device_properties(rt5677, &i2c->dev); rt5677_read_device_properties(rt5677, &i2c->dev);
...@@ -5673,9 +5632,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c) ...@@ -5673,9 +5632,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL2, regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL2,
RT5677_GPIO5_FUNC_MASK, RT5677_GPIO5_FUNC_MASK,
RT5677_GPIO5_FUNC_DMIC); RT5677_GPIO5_FUNC_DMIC);
regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2, rt5677_update_gpio_bits(rt5677, RT5677_GPIO5,
RT5677_GPIO5_DIR_MASK, RT5677_GPIOx_DIR_MASK,
RT5677_GPIO5_DIR_OUT); RT5677_GPIOx_DIR_OUT);
} }
if (rt5677->pdata.micbias1_vdd_3v3) if (rt5677->pdata.micbias1_vdd_3v3)
...@@ -5702,7 +5661,7 @@ static struct i2c_driver rt5677_i2c_driver = { ...@@ -5702,7 +5661,7 @@ static struct i2c_driver rt5677_i2c_driver = {
.driver = { .driver = {
.name = RT5677_DRV_NAME, .name = RT5677_DRV_NAME,
.of_match_table = rt5677_of_match, .of_match_table = rt5677_of_match,
.acpi_match_table = ACPI_PTR(rt5677_acpi_match), .acpi_match_table = rt5677_acpi_match,
}, },
.probe = rt5677_i2c_probe, .probe = rt5677_i2c_probe,
.remove = rt5677_i2c_remove, .remove = rt5677_i2c_remove,
......
...@@ -1587,81 +1587,19 @@ ...@@ -1587,81 +1587,19 @@
#define RT5677_FUNC_MODE_DMIC_GPIO (0x0 << 13) #define RT5677_FUNC_MODE_DMIC_GPIO (0x0 << 13)
#define RT5677_FUNC_MODE_JTAG (0x1 << 13) #define RT5677_FUNC_MODE_JTAG (0x1 << 13)
/* GPIO Control 2 (0xc1) */ /* GPIO Control 2 (0xc1) & 3 (0xc2) common bits */
#define RT5677_GPIO5_DIR_MASK (0x1 << 14) #define RT5677_GPIOx_DIR_MASK (0x1 << 2)
#define RT5677_GPIO5_DIR_SFT 14 #define RT5677_GPIOx_DIR_SFT 2
#define RT5677_GPIO5_DIR_IN (0x0 << 14) #define RT5677_GPIOx_DIR_IN (0x0 << 2)
#define RT5677_GPIO5_DIR_OUT (0x1 << 14) #define RT5677_GPIOx_DIR_OUT (0x1 << 2)
#define RT5677_GPIO5_OUT_MASK (0x1 << 13) #define RT5677_GPIOx_OUT_MASK (0x1 << 1)
#define RT5677_GPIO5_OUT_SFT 13 #define RT5677_GPIOx_OUT_SFT 1
#define RT5677_GPIO5_OUT_LO (0x0 << 13) #define RT5677_GPIOx_OUT_LO (0x0 << 1)
#define RT5677_GPIO5_OUT_HI (0x1 << 13) #define RT5677_GPIOx_OUT_HI (0x1 << 1)
#define RT5677_GPIO5_P_MASK (0x1 << 12) #define RT5677_GPIOx_P_MASK (0x1 << 0)
#define RT5677_GPIO5_P_SFT 12 #define RT5677_GPIOx_P_SFT 0
#define RT5677_GPIO5_P_NOR (0x0 << 12) #define RT5677_GPIOx_P_NOR (0x0 << 0)
#define RT5677_GPIO5_P_INV (0x1 << 12) #define RT5677_GPIOx_P_INV (0x1 << 0)
#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)
/* General Control (0xfa) */ /* General Control (0xfa) */
#define RT5677_IRQ_DEBOUNCE_SEL_MASK (0x3 << 3) #define RT5677_IRQ_DEBOUNCE_SEL_MASK (0x3 << 3)
...@@ -1753,8 +1691,8 @@ enum { ...@@ -1753,8 +1691,8 @@ enum {
}; };
enum rt5677_type { enum rt5677_type {
RT5677, RT5677 = 1,
RT5676, RT5676 = 2,
}; };
/* ASRC clock source selection */ /* ASRC clock source selection */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment