diff mbox series

[v2,3/5] mfd: arizona: Add support for ACPI enumeration of WM5102 connected over SPI

Message ID 20210117154717.77969-4-hdegoede@redhat.com (mailing list archive)
State Superseded
Headers show
Series MFD/ASoC: Add support for Intel Bay Trail boards with WM5102 codec | expand

Commit Message

Hans de Goede Jan. 17, 2021, 3:47 p.m. UTC
The Intel Bay Trail (x86/ACPI) based Lenovo Yoga Tablet 2 series use
a WM5102 codec connected over SPI.

Add support for ACPI enumeration to arizona-spi so that arizona-spi can
bind to the codec on these tablets.

This is loosely based on an earlier attempt (for Android-x86) at this by
Christian Hartmann, combined with insights in things like the speaker GPIO
from the android-x86 android port for the Lenovo Yoga Tablet 2 1051F/L [1].

[1] https://github.com/Kitsune2222/Android_Yoga_Tablet_2-1051F_Kernel

Cc: Christian Hartmann <cornogle@googlemail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
- Minor coding style tweaks
- Use memcpy instead of for loop to copy gpiod_lookup-s
- Log a warning when the ACPI "CLKE" call fails
- Drop addition of acpi_device_get_match_data() call, as the code was
  moved over to use the generic device_get_match_data() helper in a
  (new in v2) preparation patch
---
 drivers/mfd/arizona-spi.c | 120 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

Comments

kernel test robot Jan. 17, 2021, 7:06 p.m. UTC | #1
Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on lee-mfd/for-mfd-next]
[also build test ERROR on asoc/for-next v5.11-rc3 next-20210115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/MFD-ASoC-Add-support-for-Intel-Bay-Trail-boards-with-WM5102-codec/20210117-235249
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: arm-randconfig-r021-20210118 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project bfd75bdf3fd62d4f5e7028d4122f9ffa517f2a09)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/ff3c43e0ca3dd07a3b671ee3be84b9c607dff305
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hans-de-Goede/MFD-ASoC-Add-support-for-Intel-Bay-Trail-boards-with-WM5102-codec/20210117-235249
        git checkout ff3c43e0ca3dd07a3b671ee3be84b9c607dff305
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/mfd/arizona-spi.c:194:7: error: assigning to 'int' from incompatible type 'void'
                   ret = arizona_spi_acpi_probe(arizona);
                       ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 error generated.


vim +194 drivers/mfd/arizona-spi.c

   135	
   136	static int arizona_spi_probe(struct spi_device *spi)
   137	{
   138		const struct spi_device_id *id = spi_get_device_id(spi);
   139		const void *match_data;
   140		struct arizona *arizona;
   141		const struct regmap_config *regmap_config = NULL;
   142		unsigned long type = 0;
   143		int ret;
   144	
   145		match_data = device_get_match_data(&spi->dev);
   146		if (match_data)
   147			type = (unsigned long)match_data;
   148		else if (id)
   149			type = id->driver_data;
   150	
   151		switch (type) {
   152		case WM5102:
   153			if (IS_ENABLED(CONFIG_MFD_WM5102))
   154				regmap_config = &wm5102_spi_regmap;
   155			break;
   156		case WM5110:
   157		case WM8280:
   158			if (IS_ENABLED(CONFIG_MFD_WM5110))
   159				regmap_config = &wm5110_spi_regmap;
   160			break;
   161		case WM1831:
   162		case CS47L24:
   163			if (IS_ENABLED(CONFIG_MFD_CS47L24))
   164				regmap_config = &cs47l24_spi_regmap;
   165			break;
   166		default:
   167			dev_err(&spi->dev, "Unknown device type %ld\n", type);
   168			return -EINVAL;
   169		}
   170	
   171		if (!regmap_config) {
   172			dev_err(&spi->dev,
   173				"No kernel support for device type %ld\n", type);
   174			return -EINVAL;
   175		}
   176	
   177		arizona = devm_kzalloc(&spi->dev, sizeof(*arizona), GFP_KERNEL);
   178		if (arizona == NULL)
   179			return -ENOMEM;
   180	
   181		arizona->regmap = devm_regmap_init_spi(spi, regmap_config);
   182		if (IS_ERR(arizona->regmap)) {
   183			ret = PTR_ERR(arizona->regmap);
   184			dev_err(&spi->dev, "Failed to allocate register map: %d\n",
   185				ret);
   186			return ret;
   187		}
   188	
   189		arizona->type = type;
   190		arizona->dev = &spi->dev;
   191		arizona->irq = spi->irq;
   192	
   193		if (has_acpi_companion(&spi->dev)) {
 > 194			ret = arizona_spi_acpi_probe(arizona);
   195			if (ret)
   196				return ret;
   197		}
   198	
   199		return arizona_dev_init(arizona);
   200	}
   201	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Jan. 17, 2021, 8:07 p.m. UTC | #2
Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on lee-mfd/for-mfd-next]
[also build test ERROR on asoc/for-next v5.11-rc3 next-20210115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/MFD-ASoC-Add-support-for-Intel-Bay-Trail-boards-with-WM5102-codec/20210117-235249
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: sh-randconfig-s031-20210118 (attached as .config)
compiler: sh4-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-208-g46a52ca4-dirty
        # https://github.com/0day-ci/linux/commit/ff3c43e0ca3dd07a3b671ee3be84b9c607dff305
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hans-de-Goede/MFD-ASoC-Add-support-for-Intel-Bay-Trail-boards-with-WM5102-codec/20210117-235249
        git checkout ff3c43e0ca3dd07a3b671ee3be84b9c607dff305
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=sh 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   cc1: warning: arch/sh/include/mach-rsk: No such file or directory [-Wmissing-include-dirs]
   cc1: warning: arch/sh/include/mach-rsk: No such file or directory [-Wmissing-include-dirs]
   drivers/mfd/arizona-spi.c: In function 'arizona_spi_probe':
>> drivers/mfd/arizona-spi.c:194:7: error: void value not ignored as it ought to be
     194 |   ret = arizona_spi_acpi_probe(arizona);
         |       ^


vim +194 drivers/mfd/arizona-spi.c

   135	
   136	static int arizona_spi_probe(struct spi_device *spi)
   137	{
   138		const struct spi_device_id *id = spi_get_device_id(spi);
   139		const void *match_data;
   140		struct arizona *arizona;
   141		const struct regmap_config *regmap_config = NULL;
   142		unsigned long type = 0;
   143		int ret;
   144	
   145		match_data = device_get_match_data(&spi->dev);
   146		if (match_data)
   147			type = (unsigned long)match_data;
   148		else if (id)
   149			type = id->driver_data;
   150	
   151		switch (type) {
   152		case WM5102:
   153			if (IS_ENABLED(CONFIG_MFD_WM5102))
   154				regmap_config = &wm5102_spi_regmap;
   155			break;
   156		case WM5110:
   157		case WM8280:
   158			if (IS_ENABLED(CONFIG_MFD_WM5110))
   159				regmap_config = &wm5110_spi_regmap;
   160			break;
   161		case WM1831:
   162		case CS47L24:
   163			if (IS_ENABLED(CONFIG_MFD_CS47L24))
   164				regmap_config = &cs47l24_spi_regmap;
   165			break;
   166		default:
   167			dev_err(&spi->dev, "Unknown device type %ld\n", type);
   168			return -EINVAL;
   169		}
   170	
   171		if (!regmap_config) {
   172			dev_err(&spi->dev,
   173				"No kernel support for device type %ld\n", type);
   174			return -EINVAL;
   175		}
   176	
   177		arizona = devm_kzalloc(&spi->dev, sizeof(*arizona), GFP_KERNEL);
   178		if (arizona == NULL)
   179			return -ENOMEM;
   180	
   181		arizona->regmap = devm_regmap_init_spi(spi, regmap_config);
   182		if (IS_ERR(arizona->regmap)) {
   183			ret = PTR_ERR(arizona->regmap);
   184			dev_err(&spi->dev, "Failed to allocate register map: %d\n",
   185				ret);
   186			return ret;
   187		}
   188	
   189		arizona->type = type;
   190		arizona->dev = &spi->dev;
   191		arizona->irq = spi->irq;
   192	
   193		if (has_acpi_companion(&spi->dev)) {
 > 194			ret = arizona_spi_acpi_probe(arizona);
   195			if (ret)
   196				return ret;
   197		}
   198	
   199		return arizona_dev_init(arizona);
   200	}
   201	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hans de Goede Jan. 17, 2021, 8:20 p.m. UTC | #3
Hi,

On 1/17/21 8:06 PM, kernel test robot wrote:
> Hi Hans,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on lee-mfd/for-mfd-next]
> [also build test ERROR on asoc/for-next v5.11-rc3 next-20210115]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/MFD-ASoC-Add-support-for-Intel-Bay-Trail-boards-with-WM5102-codec/20210117-235249
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
> config: arm-randconfig-r021-20210118 (attached as .config)
> compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project bfd75bdf3fd62d4f5e7028d4122f9ffa517f2a09)
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # install arm cross compiling tool for clang build
>         # apt-get install binutils-arm-linux-gnueabi
>         # https://github.com/0day-ci/linux/commit/ff3c43e0ca3dd07a3b671ee3be84b9c607dff305
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review Hans-de-Goede/MFD-ASoC-Add-support-for-Intel-Bay-Trail-boards-with-WM5102-codec/20210117-235249
>         git checkout ff3c43e0ca3dd07a3b671ee3be84b9c607dff305
>         # save the attached .config to linux build tree
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm 
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>>> drivers/mfd/arizona-spi.c:194:7: error: assigning to 'int' from incompatible type 'void'
>                    ret = arizona_spi_acpi_probe(arizona);>                        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    1 error generated.

UGh, the test-robot gave the same errors for v1 of this patch-set; and I checked,
but I could not find the problem. Since there was some time between v1 and v2
I assumed that I had already fixed this in my local tree, but I now see that
this is caused by a bug in the #else block of the
#ifdef CONFIG_ACPI
#else
#endif

in this patch. I will submit a v3 of this patch-set fixing this.

Regards,

Hans
diff mbox series

Patch

diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index 798b88295c77..4dab9958846d 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -7,7 +7,10 @@ 
  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
@@ -15,11 +18,121 @@ 
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/of.h>
+#include <uapi/linux/input-event-codes.h>
 
 #include <linux/mfd/arizona/core.h>
 
 #include "arizona.h"
 
+#ifdef CONFIG_ACPI
+const struct acpi_gpio_params reset_gpios = { 1, 0, false };
+const struct acpi_gpio_params ldoena_gpios = { 2, 0, false };
+
+static const struct acpi_gpio_mapping arizona_acpi_gpios[] = {
+	{ "reset-gpios", &reset_gpios, 1, },
+	{ "wlf,ldoena-gpios", &ldoena_gpios, 1 },
+	{ }
+};
+
+/*
+ * The ACPI resources for the device only describe external GPIO-s. They do
+ * not provide mappings for the GPIO-s coming from the Arizona codec itself.
+ */
+static const struct gpiod_lookup arizona_soc_gpios[] = {
+	{ "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH },
+	{ "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW },
+};
+
+/*
+ * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
+ * Function A Play/Pause:           0 ohm
+ * Function D Voice assistant:    135 ohm
+ * Function B Volume Up           240 ohm
+ * Function C Volume Down         470 ohm
+ * Minimum Mic DC resistance     1000 ohm
+ * Minimum Ear speaker impedance   16 ohm
+ * Note the first max value below must be less then the min. speaker impedance,
+ * to allow CTIA/OMTP detection to work. The other max values are the closest
+ * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
+ */
+static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
+	{ .max =  11, .key = KEY_PLAYPAUSE },
+	{ .max = 186, .key = KEY_VOICECOMMAND },
+	{ .max = 348, .key = KEY_VOLUMEUP },
+	{ .max = 752, .key = KEY_VOLUMEDOWN },
+};
+
+static void arizona_spi_acpi_remove_lookup(void *lookup)
+{
+	gpiod_remove_lookup_table(lookup);
+}
+
+static int arizona_spi_acpi_probe(struct arizona *arizona)
+{
+	struct gpiod_lookup_table *lookup;
+	acpi_status status;
+	int ret;
+
+	/* Add mappings for the 2 ACPI declared GPIOs used for reset and ldo-ena */
+	devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios);
+
+	/* Add lookups for the SoCs own GPIOs used for micdet-polarity and spkVDD-enable */
+	lookup = devm_kzalloc(arizona->dev,
+			      struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1),
+			      GFP_KERNEL);
+	if (!lookup)
+		return -ENOMEM;
+
+	lookup->dev_id = dev_name(arizona->dev);
+	memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios));
+
+	gpiod_add_lookup_table(lookup);
+	ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup);
+	if (ret)
+		return ret;
+
+	/* Enable 32KHz clock from SoC to codec for jack-detect */
+	status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL);
+	if (ACPI_FAILURE(status))
+		dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status);
+
+	/*
+	 * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING
+	 * The IRQ line will stay low when a new IRQ event happens between reading
+	 * the IRQ status flags and acknowledging them. When the IRQ line stays
+	 * low like this the IRQ will never trigger again when its type is set
+	 * to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this.
+	 */
+	arizona->pdata.irq_flags = IRQF_TRIGGER_LOW;
+
+	/* Wait 200 ms after jack insertion */
+	arizona->pdata.micd_detect_debounce = 200;
+
+	/* Use standard AOSP values for headset-button mappings */
+	arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
+	arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);
+
+	return 0;
+}
+
+static const struct acpi_device_id arizona_acpi_match[] = {
+	{
+		.id = "WM510204",
+		.driver_data = WM5102,
+	},
+	{
+		.id = "WM510205",
+		.driver_data = WM5102,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
+#else
+static void arizona_spi_acpi_probe(struct arizona *arizona)
+{
+}
+#endif
+
 static int arizona_spi_probe(struct spi_device *spi)
 {
 	const struct spi_device_id *id = spi_get_device_id(spi);
@@ -77,6 +190,12 @@  static int arizona_spi_probe(struct spi_device *spi)
 	arizona->dev = &spi->dev;
 	arizona->irq = spi->irq;
 
+	if (has_acpi_companion(&spi->dev)) {
+		ret = arizona_spi_acpi_probe(arizona);
+		if (ret)
+			return ret;
+	}
+
 	return arizona_dev_init(arizona);
 }
 
@@ -104,6 +223,7 @@  static struct spi_driver arizona_spi_driver = {
 		.name	= "arizona",
 		.pm	= &arizona_pm_ops,
 		.of_match_table	= of_match_ptr(arizona_of_match),
+		.acpi_match_table = ACPI_PTR(arizona_acpi_match),
 	},
 	.probe		= arizona_spi_probe,
 	.remove		= arizona_spi_remove,