From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934935AbeCEMsv (ORCPT ); Mon, 5 Mar 2018 07:48:51 -0500 Received: from mail.bootlin.com ([62.4.15.54]:56171 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934149AbeCEMsr (ORCPT ); Mon, 5 Mar 2018 07:48:47 -0500 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= To: lgirdwood@gmail.com, broonie@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, perex@perex.cz, tiwai@suse.com Cc: alsa-devel@alsa-project.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, mylene.josserand@bootlin.com, alexandre.belloni@bootlin.com, thomas.petazzoni@bootlin.com, michael@amarulasolutions.com Subject: [PATCH v2 1/2] ASoC: codecs: Add support for PCM1789 Date: Mon, 5 Mar 2018 13:48:16 +0100 Message-Id: <20180305124817.7421-2-mylene.josserand@bootlin.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180305124817.7421-1-mylene.josserand@bootlin.com> References: <20180305124817.7421-1-mylene.josserand@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add Texas Instruments's PCM1789 DAC support. It is a simple DAC and does not have many registers. One particularity about this DAC is that the clocks must be always enabled. Also, an entire software reset is necessary while starting to play a sound otherwise, the clocks are not synchronized (so the DAC is not able to send data). Signed-off-by: Mylène Josserand --- sound/soc/codecs/Kconfig | 12 ++ sound/soc/codecs/Makefile | 4 + sound/soc/codecs/pcm1789-i2c.c | 76 +++++++++++ sound/soc/codecs/pcm1789.c | 288 +++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/pcm1789.h | 28 ++++ 5 files changed, 408 insertions(+) create mode 100644 sound/soc/codecs/pcm1789-i2c.c create mode 100644 sound/soc/codecs/pcm1789.c create mode 100644 sound/soc/codecs/pcm1789.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 822df8d3d4f9..0314a9faae36 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -112,6 +112,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_NAU8825 if I2C select SND_SOC_HDMI_CODEC select SND_SOC_PCM1681 if I2C + select SND_SOC_PCM1789_I2C if I2C select SND_SOC_PCM179X_I2C if I2C select SND_SOC_PCM179X_SPI if SPI_MASTER select SND_SOC_PCM186X_I2C if I2C @@ -676,6 +677,17 @@ config SND_SOC_PCM1681 tristate "Texas Instruments PCM1681 CODEC" depends on I2C +config SND_SOC_PCM1789 + tristate + +config SND_SOC_PCM1789_I2C + tristate "Texas Instruments PCM1789 CODEC (I2C)" + depends on I2C + select SND_SOC_PCM1789 + help + Enable support for Texas Instruments PCM1789 CODEC. + Select this if your PCM1789 is connected via an I2C bus. + config SND_SOC_PCM179X tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index bc9425b4ba0c..b1654909582f 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -108,6 +108,8 @@ snd-soc-nau8824-objs := nau8824.o snd-soc-nau8825-objs := nau8825.o snd-soc-hdmi-codec-objs := hdmi-codec.o snd-soc-pcm1681-objs := pcm1681.o +snd-soc-pcm1789-codec-objs := pcm1789.o +snd-soc-pcm1789-i2c-objs := pcm1789-i2c.o snd-soc-pcm179x-codec-objs := pcm179x.o snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o snd-soc-pcm179x-spi-objs := pcm179x-spi.o @@ -359,6 +361,8 @@ obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o +obj-$(CONFIG_SND_SOC_PCM1789_I2C) += snd-soc-pcm1789-i2c.o +obj-$(CONFIG_SND_SOC_PCM1789) += snd-soc-pcm1789-codec.o obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o obj-$(CONFIG_SND_SOC_PCM179X_SPI) += snd-soc-pcm179x-spi.o obj-$(CONFIG_SND_SOC_PCM186X) += snd-soc-pcm186x.o diff --git a/sound/soc/codecs/pcm1789-i2c.c b/sound/soc/codecs/pcm1789-i2c.c new file mode 100644 index 000000000000..9a34790cd0de --- /dev/null +++ b/sound/soc/codecs/pcm1789-i2c.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PCM1789 ASoC I2C driver + * + * Copyright (c) Bootlin 2018 + * + * Mylène Josserand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include "pcm1789.h" + +static int pcm1789_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + int ret; + + regmap = devm_regmap_init_i2c(client, &pcm1789_regmap_config); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret); + return ret; + } + + return pcm1789_common_init(&client->dev, regmap); +} + +static int pcm1789_i2c_remove(struct i2c_client *client) +{ + return pcm1789_common_exit(&client->dev); +} + +static const struct of_device_id pcm1789_of_match[] = { + { .compatible = "ti,pcm1789", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm1789_of_match); + +static const struct i2c_device_id pcm1789_i2c_ids[] = { + { "pcm1789", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pcm1789_i2c_ids); + +static struct i2c_driver pcm1789_i2c_driver = { + .driver = { + .name = "pcm1789", + .of_match_table = of_match_ptr(pcm1789_of_match), + }, + .id_table = pcm1789_i2c_ids, + .probe = pcm1789_i2c_probe, + .remove = pcm1789_i2c_remove, +}; + +module_i2c_driver(pcm1789_i2c_driver); + +MODULE_DESCRIPTION("ASoC PCM1789 I2C driver"); +MODULE_AUTHOR("Mylène Josserand "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c new file mode 100644 index 000000000000..93fad175c4ef --- /dev/null +++ b/sound/soc/codecs/pcm1789.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PCM1789 ASoC codec driver + * + * Copyright (c) Bootlin 2018 + * + * Mylène Josserand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include +#include +#include + +#include "pcm1789.h" + +#define PCM1789_MUTE_CONTROL 0x10 +#define PCM1789_FMT_CONTROL 0x11 +#define PCM1789_SOFT_MUTE 0x14 +#define PCM1789_DAC_VOL_LEFT 0x18 +#define PCM1789_DAC_VOL_RIGHT 0x19 + +#define PCM1789_FMT_MASK 0x07 +#define PCM1789_MUTE_MASK 0x03 +#define PCM1789_MUTE_SRET 0x06 + +struct pcm1789_private { + struct regmap *regmap; + unsigned int format; + unsigned int rate; + struct gpio_desc *reset; + struct work_struct work; + struct device *dev; +}; + +static const struct reg_default pcm1789_reg_defaults[] = { + { PCM1789_FMT_CONTROL, 0x00 }, + { PCM1789_SOFT_MUTE, 0x00 }, + { PCM1789_DAC_VOL_LEFT, 0xff }, + { PCM1789_DAC_VOL_RIGHT, 0xff }, +}; + +static bool pcm1789_accessible_reg(struct device *dev, unsigned int reg) +{ + return reg >= PCM1789_MUTE_CONTROL && reg <= PCM1789_DAC_VOL_RIGHT; +} + +static bool pcm1789_writeable_reg(struct device *dev, unsigned int reg) +{ + return pcm1789_accessible_reg(dev, reg); +} + +static int pcm1789_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int format) +{ + struct snd_soc_component *component = codec_dai->component; + struct pcm1789_private *priv = snd_soc_component_get_drvdata(component); + + priv->format = format; + + return 0; +} + +static int pcm1789_digital_mute(struct snd_soc_dai *codec_dai, int mute) +{ + struct snd_soc_component *component = codec_dai->component; + struct pcm1789_private *priv = snd_soc_component_get_drvdata(component); + + return regmap_update_bits(priv->regmap, PCM1789_SOFT_MUTE, + PCM1789_MUTE_MASK, + mute ? 0 : PCM1789_MUTE_MASK); +} + +static int pcm1789_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *codec_dai) +{ + struct snd_soc_component *component = codec_dai->component; + struct pcm1789_private *priv = snd_soc_component_get_drvdata(component); + int val = 0, ret; + + priv->rate = params_rate(params); + + switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + switch (params_width(params)) { + case 24: + val = 2; + break; + case 16: + val = 3; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + switch (params_width(params)) { + case 16: + case 24: + case 32: + val = 0; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_LEFT_J: + switch (params_width(params)) { + case 16: + case 24: + case 32: + val = 1; + break; + default: + return -EINVAL; + } + break; + default: + dev_err(component->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + ret = regmap_update_bits(priv->regmap, PCM1789_FMT_CONTROL, + PCM1789_FMT_MASK, val); + if (ret < 0) + return ret; + + return 0; +} + +static void pcm1789_work_queue(struct work_struct *work) +{ + struct pcm1789_private *priv = container_of(work, + struct pcm1789_private, + work); + + /* Perform a software reset to remove codec from desynchronized state */ + if (regmap_update_bits(priv->regmap, PCM1789_MUTE_CONTROL, + 0x3 << PCM1789_MUTE_SRET, 0) < 0) + dev_err(priv->dev, "Error while setting SRET"); +} + +static int pcm1789_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct pcm1789_private *priv = snd_soc_component_get_drvdata(component); + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + schedule_work(&priv->work); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct snd_soc_dai_ops pcm1789_dai_ops = { + .set_fmt = pcm1789_set_dai_fmt, + .hw_params = pcm1789_hw_params, + .digital_mute = pcm1789_digital_mute, + .trigger = pcm1789_trigger, +}; + +static const DECLARE_TLV_DB_SCALE(pcm1789_dac_tlv, -12000, 50, 1); + +static const struct snd_kcontrol_new pcm1789_controls[] = { + SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1789_DAC_VOL_LEFT, + PCM1789_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, + pcm1789_dac_tlv), +}; + +static const struct snd_soc_dapm_widget pcm1789_dapm_widgets[] = { + SND_SOC_DAPM_OUTPUT("IOUTL+"), + SND_SOC_DAPM_OUTPUT("IOUTL-"), + SND_SOC_DAPM_OUTPUT("IOUTR+"), + SND_SOC_DAPM_OUTPUT("IOUTR-"), +}; + +static const struct snd_soc_dapm_route pcm1789_dapm_routes[] = { + { "IOUTL+", NULL, "Playback" }, + { "IOUTL-", NULL, "Playback" }, + { "IOUTR+", NULL, "Playback" }, + { "IOUTR-", NULL, "Playback" }, +}; + +static struct snd_soc_dai_driver pcm1789_dai = { + .name = "pcm1789-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 10000, + .rate_max = 200000, + .formats = PCM1789_FORMATS, + }, + .ops = &pcm1789_dai_ops, +}; + +const struct regmap_config pcm1789_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = PCM1789_DAC_VOL_RIGHT, + .reg_defaults = pcm1789_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(pcm1789_reg_defaults), + .writeable_reg = pcm1789_writeable_reg, + .readable_reg = pcm1789_accessible_reg, +}; +EXPORT_SYMBOL_GPL(pcm1789_regmap_config); + +static const struct snd_soc_component_driver soc_component_dev_pcm1789 = { + .controls = pcm1789_controls, + .num_controls = ARRAY_SIZE(pcm1789_controls), + .dapm_widgets = pcm1789_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(pcm1789_dapm_widgets), + .dapm_routes = pcm1789_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(pcm1789_dapm_routes), + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, + .non_legacy_dai_naming = 1, +}; + +int pcm1789_common_init(struct device *dev, struct regmap *regmap) +{ + struct pcm1789_private *pcm1789; + + pcm1789 = devm_kzalloc(dev, sizeof(struct pcm1789_private), + GFP_KERNEL); + if (!pcm1789) + return -ENOMEM; + + pcm1789->regmap = regmap; + pcm1789->dev = dev; + dev_set_drvdata(dev, pcm1789); + + pcm1789->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(pcm1789->reset)) + return PTR_ERR(pcm1789->reset); + + gpiod_set_value_cansleep(pcm1789->reset, 0); + msleep(300); + + INIT_WORK(&pcm1789->work, pcm1789_work_queue); + + return devm_snd_soc_register_component(dev, &soc_component_dev_pcm1789, + &pcm1789_dai, 1); +} +EXPORT_SYMBOL_GPL(pcm1789_common_init); + +int pcm1789_common_exit(struct device *dev) +{ + struct pcm1789_private *priv = dev_get_drvdata(dev); + + if (&priv->work) + flush_work(&priv->work); + + return 0; +} +EXPORT_SYMBOL_GPL(pcm1789_common_exit); + +MODULE_DESCRIPTION("ASoC PCM1789 driver"); +MODULE_AUTHOR("Mylène Josserand "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pcm1789.h b/sound/soc/codecs/pcm1789.h new file mode 100644 index 000000000000..05c2c8ad2bad --- /dev/null +++ b/sound/soc/codecs/pcm1789.h @@ -0,0 +1,28 @@ +/* + * definitions for PCM1789 + * + * Copyright (c) Bootlin 2018 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PCM1789_H__ +#define __PCM1789_H__ + +#define PCM1789_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +extern const struct regmap_config pcm1789_regmap_config; + +int pcm1789_common_init(struct device *dev, struct regmap *regmap); +int pcm1789_common_exit(struct device *dev); + +#endif -- 2.11.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Subject: [PATCH v2 1/2] ASoC: codecs: Add support for PCM1789 Date: Mon, 5 Mar 2018 13:48:16 +0100 Message-ID: <20180305124817.7421-2-mylene.josserand@bootlin.com> References: <20180305124817.7421-1-mylene.josserand@bootlin.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180305124817.7421-1-mylene.josserand@bootlin.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org To: lgirdwood@gmail.com, broonie@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, perex@perex.cz, tiwai@suse.com Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org, michael@amarulasolutions.com, alexandre.belloni@bootlin.com, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, mylene.josserand@bootlin.com List-Id: devicetree@vger.kernel.org QWRkIFRleGFzIEluc3RydW1lbnRzJ3MgUENNMTc4OSBEQUMgc3VwcG9ydC4KSXQgaXMgYSBzaW1w bGUgREFDIGFuZCBkb2VzIG5vdCBoYXZlIG1hbnkgcmVnaXN0ZXJzLgoKT25lIHBhcnRpY3VsYXJp dHkgYWJvdXQgdGhpcyBEQUMgaXMgdGhhdCB0aGUgY2xvY2tzIG11c3QgYmUKYWx3YXlzIGVuYWJs ZWQuIEFsc28sIGFuIGVudGlyZSBzb2Z0d2FyZSByZXNldCBpcyBuZWNlc3NhcnkKd2hpbGUgc3Rh cnRpbmcgdG8gcGxheSBhIHNvdW5kIG90aGVyd2lzZSwgdGhlIGNsb2NrcyBhcmUgbm90CnN5bmNo cm9uaXplZCAoc28gdGhlIERBQyBpcyBub3QgYWJsZSB0byBzZW5kIGRhdGEpLgoKU2lnbmVkLW9m Zi1ieTogTXlsw6huZSBKb3NzZXJhbmQgPG15bGVuZS5qb3NzZXJhbmRAYm9vdGxpbi5jb20+Ci0t LQogc291bmQvc29jL2NvZGVjcy9LY29uZmlnICAgICAgIHwgIDEyICsrCiBzb3VuZC9zb2MvY29k ZWNzL01ha2VmaWxlICAgICAgfCAgIDQgKwogc291bmQvc29jL2NvZGVjcy9wY20xNzg5LWkyYy5j IHwgIDc2ICsrKysrKysrKysrCiBzb3VuZC9zb2MvY29kZWNzL3BjbTE3ODkuYyAgICAgfCAyODgg KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKIHNvdW5kL3NvYy9jb2Rl Y3MvcGNtMTc4OS5oICAgICB8ICAyOCArKysrCiA1IGZpbGVzIGNoYW5nZWQsIDQwOCBpbnNlcnRp b25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQgc291bmQvc29jL2NvZGVjcy9wY20xNzg5LWkyYy5j CiBjcmVhdGUgbW9kZSAxMDA2NDQgc291bmQvc29jL2NvZGVjcy9wY20xNzg5LmMKIGNyZWF0ZSBt b2RlIDEwMDY0NCBzb3VuZC9zb2MvY29kZWNzL3BjbTE3ODkuaAoKZGlmZiAtLWdpdCBhL3NvdW5k L3NvYy9jb2RlY3MvS2NvbmZpZyBiL3NvdW5kL3NvYy9jb2RlY3MvS2NvbmZpZwppbmRleCA4MjJk ZjhkM2Q0ZjkuLjAzMTRhOWZhYWUzNiAxMDA2NDQKLS0tIGEvc291bmQvc29jL2NvZGVjcy9LY29u ZmlnCisrKyBiL3NvdW5kL3NvYy9jb2RlY3MvS2NvbmZpZwpAQCAtMTEyLDYgKzExMiw3IEBAIGNv bmZpZyBTTkRfU09DX0FMTF9DT0RFQ1MKIAlzZWxlY3QgU05EX1NPQ19OQVU4ODI1IGlmIEkyQwog CXNlbGVjdCBTTkRfU09DX0hETUlfQ09ERUMKIAlzZWxlY3QgU05EX1NPQ19QQ00xNjgxIGlmIEky QworCXNlbGVjdCBTTkRfU09DX1BDTTE3ODlfSTJDIGlmIEkyQwogCXNlbGVjdCBTTkRfU09DX1BD TTE3OVhfSTJDIGlmIEkyQwogCXNlbGVjdCBTTkRfU09DX1BDTTE3OVhfU1BJIGlmIFNQSV9NQVNU RVIKIAlzZWxlY3QgU05EX1NPQ19QQ00xODZYX0kyQyBpZiBJMkMKQEAgLTY3Niw2ICs2NzcsMTcg QEAgY29uZmlnIFNORF9TT0NfUENNMTY4MQogCXRyaXN0YXRlICJUZXhhcyBJbnN0cnVtZW50cyBQ Q00xNjgxIENPREVDIgogCWRlcGVuZHMgb24gSTJDCiAKK2NvbmZpZyBTTkRfU09DX1BDTTE3ODkK Kwl0cmlzdGF0ZQorCitjb25maWcgU05EX1NPQ19QQ00xNzg5X0kyQworCXRyaXN0YXRlICJUZXhh cyBJbnN0cnVtZW50cyBQQ00xNzg5IENPREVDIChJMkMpIgorCWRlcGVuZHMgb24gSTJDCisJc2Vs ZWN0IFNORF9TT0NfUENNMTc4OQorCWhlbHAKKwkgIEVuYWJsZSBzdXBwb3J0IGZvciBUZXhhcyBJ bnN0cnVtZW50cyBQQ00xNzg5IENPREVDLgorCSAgU2VsZWN0IHRoaXMgaWYgeW91ciBQQ00xNzg5 IGlzIGNvbm5lY3RlZCB2aWEgYW4gSTJDIGJ1cy4KKwogY29uZmlnIFNORF9TT0NfUENNMTc5WAog CXRyaXN0YXRlCiAKZGlmZiAtLWdpdCBhL3NvdW5kL3NvYy9jb2RlY3MvTWFrZWZpbGUgYi9zb3Vu ZC9zb2MvY29kZWNzL01ha2VmaWxlCmluZGV4IGJjOTQyNWI0YmEwYy4uYjE2NTQ5MDk1ODJmIDEw MDY0NAotLS0gYS9zb3VuZC9zb2MvY29kZWNzL01ha2VmaWxlCisrKyBiL3NvdW5kL3NvYy9jb2Rl Y3MvTWFrZWZpbGUKQEAgLTEwOCw2ICsxMDgsOCBAQCBzbmQtc29jLW5hdTg4MjQtb2JqcyA6PSBu YXU4ODI0Lm8KIHNuZC1zb2MtbmF1ODgyNS1vYmpzIDo9IG5hdTg4MjUubwogc25kLXNvYy1oZG1p LWNvZGVjLW9ianMgOj0gaGRtaS1jb2RlYy5vCiBzbmQtc29jLXBjbTE2ODEtb2JqcyA6PSBwY20x NjgxLm8KK3NuZC1zb2MtcGNtMTc4OS1jb2RlYy1vYmpzIDo9IHBjbTE3ODkubworc25kLXNvYy1w Y20xNzg5LWkyYy1vYmpzIDo9IHBjbTE3ODktaTJjLm8KIHNuZC1zb2MtcGNtMTc5eC1jb2RlYy1v YmpzIDo9IHBjbTE3OXgubwogc25kLXNvYy1wY20xNzl4LWkyYy1vYmpzIDo9IHBjbTE3OXgtaTJj Lm8KIHNuZC1zb2MtcGNtMTc5eC1zcGktb2JqcyA6PSBwY20xNzl4LXNwaS5vCkBAIC0zNTksNiAr MzYxLDggQEAgb2JqLSQoQ09ORklHX1NORF9TT0NfTkFVODgyNSkgICArPSBzbmQtc29jLW5hdTg4 MjUubwogb2JqLSQoQ09ORklHX1NORF9TT0NfSERNSV9DT0RFQykJKz0gc25kLXNvYy1oZG1pLWNv ZGVjLm8KIG9iai0kKENPTkZJR19TTkRfU09DX1BDTTE2ODEpCSs9IHNuZC1zb2MtcGNtMTY4MS5v CiBvYmotJChDT05GSUdfU05EX1NPQ19QQ00xNzlYKQkrPSBzbmQtc29jLXBjbTE3OXgtY29kZWMu bworb2JqLSQoQ09ORklHX1NORF9TT0NfUENNMTc4OV9JMkMpCSs9IHNuZC1zb2MtcGNtMTc4OS1p MmMubworb2JqLSQoQ09ORklHX1NORF9TT0NfUENNMTc4OSkJKz0gc25kLXNvYy1wY20xNzg5LWNv ZGVjLm8KIG9iai0kKENPTkZJR19TTkRfU09DX1BDTTE3OVhfSTJDKQkrPSBzbmQtc29jLXBjbTE3 OXgtaTJjLm8KIG9iai0kKENPTkZJR19TTkRfU09DX1BDTTE3OVhfU1BJKQkrPSBzbmQtc29jLXBj bTE3OXgtc3BpLm8KIG9iai0kKENPTkZJR19TTkRfU09DX1BDTTE4NlgpCSs9IHNuZC1zb2MtcGNt MTg2eC5vCmRpZmYgLS1naXQgYS9zb3VuZC9zb2MvY29kZWNzL3BjbTE3ODktaTJjLmMgYi9zb3Vu ZC9zb2MvY29kZWNzL3BjbTE3ODktaTJjLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAw MDAwMDAwMDAwLi45YTM0NzkwY2QwZGUKLS0tIC9kZXYvbnVsbAorKysgYi9zb3VuZC9zb2MvY29k ZWNzL3BjbTE3ODktaTJjLmMKQEAgLTAsMCArMSw3NiBAQAorLy8gU1BEWC1MaWNlbnNlLUlkZW50 aWZpZXI6IEdQTC0yLjAKKy8qCisgKiBQQ00xNzg5IEFTb0MgSTJDIGRyaXZlcgorICoKKyAqIENv cHlyaWdodCAoYykgQm9vdGxpbiAyMDE4CisgKgorICogTXlsw6huZSBKb3NzZXJhbmQgPG15bGVu ZS5qb3NzZXJhbmRAYm9vdGxpbi5jb20+CisgKgorICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29m dHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5IGl0IHVuZGVy IHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKKyAqIGFzIHB1Ymxp c2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyCisg KiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4K KyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3 aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVu IHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBG T1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBHTlUgR2VuZXJhbCBQdWJsaWMg TGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4K KyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgorI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgorI2lu Y2x1ZGUgPGxpbnV4L29mLmg+CisjaW5jbHVkZSA8bGludXgvaTJjLmg+CisjaW5jbHVkZSA8bGlu dXgvcmVnbWFwLmg+CisKKyNpbmNsdWRlICJwY20xNzg5LmgiCisKK3N0YXRpYyBpbnQgcGNtMTc4 OV9pMmNfcHJvYmUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwKKwkJCSAgICAgY29uc3Qgc3Ry dWN0IGkyY19kZXZpY2VfaWQgKmlkKQoreworCXN0cnVjdCByZWdtYXAgKnJlZ21hcDsKKwlpbnQg cmV0OworCisJcmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LCAmcGNtMTc4OV9y ZWdtYXBfY29uZmlnKTsKKwlpZiAoSVNfRVJSKHJlZ21hcCkpIHsKKwkJcmV0ID0gUFRSX0VSUihy ZWdtYXApOworCQlkZXZfZXJyKCZjbGllbnQtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSByZWdt YXA6ICVkXG4iLCByZXQpOworCQlyZXR1cm4gcmV0OworCX0KKworCXJldHVybiBwY20xNzg5X2Nv bW1vbl9pbml0KCZjbGllbnQtPmRldiwgcmVnbWFwKTsKK30KKworc3RhdGljIGludCBwY20xNzg5 X2kyY19yZW1vdmUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkKK3sKKwlyZXR1cm4gcGNtMTc4 OV9jb21tb25fZXhpdCgmY2xpZW50LT5kZXYpOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IG9m X2RldmljZV9pZCBwY20xNzg5X29mX21hdGNoW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJ0aSxw Y20xNzg5IiwgfSwKKwl7IH0KK307CitNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBwY20xNzg5X29m X21hdGNoKTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkIHBjbTE3ODlfaTJj X2lkc1tdID0geworCXsgInBjbTE3ODkiLCAwIH0sCisJeyB9Cit9OworTU9EVUxFX0RFVklDRV9U QUJMRShpMmMsIHBjbTE3ODlfaTJjX2lkcyk7CisKK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBw Y20xNzg5X2kyY19kcml2ZXIgPSB7CisJLmRyaXZlciA9IHsKKwkJLm5hbWUJPSAicGNtMTc4OSIs CisJCS5vZl9tYXRjaF90YWJsZSA9IG9mX21hdGNoX3B0cihwY20xNzg5X29mX21hdGNoKSwKKwl9 LAorCS5pZF90YWJsZQk9IHBjbTE3ODlfaTJjX2lkcywKKwkucHJvYmUJCT0gcGNtMTc4OV9pMmNf cHJvYmUsCisJLnJlbW92ZQk9IHBjbTE3ODlfaTJjX3JlbW92ZSwKK307CisKK21vZHVsZV9pMmNf ZHJpdmVyKHBjbTE3ODlfaTJjX2RyaXZlcik7CisKK01PRFVMRV9ERVNDUklQVElPTigiQVNvQyBQ Q00xNzg5IEkyQyBkcml2ZXIiKTsKK01PRFVMRV9BVVRIT1IoIk15bMOobmUgSm9zc2VyYW5kIDxt eWxlbmUuam9zc2VyYW5kQGJvb3RsaW4uY29tPiIpOworTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpk aWZmIC0tZ2l0IGEvc291bmQvc29jL2NvZGVjcy9wY20xNzg5LmMgYi9zb3VuZC9zb2MvY29kZWNz L3BjbTE3ODkuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjkzZmFk MTc1YzRlZgotLS0gL2Rldi9udWxsCisrKyBiL3NvdW5kL3NvYy9jb2RlY3MvcGNtMTc4OS5jCkBA IC0wLDAgKzEsMjg4IEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAorLyoK KyAqIFBDTTE3ODkgQVNvQyBjb2RlYyBkcml2ZXIKKyAqCisgKiBDb3B5cmlnaHQgKGMpIEJvb3Rs aW4gMjAxOAorICoKKyAqIE15bMOobmUgSm9zc2VyYW5kIDxteWxlbmUuam9zc2VyYW5kQGJvb3Rs aW4uY29tPgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJl ZGlzdHJpYnV0ZSBpdCBhbmQvb3IKKyAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhl IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCisgKiBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUg U29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMgorICogb2YgdGhlIExpY2Vuc2Us IG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCisgKgorICogVGhpcyBwcm9n cmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCisg KiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJy YW50eSBvZgorICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQ VVJQT1NFLiAgU2VlIHRoZQorICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUg ZGV0YWlscy4KKyAqLworCisjaW5jbHVkZSA8bGludXgvZ3Bpby5oPgorI2luY2x1ZGUgPGxpbnV4 L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgorCisjaW5jbHVkZSA8c291 bmQvcGNtX3BhcmFtcy5oPgorI2luY2x1ZGUgPHNvdW5kL3NvYy5oPgorI2luY2x1ZGUgPHNvdW5k L3Rsdi5oPgorCisjaW5jbHVkZSAicGNtMTc4OS5oIgorCisjZGVmaW5lIFBDTTE3ODlfTVVURV9D T05UUk9MCTB4MTAKKyNkZWZpbmUgUENNMTc4OV9GTVRfQ09OVFJPTAkweDExCisjZGVmaW5lIFBD TTE3ODlfU09GVF9NVVRFCTB4MTQKKyNkZWZpbmUgUENNMTc4OV9EQUNfVk9MX0xFRlQJMHgxOAor I2RlZmluZSBQQ00xNzg5X0RBQ19WT0xfUklHSFQJMHgxOQorCisjZGVmaW5lIFBDTTE3ODlfRk1U X01BU0sJMHgwNworI2RlZmluZSBQQ00xNzg5X01VVEVfTUFTSwkweDAzCisjZGVmaW5lIFBDTTE3 ODlfTVVURV9TUkVUCTB4MDYKKworc3RydWN0IHBjbTE3ODlfcHJpdmF0ZSB7CisJc3RydWN0IHJl Z21hcCAqcmVnbWFwOworCXVuc2lnbmVkIGludCBmb3JtYXQ7CisJdW5zaWduZWQgaW50IHJhdGU7 CisJc3RydWN0IGdwaW9fZGVzYyAqcmVzZXQ7CisJc3RydWN0IHdvcmtfc3RydWN0IHdvcms7CisJ c3RydWN0IGRldmljZSAqZGV2OworfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCByZWdfZGVmYXVs dCBwY20xNzg5X3JlZ19kZWZhdWx0c1tdID0geworCXsgUENNMTc4OV9GTVRfQ09OVFJPTCwgMHgw MCB9LAorCXsgUENNMTc4OV9TT0ZUX01VVEUsIDB4MDAgfSwKKwl7IFBDTTE3ODlfREFDX1ZPTF9M RUZULCAweGZmIH0sCisJeyBQQ00xNzg5X0RBQ19WT0xfUklHSFQsIDB4ZmYgfSwKK307CisKK3N0 YXRpYyBib29sIHBjbTE3ODlfYWNjZXNzaWJsZV9yZWcoc3RydWN0IGRldmljZSAqZGV2LCB1bnNp Z25lZCBpbnQgcmVnKQoreworCXJldHVybiByZWcgPj0gUENNMTc4OV9NVVRFX0NPTlRST0wgJiYg cmVnIDw9IFBDTTE3ODlfREFDX1ZPTF9SSUdIVDsKK30KKworc3RhdGljIGJvb2wgcGNtMTc4OV93 cml0ZWFibGVfcmVnKHN0cnVjdCBkZXZpY2UgKmRldiwgdW5zaWduZWQgaW50IHJlZykKK3sKKwly ZXR1cm4gcGNtMTc4OV9hY2Nlc3NpYmxlX3JlZyhkZXYsIHJlZyk7Cit9CisKK3N0YXRpYyBpbnQg cGNtMTc4OV9zZXRfZGFpX2ZtdChzdHJ1Y3Qgc25kX3NvY19kYWkgKmNvZGVjX2RhaSwKKwkJCSAg ICAgICB1bnNpZ25lZCBpbnQgZm9ybWF0KQoreworCXN0cnVjdCBzbmRfc29jX2NvbXBvbmVudCAq Y29tcG9uZW50ID0gY29kZWNfZGFpLT5jb21wb25lbnQ7CisJc3RydWN0IHBjbTE3ODlfcHJpdmF0 ZSAqcHJpdiA9IHNuZF9zb2NfY29tcG9uZW50X2dldF9kcnZkYXRhKGNvbXBvbmVudCk7CisKKwlw cml2LT5mb3JtYXQgPSBmb3JtYXQ7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBwY20x Nzg5X2RpZ2l0YWxfbXV0ZShzdHJ1Y3Qgc25kX3NvY19kYWkgKmNvZGVjX2RhaSwgaW50IG11dGUp Cit7CisJc3RydWN0IHNuZF9zb2NfY29tcG9uZW50ICpjb21wb25lbnQgPSBjb2RlY19kYWktPmNv bXBvbmVudDsKKwlzdHJ1Y3QgcGNtMTc4OV9wcml2YXRlICpwcml2ID0gc25kX3NvY19jb21wb25l bnRfZ2V0X2RydmRhdGEoY29tcG9uZW50KTsKKworCXJldHVybiByZWdtYXBfdXBkYXRlX2JpdHMo cHJpdi0+cmVnbWFwLCBQQ00xNzg5X1NPRlRfTVVURSwKKwkJCQkgIFBDTTE3ODlfTVVURV9NQVNL LAorCQkJCSAgbXV0ZSA/IDAgOiBQQ00xNzg5X01VVEVfTUFTSyk7Cit9CisKK3N0YXRpYyBpbnQg cGNtMTc4OV9od19wYXJhbXMoc3RydWN0IHNuZF9wY21fc3Vic3RyZWFtICpzdWJzdHJlYW0sCisJ CQkgICAgIHN0cnVjdCBzbmRfcGNtX2h3X3BhcmFtcyAqcGFyYW1zLAorCQkJICAgICBzdHJ1Y3Qg c25kX3NvY19kYWkgKmNvZGVjX2RhaSkKK3sKKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNv bXBvbmVudCA9IGNvZGVjX2RhaS0+Y29tcG9uZW50OworCXN0cnVjdCBwY20xNzg5X3ByaXZhdGUg KnByaXYgPSBzbmRfc29jX2NvbXBvbmVudF9nZXRfZHJ2ZGF0YShjb21wb25lbnQpOworCWludCB2 YWwgPSAwLCByZXQ7CisKKwlwcml2LT5yYXRlID0gcGFyYW1zX3JhdGUocGFyYW1zKTsKKworCXN3 aXRjaCAocHJpdi0+Zm9ybWF0ICYgU05EX1NPQ19EQUlGTVRfRk9STUFUX01BU0spIHsKKwljYXNl IFNORF9TT0NfREFJRk1UX1JJR0hUX0o6CisJCXN3aXRjaCAocGFyYW1zX3dpZHRoKHBhcmFtcykp IHsKKwkJY2FzZSAyNDoKKwkJCXZhbCA9IDI7CisJCQlicmVhazsKKwkJY2FzZSAxNjoKKwkJCXZh bCA9IDM7CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCXJldHVybiAtRUlOVkFMOworCQl9CisJ CWJyZWFrOworCWNhc2UgU05EX1NPQ19EQUlGTVRfSTJTOgorCQlzd2l0Y2ggKHBhcmFtc193aWR0 aChwYXJhbXMpKSB7CisJCWNhc2UgMTY6CisJCWNhc2UgMjQ6CisJCWNhc2UgMzI6CisJCQl2YWwg PSAwOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlyZXR1cm4gLUVJTlZBTDsKKwkJfQorCQli cmVhazsKKwljYXNlIFNORF9TT0NfREFJRk1UX0xFRlRfSjoKKwkJc3dpdGNoIChwYXJhbXNfd2lk dGgocGFyYW1zKSkgeworCQljYXNlIDE2OgorCQljYXNlIDI0OgorCQljYXNlIDMyOgorCQkJdmFs ID0gMTsKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJcmV0dXJuIC1FSU5WQUw7CisJCX0KKwkJ YnJlYWs7CisJZGVmYXVsdDoKKwkJZGV2X2Vycihjb21wb25lbnQtPmRldiwgIkludmFsaWQgREFJ IGZvcm1hdFxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCXJldCA9IHJlZ21hcF91cGRh dGVfYml0cyhwcml2LT5yZWdtYXAsIFBDTTE3ODlfRk1UX0NPTlRST0wsCisJCQkJIFBDTTE3ODlf Rk1UX01BU0ssIHZhbCk7CisJaWYgKHJldCA8IDApCisJCXJldHVybiByZXQ7CisKKwlyZXR1cm4g MDsKK30KKworc3RhdGljIHZvaWQgcGNtMTc4OV93b3JrX3F1ZXVlKHN0cnVjdCB3b3JrX3N0cnVj dCAqd29yaykKK3sKKwlzdHJ1Y3QgcGNtMTc4OV9wcml2YXRlICpwcml2ID0gY29udGFpbmVyX29m KHdvcmssCisJCQkJCQkgICAgc3RydWN0IHBjbTE3ODlfcHJpdmF0ZSwKKwkJCQkJCSAgICB3b3Jr KTsKKworCS8qIFBlcmZvcm0gYSBzb2Z0d2FyZSByZXNldCB0byByZW1vdmUgY29kZWMgZnJvbSBk ZXN5bmNocm9uaXplZCBzdGF0ZSAqLworCWlmIChyZWdtYXBfdXBkYXRlX2JpdHMocHJpdi0+cmVn bWFwLCBQQ00xNzg5X01VVEVfQ09OVFJPTCwKKwkJCSAgICAgICAweDMgPDwgUENNMTc4OV9NVVRF X1NSRVQsIDApIDwgMCkKKwkJZGV2X2Vycihwcml2LT5kZXYsICJFcnJvciB3aGlsZSBzZXR0aW5n IFNSRVQiKTsKK30KKworc3RhdGljIGludCBwY20xNzg5X3RyaWdnZXIoc3RydWN0IHNuZF9wY21f c3Vic3RyZWFtICpzdWJzdHJlYW0sIGludCBjbWQsCisJCQkgICBzdHJ1Y3Qgc25kX3NvY19kYWkg KmRhaSkKK3sKKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNvbXBvbmVudCA9IGRhaS0+Y29t cG9uZW50OworCXN0cnVjdCBwY20xNzg5X3ByaXZhdGUgKnByaXYgPSBzbmRfc29jX2NvbXBvbmVu dF9nZXRfZHJ2ZGF0YShjb21wb25lbnQpOworCWludCByZXQgPSAwOworCisJc3dpdGNoIChjbWQp IHsKKwljYXNlIFNORFJWX1BDTV9UUklHR0VSX1NUQVJUOgorCWNhc2UgU05EUlZfUENNX1RSSUdH RVJfUkVTVU1FOgorCWNhc2UgU05EUlZfUENNX1RSSUdHRVJfUEFVU0VfUkVMRUFTRToKKwkJc2No ZWR1bGVfd29yaygmcHJpdi0+d29yayk7CisJCWJyZWFrOworCWNhc2UgU05EUlZfUENNX1RSSUdH RVJfU1RPUDoKKwljYXNlIFNORFJWX1BDTV9UUklHR0VSX1NVU1BFTkQ6CisJY2FzZSBTTkRSVl9Q Q01fVFJJR0dFUl9QQVVTRV9QVVNIOgorCQlicmVhazsKKwlkZWZhdWx0OgorCQlyZXQgPSAtRUlO VkFMOworCX0KKworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc25kX3Nv Y19kYWlfb3BzIHBjbTE3ODlfZGFpX29wcyA9IHsKKwkuc2V0X2ZtdAk9IHBjbTE3ODlfc2V0X2Rh aV9mbXQsCisJLmh3X3BhcmFtcwk9IHBjbTE3ODlfaHdfcGFyYW1zLAorCS5kaWdpdGFsX211dGUJ PSBwY20xNzg5X2RpZ2l0YWxfbXV0ZSwKKwkudHJpZ2dlcgk9IHBjbTE3ODlfdHJpZ2dlciwKK307 CisKK3N0YXRpYyBjb25zdCBERUNMQVJFX1RMVl9EQl9TQ0FMRShwY20xNzg5X2RhY190bHYsIC0x MjAwMCwgNTAsIDEpOworCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9rY29udHJvbF9uZXcgcGNt MTc4OV9jb250cm9sc1tdID0geworCVNPQ19ET1VCTEVfUl9SQU5HRV9UTFYoIkRBQyBQbGF5YmFj ayBWb2x1bWUiLCBQQ00xNzg5X0RBQ19WT0xfTEVGVCwKKwkJCSAgICAgICBQQ00xNzg5X0RBQ19W T0xfUklHSFQsIDAsIDB4ZiwgMHhmZiwgMCwKKwkJCSAgICAgICBwY20xNzg5X2RhY190bHYpLAor fTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfc29jX2RhcG1fd2lkZ2V0IHBjbTE3ODlfZGFw bV93aWRnZXRzW10gPSB7CisJU05EX1NPQ19EQVBNX09VVFBVVCgiSU9VVEwrIiksCisJU05EX1NP Q19EQVBNX09VVFBVVCgiSU9VVEwtIiksCisJU05EX1NPQ19EQVBNX09VVFBVVCgiSU9VVFIrIiks CisJU05EX1NPQ19EQVBNX09VVFBVVCgiSU9VVFItIiksCit9OworCitzdGF0aWMgY29uc3Qgc3Ry dWN0IHNuZF9zb2NfZGFwbV9yb3V0ZSBwY20xNzg5X2RhcG1fcm91dGVzW10gPSB7CisJeyAiSU9V VEwrIiwgTlVMTCwgIlBsYXliYWNrIiB9LAorCXsgIklPVVRMLSIsIE5VTEwsICJQbGF5YmFjayIg fSwKKwl7ICJJT1VUUisiLCBOVUxMLCAiUGxheWJhY2siIH0sCisJeyAiSU9VVFItIiwgTlVMTCwg IlBsYXliYWNrIiB9LAorfTsKKworc3RhdGljIHN0cnVjdCBzbmRfc29jX2RhaV9kcml2ZXIgcGNt MTc4OV9kYWkgPSB7CisJLm5hbWUgPSAicGNtMTc4OS1oaWZpIiwKKwkucGxheWJhY2sgPSB7CisJ CS5zdHJlYW1fbmFtZSA9ICJQbGF5YmFjayIsCisJCS5jaGFubmVsc19taW4gPSAyLAorCQkuY2hh bm5lbHNfbWF4ID0gMiwKKwkJLnJhdGVzID0gU05EUlZfUENNX1JBVEVfQ09OVElOVU9VUywKKwkJ LnJhdGVfbWluID0gMTAwMDAsCisJCS5yYXRlX21heCA9IDIwMDAwMCwKKwkJLmZvcm1hdHMgPSBQ Q00xNzg5X0ZPUk1BVFMsCisJfSwKKwkub3BzID0gJnBjbTE3ODlfZGFpX29wcywKK307CisKK2Nv bnN0IHN0cnVjdCByZWdtYXBfY29uZmlnIHBjbTE3ODlfcmVnbWFwX2NvbmZpZyA9IHsKKwkucmVn X2JpdHMJCT0gOCwKKwkudmFsX2JpdHMJCT0gOCwKKwkubWF4X3JlZ2lzdGVyCQk9IFBDTTE3ODlf REFDX1ZPTF9SSUdIVCwKKwkucmVnX2RlZmF1bHRzCQk9IHBjbTE3ODlfcmVnX2RlZmF1bHRzLAor CS5udW1fcmVnX2RlZmF1bHRzCT0gQVJSQVlfU0laRShwY20xNzg5X3JlZ19kZWZhdWx0cyksCisJ LndyaXRlYWJsZV9yZWcJCT0gcGNtMTc4OV93cml0ZWFibGVfcmVnLAorCS5yZWFkYWJsZV9yZWcJ CT0gcGNtMTc4OV9hY2Nlc3NpYmxlX3JlZywKK307CitFWFBPUlRfU1lNQk9MX0dQTChwY20xNzg5 X3JlZ21hcF9jb25maWcpOworCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9zb2NfY29tcG9uZW50 X2RyaXZlciBzb2NfY29tcG9uZW50X2Rldl9wY20xNzg5ID0geworCS5jb250cm9scwkJPSBwY20x Nzg5X2NvbnRyb2xzLAorCS5udW1fY29udHJvbHMJCT0gQVJSQVlfU0laRShwY20xNzg5X2NvbnRy b2xzKSwKKwkuZGFwbV93aWRnZXRzCQk9IHBjbTE3ODlfZGFwbV93aWRnZXRzLAorCS5udW1fZGFw bV93aWRnZXRzCT0gQVJSQVlfU0laRShwY20xNzg5X2RhcG1fd2lkZ2V0cyksCisJLmRhcG1fcm91 dGVzCQk9IHBjbTE3ODlfZGFwbV9yb3V0ZXMsCisJLm51bV9kYXBtX3JvdXRlcwk9IEFSUkFZX1NJ WkUocGNtMTc4OV9kYXBtX3JvdXRlcyksCisJLmlkbGVfYmlhc19vbgkJPSAxLAorCS51c2VfcG1k b3duX3RpbWUJPSAxLAorCS5lbmRpYW5uZXNzCQk9IDEsCisJLm5vbl9sZWdhY3lfZGFpX25hbWlu Zwk9IDEsCit9OworCitpbnQgcGNtMTc4OV9jb21tb25faW5pdChzdHJ1Y3QgZGV2aWNlICpkZXYs IHN0cnVjdCByZWdtYXAgKnJlZ21hcCkKK3sKKwlzdHJ1Y3QgcGNtMTc4OV9wcml2YXRlICpwY20x Nzg5OworCisJcGNtMTc4OSA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZihzdHJ1Y3QgcGNtMTc4 OV9wcml2YXRlKSwKKwkJCSAgICAgICBHRlBfS0VSTkVMKTsKKwlpZiAoIXBjbTE3ODkpCisJCXJl dHVybiAtRU5PTUVNOworCisJcGNtMTc4OS0+cmVnbWFwID0gcmVnbWFwOworCXBjbTE3ODktPmRl diA9IGRldjsKKwlkZXZfc2V0X2RydmRhdGEoZGV2LCBwY20xNzg5KTsKKworCXBjbTE3ODktPnJl c2V0ID0gZGV2bV9ncGlvZF9nZXRfb3B0aW9uYWwoZGV2LCAicmVzZXQiLCBHUElPRF9PVVRfSElH SCk7CisJaWYgKElTX0VSUihwY20xNzg5LT5yZXNldCkpCisJCXJldHVybiBQVFJfRVJSKHBjbTE3 ODktPnJlc2V0KTsKKworCWdwaW9kX3NldF92YWx1ZV9jYW5zbGVlcChwY20xNzg5LT5yZXNldCwg MCk7CisJbXNsZWVwKDMwMCk7CisKKwlJTklUX1dPUksoJnBjbTE3ODktPndvcmssIHBjbTE3ODlf d29ya19xdWV1ZSk7CisKKwlyZXR1cm4gZGV2bV9zbmRfc29jX3JlZ2lzdGVyX2NvbXBvbmVudChk ZXYsICZzb2NfY29tcG9uZW50X2Rldl9wY20xNzg5LAorCQkJCQkgICAgICAgJnBjbTE3ODlfZGFp LCAxKTsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKHBjbTE3ODlfY29tbW9uX2luaXQpOworCitpbnQg cGNtMTc4OV9jb21tb25fZXhpdChzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3RydWN0IHBjbTE3 ODlfcHJpdmF0ZSAqcHJpdiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOworCisJaWYgKCZwcml2LT53 b3JrKQorCQlmbHVzaF93b3JrKCZwcml2LT53b3JrKTsKKworCXJldHVybiAwOworfQorRVhQT1JU X1NZTUJPTF9HUEwocGNtMTc4OV9jb21tb25fZXhpdCk7CisKK01PRFVMRV9ERVNDUklQVElPTigi QVNvQyBQQ00xNzg5IGRyaXZlciIpOworTU9EVUxFX0FVVEhPUigiTXlsw6huZSBKb3NzZXJhbmQg PG15bGVuZS5qb3NzZXJhbmRAZnJlZS1lbGVjdHJvbnMuY29tPiIpOworTU9EVUxFX0xJQ0VOU0Uo IkdQTCIpOwpkaWZmIC0tZ2l0IGEvc291bmQvc29jL2NvZGVjcy9wY20xNzg5LmggYi9zb3VuZC9z b2MvY29kZWNzL3BjbTE3ODkuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAw MDAuLjA1YzJjOGFkMmJhZAotLS0gL2Rldi9udWxsCisrKyBiL3NvdW5kL3NvYy9jb2RlY3MvcGNt MTc4OS5oCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBkZWZpbml0aW9ucyBmb3IgUENNMTc4OQor ICoKKyAqIENvcHlyaWdodCAoYykgQm9vdGxpbiAyMDE4CisgKgorICogVGhpcyBwcm9ncmFtIGlz IGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5 IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKKyAq IGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVy c2lvbiAyCisgKiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg dmVyc2lvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUg dGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0 aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3Ig RklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBHTlUgR2VuZXJh bCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKyNpZm5kZWYgX19QQ00x Nzg5X0hfXworI2RlZmluZSBfX1BDTTE3ODlfSF9fCisKKyNkZWZpbmUgUENNMTc4OV9GT1JNQVRT IChTTkRSVl9QQ01fRk1UQklUX1MzMl9MRSB8IFNORFJWX1BDTV9GTVRCSVRfUzI0X0xFIHwgXAor CQkJIFNORFJWX1BDTV9GTVRCSVRfUzE2X0xFKQorCitleHRlcm4gY29uc3Qgc3RydWN0IHJlZ21h cF9jb25maWcgcGNtMTc4OV9yZWdtYXBfY29uZmlnOworCitpbnQgcGNtMTc4OV9jb21tb25faW5p dChzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCByZWdtYXAgKnJlZ21hcCk7CitpbnQgcGNtMTc4 OV9jb21tb25fZXhpdChzdHJ1Y3QgZGV2aWNlICpkZXYpOworCisjZW5kaWYKLS0gCjIuMTEuMAoK X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KQWxzYS1kZXZl bCBtYWlsaW5nIGxpc3QKQWxzYS1kZXZlbEBhbHNhLXByb2plY3Qub3JnCmh0dHA6Ly9tYWlsbWFu LmFsc2EtcHJvamVjdC5vcmcvbWFpbG1hbi9saXN0aW5mby9hbHNhLWRldmVsCg==