[alsa-devel] [PATCH] ASoC: Add new TI TLV320AIC3204 CODEC driver
The TLV320AIC3204 is a low-power stereo audio CODEC capable of sample rates of up to 192kHz. This driver implements basic functionality, using I²C for the control channel.
The audio interface supports many data bus formats, including I²S master/slave, DSP, left/right justified and TDM.
What works: - Playback at various bitrates up to 96kHz - Recording at various bitrates up to 96kHz - Mixer interface - PLL generation of CODEC clocks from MCLK
What could work better: - DAPM
What isn't tested: - Audio interfaces other than I²S - PLL with clocks other than ~12MHz - Mono recording/playback - 192kHz recording/playback - Suspend & Resume
What isn't implemented: - SPI interface support - PLL without fractional divider (would allow <10MHz clocks) - Clock sources other than MCLK - Adaptive filtering - AGC - Headset detection, JACK framework
TODO list: - Clean up the register cache ... this is in the early planning phase
Signed-off-by: Stuart Longland redhatter@gentoo.org --- include/sound/tlv320aic3204.h | 64 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tlv320aic3204.c | 4197 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/tlv320aic3204.h | 1350 ++++++++++++ 5 files changed, 5618 insertions(+), 0 deletions(-) create mode 100644 include/sound/tlv320aic3204.h create mode 100644 sound/soc/codecs/tlv320aic3204.c create mode 100644 sound/soc/codecs/tlv320aic3204.h
diff --git a/include/sound/tlv320aic3204.h b/include/sound/tlv320aic3204.h new file mode 100644 index 0000000..491cd22 --- /dev/null +++ b/include/sound/tlv320aic3204.h @@ -0,0 +1,64 @@ +/* + * Platform data for Texas Instruments TLV320AIC3204 codec + * + * Copyright (C) 2010 Jacques Electronics Pty Ltd + * Author: Stuart Longland redhatter@gentoo.org + * + * Based on tlv320aic3x.h: + * Author: Jarkko Nikula jhnikula@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __TLV320AIC3204_H__ +#define __TLV320AIC3204_H__ + +/* + * Analogue Input Quick-Charge Power Up Delay + */ +enum { + /* Power up time: Default Value (whatever that is) */ + AIC3204_PDATA_AIN_PWRUP_DEFAULT = (0x00), + /* Power up time: 3.1ms */ + AIC3204_PDATA_AIN_PWRUP_3M1S = (0x31), + /* Power up time: 6.4ms */ + AIC3204_PDATA_AIN_PWRUP_6M4S = (0x32), + /* Power up time: 1.6ms */ + AIC3204_PDATA_AIN_PWRUP_1M6S = (0x33), +}; + +/* + * Analogue Reference Power Up Delay + */ +enum { + /* Reference Power-Up delay: Slow */ + AIC3204_PDATA_REF_PWRUP_SLOW = (0 << 0), + /* Reference Power-Up delay: 40ms */ + AIC3204_PDATA_REF_PWRUP_40MS = (1 << 0), + /* Reference Power-Up delay: 80ms */ + AIC3204_PDATA_REF_PWRUP_80MS = (2 << 0), + /* Reference Power-Up delay: 120ms */ + AIC3204_PDATA_REF_PWRUP_120MS = (3 << 0), +}; + +struct aic3204_pdata { + int gpio_reset; /* < 0 if not used */ + + /* Analogue-in Power up delay */ + u8 ain_pwrup_delay; + + /* Analogue Reference Power up delay */ + u8 ref_pwrup_delay; + + /* AVDD <->DVDD Link enable */ + u8 avdd_link_en; + + /* LDO Enable */ + u8 ldo_en; + + /* Oversampling rate (both ADC and DAC) */ + u8 osr; +}; + +#endif diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index c37c844..80b56a4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -32,6 +32,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_TLV320AIC23 if I2C select SND_SOC_TLV320AIC26 if SPI_MASTER + select SND_SOC_TLV320AIC3204 if I2C select SND_SOC_TLV320AIC3X if I2C select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C @@ -164,6 +165,10 @@ config SND_SOC_TLV320AIC26 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE depends on SPI
+config SND_SOC_TLV320AIC3204 + tristate + depends on I2C + config SND_SOC_TLV320AIC3X tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 4a9c205..c649f14 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -20,6 +20,7 @@ snd-soc-ssm2602-objs := ssm2602.o snd-soc-stac9766-objs := stac9766.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic26-objs := tlv320aic26.o +snd-soc-tlv320aic3204-objs := tlv320aic3204.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o snd-soc-tlv320dac33-objs := tlv320dac33.o snd-soc-twl4030-objs := twl4030.o @@ -86,6 +87,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o +obj-$(CONFIG_SND_SOC_TLV320AIC3204) += snd-soc-tlv320aic3204.o obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o diff --git a/sound/soc/codecs/tlv320aic3204.c b/sound/soc/codecs/tlv320aic3204.c new file mode 100644 index 0000000..6b185c5 --- /dev/null +++ b/sound/soc/codecs/tlv320aic3204.c @@ -0,0 +1,4197 @@ +/* + * ALSA SoC TLV320AIC3204 codec driver + * + * Author: Stuart Longland, redhatter@gentoo.org + * Copyright: (C) 2010 Jacques Electronics Pty. Ltd. + * + * Based upon the TLV320AIC3X driver: + * Author: Vladimir Barinov, vbarinov@embeddedalley.com + * Copyright: (C) 2007 MontaVista Software, Inc., source@mvista.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/device.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/regulator/consumer.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/initval.h> +#include <sound/tlv.h> +#include <sound/tlv320aic3204.h> + +#include "tlv320aic3204.h" + +/* + * Default settings; these will be used if no platform data is provided. + */ +static const struct aic3204_pdata aic3204_default_pdata = { + .gpio_reset = -1, + .ain_pwrup_delay = AIC3204_PDATA_AIN_PWRUP_DEFAULT, + .ref_pwrup_delay = AIC3204_PDATA_REF_PWRUP_SLOW, + .avdd_link_en = 1, + .ldo_en = 0, + .osr = 128, +}; + +/* + * Default Register Values; this is used to initialise the register cache. + * There are 128 pages, of 128 registers each stored here. The data was + * captured from a TLV320AIC3204 immediately after reset, and therefore should + * be representative of what's displayed in the datasheet. + */ +static const u8 aic3204_default_reg_data[128*128] = { + /* --- Page 0 --- */ + 0x00, 0x00, 0x50, 0x00, 0x00, 0x11, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x02, + 0x00, 0x08, 0x01, 0x01, 0x80, 0x01, 0x00, 0x04, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x03, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x14, + 0x0c, 0x00, 0x00, 0x00, 0x6f, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xee, 0x10, 0xd8, 0x7e, 0xe3, + 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 1 --- */ + 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 2 --- */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 3 --- */ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 4 --- */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 5 --- */ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 6 --- */ + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 7 --- */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 8 --- */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x7d, 0xd3, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 9 --- */ + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + + /* --- Page 10 --- */ + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 11 --- */ + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 12 --- */ + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 13 --- */ + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 14 --- */ + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 15 --- */ + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 16 --- */ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x7d, 0xd3, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 17 --- */ + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 18 --- */ + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 19 --- */ + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 20 --- */ + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 21 --- */ + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 22 --- */ + 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 23 --- */ + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 24 --- */ + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 25 --- */ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 26 --- */ + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x7d, 0xd3, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 27 --- */ + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + + /* --- Page 28 --- */ + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 29 --- */ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 30 --- */ + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 31 --- */ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 32 --- */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 33 --- */ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 34 --- */ + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x7d, 0xd3, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 35 --- */ + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 36 --- */ + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 37 --- */ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 38 --- */ + 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 39 --- */ + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 40 --- */ + 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 41 --- */ + 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 42 --- */ + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 43 --- */ + 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 44 --- */ + 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 45 --- */ + 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 46 --- */ + 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf7, 0x00, 0x00, + 0x80, 0x09, 0x00, 0x00, 0x7f, 0xef, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x7f, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 47 --- */ + 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 48 --- */ + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 49 --- */ + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 50 --- */ + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 51 --- */ + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 52 --- */ + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 53 --- */ + 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 54 --- */ + 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 55 --- */ + 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 56 --- */ + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 57 --- */ + 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 58 --- */ + 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 59 --- */ + 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 60 --- */ + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 61 --- */ + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 62 --- */ + 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 63 --- */ + 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 64 --- */ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf7, 0x00, 0x00, + 0x80, 0x09, 0x00, 0x00, 0x7f, 0xef, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x7f, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 65 --- */ + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 66 --- */ + 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 67 --- */ + 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 68 --- */ + 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 69 --- */ + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 70 --- */ + 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 71 --- */ + 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 72 --- */ + 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 73 --- */ + 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 74 --- */ + 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 75 --- */ + 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 76 --- */ + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 77 --- */ + 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 78 --- */ + 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 79 --- */ + 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 80 --- */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 81 --- */ + 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 82 --- */ + 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 83 --- */ + 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 84 --- */ + 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 85 --- */ + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 86 --- */ + 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 87 --- */ + 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 88 --- */ + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 89 --- */ + 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 90 --- */ + 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 91 --- */ + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 92 --- */ + 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 93 --- */ + 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 94 --- */ + 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 95 --- */ + 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 96 --- */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 97 --- */ + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 98 --- */ + 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 99 --- */ + 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 100 --- */ + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 101 --- */ + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 102 --- */ + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 103 --- */ + 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 104 --- */ + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 105 --- */ + 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 106 --- */ + 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 107 --- */ + 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 108 --- */ + 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 109 --- */ + 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 110 --- */ + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 111 --- */ + 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 112 --- */ + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 113 --- */ + 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 114 --- */ + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 115 --- */ + 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 116 --- */ + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 117 --- */ + 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 118 --- */ + 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 119 --- */ + 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 120 --- */ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 121 --- */ + 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 122 --- */ + 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 123 --- */ + 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 124 --- */ + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 125 --- */ + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 126 --- */ + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* --- Page 127 --- */ + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define AIC3204_NUM_SUPPLIES 4 +static const char *aic3204_supply_names[AIC3204_NUM_SUPPLIES] = { + "IOVDD", /* I/O Voltage */ + "DVDD", /* Digital Core Voltage */ + "AVDD", /* Analog DAC Voltage */ + "LDOin", /* Supply for internal LDOs and output amplifiers */ +}; + +/* codec private data */ +struct aic3204_priv { + struct snd_soc_codec codec; + struct regulator_bulk_data supplies[AIC3204_NUM_SUPPLIES]; + unsigned int sysclk; + struct aic3204_pdata pdata; +}; + +/* + * Determine whether a register is readable. + */ +static int aic3204_reg_is_readable(unsigned int reg) +{ + u8 page = reg >> 7; + reg &= 0x7f; + + /* Anything beyond page 70 is undefined */ + if (page > 70) + return 0; + + /* Page 62..70 */ + if (page >= 62) { + /* Register 0 is page select */ + if (reg == 0) + return 1; + /* Registers 1..7 are reserved */ + if (reg <= 7) + return 0; + /* Registers 8..127 are valid */ + return 1; + } + + /* Pages 53..62 are undefined */ + if (page >= 53) + return 0; + + /* Pages 45..52 */ + if (page >= 45) { + /* Register 0 is page select */ + if (reg == 0) + return 1; + /* Registers 1..7 are reserved */ + if (reg <= 7) + return 0; + /* Registers 8..127 are valid */ + return 1; + } + + /* Page 44 --- XXX The datasheet may have some typos here! */ + if (page == 44) { + /* + * Register 0 is page select + * Register 1 enables adaptive filtering + */ + if (reg <= 1) + return 1; + /* Registers 2..7 are reserved */ + if (reg <= 7) + return 0; + /* Registers 8..127 are valid */ + return 1; + } + + /* Pages 35..43 are undefined */ + if (page >= 35) + return 0; + + /* Pages 26..34 */ + if (page >= 26) { + /* Register 0 is page select */ + if (reg == 0) + return 1; + /* Registers 1..7 are reserved */ + if (reg <= 7) + return 0; + /* Registers 8..127 are valid */ + return 1; + } + + /* Pages 17..25 are undefined */ + if (page >= 17) + return 0; + + /* Pages 9..16 */ + if (page >= 9) { + if (reg == 0) + return 1; + if (reg <= 7) + return 0; + return 1; + } + + /* Page 8 */ + if (page == 8) { + if (reg <= 1) + return 1; + if (reg <= 7) + return 0; + return 1; + } + + /* Page 2..7 are undefined */ + if (page >= 2) + return 0; + + /* Page 1 */ + if (page == 1) { + if (reg <= 4) + return 1; + if (reg <= 8) + return 0; + if (reg <= 20) + return 1; + if (reg == 21) + return 0; + if (reg <= 25) + return 1; + if (reg <= 50) + return 0; + if (reg <= 52) + return 1; + if (reg == 53) + return 0; + if (reg <= 55) + return 1; + if (reg == 56) + return 0; + if (reg <= 63) + return 1; + if (reg <= 70) + return 0; + if (reg == 71) + return 1; + if (reg <= 122) + return 0; + if (reg == 123) + return 1; + return 0; + } + + /* Page 0 */ + if (reg == 0) + return 1; + if (reg <= 3) + return 0; + if (reg <= 8) + return 1; + if (reg <= 10) + return 0; + if (reg <= 14) + return 1; + if (reg <= 17) + return 0; + if (reg <= 20) + return 1; + if (reg <= 24) + return 0; + if (reg <= 34) + return 1; + if (reg == 35) + return 0; + if (reg <= 38) + return 1; + if (reg <= 41) + return 0; + if (reg <= 49) + return 1; + if (reg <= 51) + return 0; + if (reg <= 56) + return 1; + if (reg <= 59) + return 0; + if (reg <= 61) + return 1; + if (reg == 62) + return 0; + if (reg <= 79) + return 1; + if (reg == 80) + return 0; + if (reg <= 109) + return 1; + return 0; +} + +/* + * read aic3204 register cache + */ +static inline unsigned int aic3204_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u8 *cache = codec->reg_cache; + if (reg >= AIC3204_CACHEREGNUM) + return -EINVAL; + + return cache[reg]; +} + +/* + * Pretty-print the value of a register + */ +static int aic3204_show_reg(struct snd_soc_codec *codec, char *buf, + int buf_sz, unsigned int reg) +{ + return snprintf(buf, buf_sz, "%02x", + aic3204_read_reg_cache(codec, reg)); +} + +/* + * write aic3204 register cache + */ +static inline void aic3204_write_reg_cache(struct snd_soc_codec *codec, + u16 reg, u8 value) +{ + u8 *cache = codec->reg_cache; + + if (reg >= AIC3204_CACHEREGNUM) + return; + cache[reg] = value; +} + +/* + * write to the aic3204 register space + */ +static int aic3204_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + /* data is + * D15..D8 aic3204 register offset + * D7...D0 register data + */ + u8 data[2]; + + /* + * Register number; upper 8 bits indicate page + */ + if (reg && (aic3204_read_reg_cache(codec, AIC3204_PAGE_SELECT) + != (reg >> 7))) { + /* Select the required page */ + data[0] = 0; + data[1] = reg >> 7; + if (codec->hw_write(codec->control_data, data, 2) != 2) + return -EIO; + aic3204_write_reg_cache(codec, AIC3204_PAGE_SELECT, reg >> 7); + dev_dbg(codec->dev, "%s: Page %d selected\n", + __func__, reg >> 7); + } + + data[0] = reg & 0x7f; + data[1] = value & 0xff; + + if (codec->hw_write(codec->control_data, data, 2) != 2) + return -EIO; + + dev_dbg(codec->dev, "%s: pg %d reg %d[%04x] <= %02x\n", + __func__, reg >> 7, reg & 0x7f, reg, value); + aic3204_write_reg_cache(codec, reg, value); + return 0; +} + +/* + * read from the aic3204 register space + */ +static int aic3204_read(struct snd_soc_codec *codec, unsigned int reg, + u8 *value) +{ + *value = reg & 0xff; + + /* + * Register number; upper 8 bits indicate page + */ + if (reg && (aic3204_read_reg_cache(codec, AIC3204_PAGE_SELECT) + != (reg >> 7))) + /* Select the required page */ + aic3204_write(codec, AIC3204_PAGE_SELECT, (reg >> 7)); + + value[0] = i2c_smbus_read_byte_data(codec->control_data, value[0]); + dev_dbg(codec->dev, "%s: pg %d reg %d[%04x] => %02x\n", + __func__, reg >> 7, reg & 0x7f, reg, value[0]); + aic3204_write_reg_cache(codec, reg, *value); + return 0; +} + +/* + * Check BCLK direction. Returns >0 if the BCLK pin is an output, 0 if it's an + * input, or negative error. + */ +static inline int aic3204_check_bclk_is_output( + struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + int reg = snd_soc_read(source->codec, AIC3204_AISR1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR1_BCLK; + + return reg & AIC3204_AISR1_BCLK_OUT; +} + +/* + * Check WCLK direction. Returns >0 if the WCLK pin is an output, 0 if it's an + * input, or negative error. + */ + +static inline int aic3204_check_wclk_is_output( + struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + int reg = snd_soc_read(source->codec, AIC3204_AISR1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR1_WCLK; + + return reg & AIC3204_AISR1_WCLK_OUT; +} + +/* + * Check PLL source; called by the PLL input clock DAPM widgets. + * Returns 1 if the two given widgets are presently connected, 0 otherwise. + * Negative error number returned on error. + */ +static int aic3204_check_pll_clk_src(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + int reg = snd_soc_read(source->codec, AIC3204_CLK1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + + reg &= AIC3204_CLK1_PLLSRC; + + if (reg == AIC3204_CLK1_PLLSRC_MCLK) + reg = (!strcmp(source->name, "MCLK")); + else if (reg == AIC3204_CLK1_PLLSRC_BCLK) + reg = (!strcmp(source->name, "BCLK")); + else if (reg == AIC3204_CLK1_PLLSRC_GPIO) + reg = (!strcmp(source->name, "GPIO")); + else if (reg == AIC3204_CLK1_PLLSRC_DIN) + reg = (!strcmp(source->name, "DIN")); + else + reg = 0; + + if (reg) + dev_dbg(source->codec->dev, "%s: %s is connected to %s\n", + __func__, source->name, sink->name); + return reg; +} + +/* + * Check CODEC source; called by the CODEC_CLKIN input clock DAPM widgets. + * Returns 1 if the two given widgets are presently connected, 0 otherwise. + * Negative error number returned on error. + */ +static int aic3204_check_codec_clk_src(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + int reg = snd_soc_read(source->codec, AIC3204_CLK1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + + reg &= AIC3204_CLK1_CODECCLK; + + if (reg == AIC3204_CLK1_CODECCLK_MCLK) + reg = (!strcmp(source->name, "MCLK")); + else if (reg == AIC3204_CLK1_CODECCLK_BCLK) + reg = (!strcmp(source->name, "BCLK")); + else if (reg == AIC3204_CLK1_CODECCLK_GPIO) + reg = (!strcmp(source->name, "GPIO")); + else if (reg == AIC3204_CLK1_CODECCLK_PLL) + reg = (!strcmp(source->name, "PLL_CLK")); + else + reg = 0; + + if (reg) + dev_dbg(source->codec->dev, "%s: %s is connected to %s\n", + __func__, source->name, sink->name); + return reg; +} + +/* + * Check BCLK source; called by the BCLK input clock DAPM widgets. + * Returns 1 if the two given widgets are presently connected, 0 otherwise. + * Negative error number returned on error. + */ +static int aic3204_check_bclk_src(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + int reg = snd_soc_read(source->codec, AIC3204_AISR1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR1_BCLK; + + if (reg == AIC3204_AISR1_BCLK_IN) + /* BCLK is externally generated */ + return 0; + + reg = snd_soc_read(source->codec, AIC3204_AISR3); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR3_BDIV; + + if (reg == AIC3204_AISR3_BDIV_DAC) + reg = (!strcmp(source->name, "DAC_CLK")); + else if (reg == AIC3204_AISR3_BDIV_DAC_MOD) + reg = (!strcmp(source->name, "DAC_MOD_CLK")); + else if (reg == AIC3204_AISR3_BDIV_ADC) + reg = (!strcmp(source->name, "ADC_CLK")); + else if (reg == AIC3204_AISR3_BDIV_ADC_MOD) + reg = (!strcmp(source->name, "ADC_MOD_CLK")); + else + reg = 0; + + if (reg) + dev_dbg(source->codec->dev, "%s: %s is connected to %s\n", + __func__, source->name, sink->name); + return reg; +} + +/* + * Check WCLK source; called by the WCLK input clock DAPM widgets. + * Returns 1 if the two given widgets are presently connected, 0 otherwise. + * Negative error number returned on error. + */ +static int aic3204_check_wclk_src(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + int reg = snd_soc_read(source->codec, AIC3204_AISR1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR1_WCLK; + + if (reg == AIC3204_AISR1_WCLK_IN) + /* WCLK is externally generated */ + return 0; + + reg = snd_soc_read(source->codec, AIC3204_AISR6); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR6_WCLKOUT; + + if (reg == AIC3204_AISR6_WCLKOUT_DAC) + reg = (!strcmp(source->name, "DAC_FS")); + else if (reg == AIC3204_AISR6_WCLKOUT_ADC) + reg = (!strcmp(source->name, "ADC_FS")); + else + reg = 0; + + if (reg) + dev_dbg(source->codec->dev, "%s: %s is connected to %s\n", + __func__, source->name, sink->name); + + return reg; +} + +/* + * Event handler for audio interface BCLK; checks the state of the ADCs and + * DACs and switches the audio interface to the presently active clock. + */ +static int aic3204_aif_bclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { + u8 adcs_up; + u8 dacs_up; + u8 bclk_src; + /* Determine the current source */ + int reg = snd_soc_read(w->codec, AIC3204_AISR1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR1_BCLK; + if (reg == AIC3204_AISR1_BCLK_IN) + /* BCLK is an input, not our concirn */ + return 0; + + reg = snd_soc_read(w->codec, AIC3204_AISR3); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + bclk_src = reg & AIC3204_AISR3_BDIV; + + /* + * These registers are not manipulated by us, so we must read them from + * the CODEC directly. + */ + reg = aic3204_read(w->codec, AIC3204_ADCF, &adcs_up); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + adcs_up &= (AIC3204_ADCF_LEFT_UP | AIC3204_ADCF_RIGHT_UP); + + reg = aic3204_read(w->codec, AIC3204_DACF1, &dacs_up); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + dacs_up &= (AIC3204_DACF1_LEFT_UP | AIC3204_DACF1_RIGHT_UP); + + dev_dbg(w->codec->dev, "%s: BCLK source=0x%02x, event=%d, " + "dacf1=0x%02x, adcf=0x%02x\n", __func__, bclk_src, + event, dacs_up, adcs_up); + + /* What are we set to now? */ + if (bclk_src == AIC3204_AISR3_BDIV_DAC) { + /* Currently listening to DAC... check that it's up */ + if (adcs_up && !dacs_up) + /* No, but the ADCs are up; switch to those */ + bclk_src = AIC3204_AISR3_BDIV_ADC; + } else if (bclk_src == AIC3204_AISR3_BDIV_DAC_MOD) { + /* Currently listening to DAC... check that it's up */ + if (adcs_up && !dacs_up) + /* No, but the ADCs are up; switch to those */ + bclk_src = AIC3204_AISR3_BDIV_ADC_MOD; + } else if (bclk_src == AIC3204_AISR3_BDIV_ADC) { + /* Currently listening to ADC... check that it's up */ + if (dacs_up && !adcs_up) + /* No, but the DACs are up; switch to those */ + bclk_src = AIC3204_AISR3_BDIV_DAC; + } else if (bclk_src == AIC3204_AISR3_BDIV_ADC_MOD) { + /* Currently listening to ADC... check that it's up */ + if (adcs_up && !dacs_up) + /* No, but the DACs are up; switch to those */ + bclk_src = AIC3204_AISR3_BDIV_DAC_MOD; + } + + dev_dbg(w->codec->dev, "%s: setting source 0x%02x\n", + __func__, bclk_src); + + snd_soc_update_bits(w->codec, AIC3204_AISR3, + AIC3204_AISR3_BDIV, bclk_src); + return 0; +} + +/* + * Event handler for audio interface WCLK; checks the state of the ADCs and + * DACs and switches the audio interface to the presently active clock. + */ +static int aic3204_aif_wclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { + u8 wclk_src; + u8 adcs_up; + u8 dacs_up; + /* Determine the current source */ + int reg = snd_soc_read(w->codec, AIC3204_AISR1); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + reg &= AIC3204_AISR1_WCLK; + + if (reg == AIC3204_AISR1_WCLK_IN) + /* WCLK is an input, not our concirn */ + return 0; + + reg = snd_soc_read(w->codec, AIC3204_AISR6); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + wclk_src = reg & AIC3204_AISR6_WCLKOUT; + + /* + * These registers are not manipulated by us, so we must read them from + * the CODEC directly. + */ + reg = aic3204_read(w->codec, AIC3204_ADCF, &adcs_up); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + adcs_up &= (AIC3204_ADCF_LEFT_UP | AIC3204_ADCF_RIGHT_UP); + + reg = aic3204_read(w->codec, AIC3204_DACF1, &dacs_up); + if (reg < 0) { + printk(KERN_WARNING "%s: read returned %d\n", __func__, reg); + return reg; + } + dacs_up &= (AIC3204_DACF1_LEFT_UP | AIC3204_DACF1_RIGHT_UP); + + dev_dbg(w->codec->dev, "%s: WCLK source=0x%02x, event=%d, " + "dacf1=0x%02x, adcf=0x%02x\n", __func__, wclk_src, + event, dacs_up, adcs_up); + + /* What are we set to now? */ + if (wclk_src == AIC3204_AISR6_WCLKOUT_DAC) { + /* Currently listening to DAC... check that it's up */ + if (adcs_up && !dacs_up) + /* No, but the ADCs are up; switch to those */ + wclk_src = AIC3204_AISR6_WCLKOUT_ADC; + } else if (wclk_src == AIC3204_AISR6_WCLKOUT_ADC) { + /* Currently listening to ADC... check that it's up */ + if (dacs_up && !adcs_up) + /* No, but the DACs are up; switch to those */ + wclk_src = AIC3204_AISR6_WCLKOUT_DAC; + } + + dev_dbg(w->codec->dev, "%s: setting source 0x%02x\n", + __func__, wclk_src); + + snd_soc_update_bits(w->codec, AIC3204_AISR6, + AIC3204_AISR6_WCLKOUT, wclk_src); + return 0; +} + +/* + * For MICPGA inputs; inputs may either be disconnected, or connected via one + * of three resistances. + */ +static const char *aic3204_micpga_input_mux[] = { + "not-connected", "10k", "20k", "40k" +}; + +static struct soc_enum aic3204_enum_in1l_lmicpgap = + SOC_ENUM_SINGLE(AIC3204_LMICPGAPROUTE, + 6, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in2l_lmicpgap = + SOC_ENUM_SINGLE(AIC3204_LMICPGAPROUTE, + 4, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in3l_lmicpgap = + SOC_ENUM_SINGLE(AIC3204_LMICPGAPROUTE, + 2, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in1r_lmicpgap = + SOC_ENUM_SINGLE(AIC3204_LMICPGAPROUTE, + 0, 4, aic3204_micpga_input_mux); + +static struct soc_enum aic3204_enum_cm1l_lmicpgan = + SOC_ENUM_SINGLE(AIC3204_LMICPGANROUTE, + 6, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in2r_lmicpgan = + SOC_ENUM_SINGLE(AIC3204_LMICPGANROUTE, + 4, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in3r_lmicpgan = + SOC_ENUM_SINGLE(AIC3204_LMICPGANROUTE, + 2, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_cm2l_lmicpgan = + SOC_ENUM_SINGLE(AIC3204_LMICPGANROUTE, + 0, 4, aic3204_micpga_input_mux); + +static struct soc_enum aic3204_enum_in1r_rmicpgap = + SOC_ENUM_SINGLE(AIC3204_RMICPGAPROUTE, + 6, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in2r_rmicpgap = + SOC_ENUM_SINGLE(AIC3204_RMICPGAPROUTE, + 4, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in3r_rmicpgap = + SOC_ENUM_SINGLE(AIC3204_RMICPGAPROUTE, + 2, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in2l_rmicpgap = + SOC_ENUM_SINGLE(AIC3204_RMICPGAPROUTE, + 0, 4, aic3204_micpga_input_mux); + +static struct soc_enum aic3204_enum_cm1r_rmicpgan = + SOC_ENUM_SINGLE(AIC3204_RMICPGANROUTE, + 6, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in1l_rmicpgan = + SOC_ENUM_SINGLE(AIC3204_RMICPGANROUTE, + 4, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_in3l_rmicpgan = + SOC_ENUM_SINGLE(AIC3204_RMICPGANROUTE, + 2, 4, aic3204_micpga_input_mux); +static struct soc_enum aic3204_enum_cm2r_rmicpgan = + SOC_ENUM_SINGLE(AIC3204_RMICPGANROUTE, + 0, 4, aic3204_micpga_input_mux); + +/* + * MICBIAS Voltages; The exact voltage depends on the common mode voltage + * setting... + * + * CM=0.75V CM=0.9V + * Low 1.04V 1.25V + * Medium 1.425V 1.7V + * High 2.075V 2.5V + * V+ Connects to power supply directly in both cases. + */ +static const char *aic3204_micbias_voltages[] = { + "Low", "Med", "High", "V+" +}; +static struct soc_enum aic3204_enum_micbias_voltage = + SOC_ENUM_SINGLE(AIC3204_MICBIAS, + 4, 4, aic3204_micbias_voltages); + +/* + * MICBIAS Voltage Source + */ +static const char *aic3204_micbias_srcs[] = { + "AVDD", "LDOIN" +}; +static struct soc_enum aic3204_enum_micbias_src = + SOC_ENUM_SINGLE(AIC3204_MICBIAS, + 3, 2, aic3204_micbias_srcs); + +/* + * Left DAC Data Source + */ +static const char *aic3204_ldac_srcs[] = { + "disabled", "left channel", "right channel", "mix" +}; +static struct soc_enum aic3204_enum_ldac_src = + SOC_ENUM_SINGLE(AIC3204_DACS1, + 4, 4, aic3204_ldac_srcs); + +/* + * Right DAC Data Source + */ +static const char *aic3204_rdac_srcs[] = { + "disabled", "right channel", "left channel", "mix" +}; +static struct soc_enum aic3204_enum_rdac_src = + SOC_ENUM_SINGLE(AIC3204_DACS1, + 2, 4, aic3204_rdac_srcs); + +/* + * DAC digital volumes. From -63.5 to +24 dB in 0.5 dB steps. + * Does not mute control. + */ +static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0); +/* + * ADC gain volumes. From -12dB to 20 dB in 0.5dB steps. + * Does not mute control. + */ +static DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 50, 0); +#if 0 +/* + * ADC Fine gain volumes. From -0.4 to 0 dB in 0.1dB steps + * Does not mute control. + */ +static DECLARE_TLV_DB_SCALE(adc_fine_tlv, -40, 10, 0); +#endif +/* + * Output driver stage volumes; -6dB through to +29dB in 1dB steps + * Does not mute control. + */ +static DECLARE_TLV_DB_SCALE(output_stage_tlv, -600, 100, 0); +/* + * MICPGA volumes; 0dB through to +47.5dB in 0.5dB steps. + * Does not mute control + */ +static DECLARE_TLV_DB_SCALE(micpga_tlv, 0, 50, 0); + +static const struct snd_kcontrol_new aic3204_snd_controls[] = { + /* Output */ + + /* + * Note regarding SOC_DOUBLE_R_SX_TLV... + * + * This is a bit misleading; xshift refers to the bit one bit *past* + * the most significant bit. Or at least that's what it appears to be + * doing the math. Mask needs to select the last 6 bits; which is the + * signed bitfield specifiying the gain in dB. + */ + SOC_DOUBLE_R_SX_TLV("Headphone Output Volume", + AIC3204_HPLGAIN, AIC3204_HPRGAIN, + 6, -6, 29, output_stage_tlv), + SOC_DOUBLE_R("Headphone Output Playback Switch", + AIC3204_HPLGAIN, AIC3204_HPRGAIN, + AIC3204_HPLGAIN_MUTE_SHIFT, 0x01, 1), + SOC_DOUBLE_R_SX_TLV("Line Output Playback Volume", + AIC3204_LOLGAIN, AIC3204_LORGAIN, + 6, -6, 29, output_stage_tlv), + SOC_DOUBLE_R("Line Output Playback Switch", AIC3204_LOLGAIN, + AIC3204_LORGAIN, AIC3204_LOLGAIN_MUTE_SHIFT, 0x01, 1), + SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", + AIC3204_LDACVOL, AIC3204_RDACVOL, + 8, -127, 48, dac_tlv), + SOC_DOUBLE("PCM Playback Switch", AIC3204_DACS2, + AIC3204_DACS2_LEFT_MUTE_SHIFT, + AIC3204_DACS2_RIGHT_MUTE_SHIFT, 0x01, 1), + SOC_DOUBLE_R_SX_TLV("Mixer Amplifier Volume", + AIC3204_MALGAIN, AIC3204_MARGAIN, + 6, -6, 29, output_stage_tlv), + + /* DAC Options */ + SOC_ENUM("Left Playback Source", aic3204_enum_ldac_src), + SOC_ENUM("Right Playback Source", aic3204_enum_rdac_src), + SOC_SINGLE("Differential Output Switch", AIC3204_DACS2, + AIC3204_DACS2_RMOD_INV_SHIFT, 1, 0), + + /* MICPGA Options */ + SOC_DOUBLE_R_TLV("MICPGA Capture Volume", + AIC3204_LMICPGAVOL, AIC3204_RMICPGAVOL, + 0, 95, 0, micpga_tlv), + SOC_DOUBLE_R("MICPGA Capture Switch", + AIC3204_LMICPGAVOL, AIC3204_RMICPGAVOL, 7, 0x1, 1), + + /* MICBIAS Options */ + SOC_SINGLE("MICBIAS Enable", AIC3204_MICBIAS, 6, 0x1, 0), + SOC_ENUM("MICBIAS Level", aic3204_enum_micbias_voltage), + SOC_ENUM("MICBIAS Source", aic3204_enum_micbias_src), + + /* ADC */ + SOC_DOUBLE_R_SX_TLV("PCM Capture Volume", + AIC3204_LADCVOL, AIC3204_RADCVOL, + 7, -24, 40, adc_tlv), + SOC_DOUBLE("PCM Capture Switch", AIC3204_ADCFINE, 7, 3, 0x01, 1), + + /* Driver/Amplifier Selection -- DAPM should handle this! */ + SOC_DOUBLE("HP Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_HPL_UP_SHIFT, + AIC3204_OUTDRV_HPR_UP_SHIFT, 0x1, 0), + SOC_DOUBLE("LO Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_LOL_UP_SHIFT, + AIC3204_OUTDRV_LOR_UP_SHIFT, 0x1, 0), + SOC_DOUBLE("MA Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_MAL_UP_SHIFT, + AIC3204_OUTDRV_MAR_UP_SHIFT, 0x1, 0), +}; + +/* Driver/Amplifier Selection */ +static const struct snd_kcontrol_new aic3204_hpl_switch = + SOC_DAPM_SINGLE("Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_HPL_UP_SHIFT, 0x1, 0); +static const struct snd_kcontrol_new aic3204_hpr_switch = + SOC_DAPM_SINGLE("Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_HPR_UP_SHIFT, 0x1, 0); +static const struct snd_kcontrol_new aic3204_lol_switch = + SOC_DAPM_SINGLE("Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_LOL_UP_SHIFT, 0x1, 0); +static const struct snd_kcontrol_new aic3204_lor_switch = + SOC_DAPM_SINGLE("Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_LOR_UP_SHIFT, 0x1, 0); +static const struct snd_kcontrol_new aic3204_mal_switch = + SOC_DAPM_SINGLE("Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_MAL_UP_SHIFT, 0x1, 0); +static const struct snd_kcontrol_new aic3204_mar_switch = + SOC_DAPM_SINGLE("Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_MAR_UP_SHIFT, 0x1, 0); + +/* Line Output Left Driver Inputs */ +static const struct snd_kcontrol_new aic3204_lol_in_controls[] = { + SOC_DAPM_SINGLE("LOR Switch", AIC3204_LOLROUTE, + AIC3204_LOLROUTE_LOR_SHIFT, 1, 0), + SOC_DAPM_SINGLE("MAL Switch", AIC3204_LOLROUTE, + AIC3204_LOLROUTE_MAL_SHIFT, 1, 0), + SOC_DAPM_SINGLE("LDAC+ Switch", AIC3204_LOLROUTE, + AIC3204_LOLROUTE_LDACP_SHIFT, 1, 0), + SOC_DAPM_SINGLE("RDAC- Switch", AIC3204_LOLROUTE, + AIC3204_LOLROUTE_RDACN_SHIFT, 1, 0), +}; + +/* Line Output Right Driver Inputs */ +static const struct snd_kcontrol_new aic3204_lor_in_controls[] = { + SOC_DAPM_SINGLE("MAR Switch", AIC3204_LORROUTE, + AIC3204_LORROUTE_MAR_SHIFT, 1, 0), + SOC_DAPM_SINGLE("RDAC+ Switch", AIC3204_LORROUTE, + AIC3204_LORROUTE_RDACP_SHIFT, 1, 0), +}; + +/* Headphone Output Left Driver Inputs */ +static const struct snd_kcontrol_new aic3204_hpl_in_controls[] = { + SOC_DAPM_SINGLE("MAR Switch", AIC3204_HPLROUTE, + AIC3204_HPLROUTE_MAR_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("MAL Switch", AIC3204_HPLROUTE, + AIC3204_HPLROUTE_MAL_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("IN1L Switch", AIC3204_HPLROUTE, + AIC3204_HPLROUTE_IN1L_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("LDAC+ Switch", AIC3204_HPLROUTE, + AIC3204_HPLROUTE_LDACP_SHIFT, 0x1, 0), +}; + +/* Headphone Output Right Driver Inputs */ +static const struct snd_kcontrol_new aic3204_hpr_in_controls[] = { + SOC_DAPM_SINGLE("HPL Switch", AIC3204_HPRROUTE, + AIC3204_HPRROUTE_HPL_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("MAR Switch", AIC3204_HPRROUTE, + AIC3204_HPRROUTE_MAR_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("IN1R Switch", AIC3204_HPRROUTE, + AIC3204_HPRROUTE_IN1R_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("RDAC+ Switch", AIC3204_HPRROUTE, + AIC3204_HPRROUTE_RDACP_SHIFT, 0x1, 0), + SOC_DAPM_SINGLE("LDAC- Switch", AIC3204_HPRROUTE, + AIC3204_HPRROUTE_LDACN_SHIFT, 0x1, 0), +}; + +static const struct snd_kcontrol_new aic3204_lmicpgap_in_controls[] = { + SOC_DAPM_ENUM("IN1L Switch", aic3204_enum_in1l_lmicpgap), + SOC_DAPM_ENUM("IN2L Switch", aic3204_enum_in2l_lmicpgap), + SOC_DAPM_ENUM("IN3L Switch", aic3204_enum_in3l_lmicpgap), + SOC_DAPM_ENUM("IN1R Switch", aic3204_enum_in1r_lmicpgap), +}; + +static const struct snd_kcontrol_new aic3204_lmicpgan_in_controls[] = { + SOC_DAPM_ENUM("CM1L Switch", aic3204_enum_cm1l_lmicpgan), + SOC_DAPM_ENUM("IN2R Switch", aic3204_enum_in2r_lmicpgan), + SOC_DAPM_ENUM("IN3R Switch", aic3204_enum_in3r_lmicpgan), + SOC_DAPM_ENUM("CM2L Switch", aic3204_enum_cm2l_lmicpgan), +}; + +static const struct snd_kcontrol_new aic3204_rmicpgap_in_controls[] = { + SOC_DAPM_ENUM("IN1R Switch", aic3204_enum_in1r_rmicpgap), + SOC_DAPM_ENUM("IN2R Switch", aic3204_enum_in2r_rmicpgap), + SOC_DAPM_ENUM("IN3R Switch", aic3204_enum_in3r_rmicpgap), + SOC_DAPM_ENUM("IN2L Switch", aic3204_enum_in2l_rmicpgap), +}; + +static const struct snd_kcontrol_new aic3204_rmicpgan_in_controls[] = { + SOC_DAPM_ENUM("CM1R Switch", aic3204_enum_cm1r_rmicpgan), + SOC_DAPM_ENUM("IN1L Switch", aic3204_enum_in1l_rmicpgan), + SOC_DAPM_ENUM("IN3L Switch", aic3204_enum_in3l_rmicpgan), + SOC_DAPM_ENUM("CM2R Switch", aic3204_enum_cm2r_rmicpgan), +}; + +static const struct snd_soc_dapm_widget aic3204_dapm_widgets[] = { + /* Driver/Amplifier Selection */ + SND_SOC_DAPM_SWITCH("HPL Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_HPL_UP_SHIFT, 0, + &aic3204_hpl_switch), + SND_SOC_DAPM_SWITCH("HPR Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_HPR_UP_SHIFT, 0, + &aic3204_hpr_switch), + SND_SOC_DAPM_SWITCH("LOL Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_LOL_UP_SHIFT, 0, + &aic3204_lol_switch), + SND_SOC_DAPM_SWITCH("LOR Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_LOR_UP_SHIFT, 0, + &aic3204_lor_switch), + SND_SOC_DAPM_SWITCH("MAL Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_MAL_UP_SHIFT, 0, + &aic3204_mal_switch), + SND_SOC_DAPM_SWITCH("MAR Playback Switch", AIC3204_OUTDRV, + AIC3204_OUTDRV_MAR_UP_SHIFT, 0, + &aic3204_mar_switch), + + /* Line Output Driver Inputs */ + SND_SOC_DAPM_MIXER("Left Line Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_lol_in_controls, + ARRAY_SIZE(aic3204_lol_in_controls)), + SND_SOC_DAPM_MIXER("Right Line Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_lor_in_controls, + ARRAY_SIZE(aic3204_lor_in_controls)), + + /* Headphone Output Driver Inputs */ + SND_SOC_DAPM_MIXER("Left Headphone Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_hpl_in_controls, + ARRAY_SIZE(aic3204_hpl_in_controls)), + SND_SOC_DAPM_MIXER("Right Headphone Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_hpr_in_controls, + ARRAY_SIZE(aic3204_hpr_in_controls)), + + /* DACs, ADCs and audio interfaces */ + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC3204_DACS1, + AIC3204_DACS1_LDAC_UP_SHIFT, 0), + SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC3204_DACS1, + AIC3204_DACS1_RDAC_UP_SHIFT, 0), + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC3204_ADCS, + AIC3204_ADCS_RADC_UP_SHIFT, 0), + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC3204_ADCS, + AIC3204_ADCS_RADC_UP_SHIFT, 0), + SND_SOC_DAPM_AIF_IN("Left Data In", "Left Playback", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("Right Data In", "Right Playback", + 1, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("Left Data Out", "Left Capture", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("Right Data Out", "Right Capture", + 1, SND_SOC_NOPM, 0, 0), + + /* System clock sources */ + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("BCLK", AIC3204_CLK12, + AIC3204_CLK12_BCLK_STATE_SHIFT, 0, + aic3204_aif_bclk_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("WCLK", SND_SOC_NOPM, 0, 0, + aic3204_aif_wclk_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("GPIO", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DIN", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("PLL_CLK", AIC3204_CLK2, + AIC3204_CLK2_PLL_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("CODEC_CLKIN", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC_CLK", AIC3204_CLK6, + AIC3204_CLK6_NDAC_STATE_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC_MOD_CLK", AIC3204_CLK7, + AIC3204_CLK7_MDAC_STATE_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("ADC_CLK", AIC3204_CLK8, + AIC3204_CLK8_NADC_STATE_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("ADC_MOD_CLK", AIC3204_CLK9, + AIC3204_CLK9_MADC_STATE_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC_FS", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("ADC_FS", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* MICPGA Input Sources */ + SND_SOC_DAPM_MIXER("Left MICPGA+ Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_lmicpgap_in_controls, + ARRAY_SIZE(aic3204_lmicpgap_in_controls)), + SND_SOC_DAPM_MIXER("Left MICPGA- Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_lmicpgan_in_controls, + ARRAY_SIZE(aic3204_lmicpgan_in_controls)), + SND_SOC_DAPM_MIXER("Right MICPGA+ Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_rmicpgap_in_controls, + ARRAY_SIZE(aic3204_rmicpgap_in_controls)), + SND_SOC_DAPM_MIXER("Right MICPGA- Output Mixer", SND_SOC_NOPM, 0, 0, + aic3204_rmicpgan_in_controls, + ARRAY_SIZE(aic3204_rmicpgan_in_controls)), + SND_SOC_DAPM_PGA("Left MICPGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("Right MICPGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MICBIAS("Mic Bias", AIC3204_MICBIAS, 6, 0), + + /* Bypass PGAs */ + SND_SOC_DAPM_PGA("IN1L Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("IN1R Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* Input Pins */ + SND_SOC_DAPM_INPUT("IN1L"), + SND_SOC_DAPM_INPUT("IN1R"), + SND_SOC_DAPM_INPUT("IN2L"), + SND_SOC_DAPM_INPUT("IN2R"), + SND_SOC_DAPM_INPUT("IN3L"), + SND_SOC_DAPM_INPUT("IN3R"), + + /* Output Pins */ + SND_SOC_DAPM_OUTPUT("LOL"), + SND_SOC_DAPM_OUTPUT("LOR"), + SND_SOC_DAPM_OUTPUT("HPL"), + SND_SOC_DAPM_OUTPUT("HPR"), + + /* Common-mode pins */ + SND_SOC_DAPM_VMID("CM1L"), + SND_SOC_DAPM_VMID("CM1R"), + SND_SOC_DAPM_VMID("CM2L"), + SND_SOC_DAPM_VMID("CM2R"), +}; + +static const struct snd_soc_dapm_route intercon[] = { + /* Clock Signals and routing */ + {"PLL_CLK", NULL, "MCLK", aic3204_check_pll_clk_src}, + {"PLL_CLK", NULL, "BCLK", aic3204_check_pll_clk_src}, + {"PLL_CLK", NULL, "GPIO", aic3204_check_pll_clk_src}, + {"PLL_CLK", NULL, "DIN", aic3204_check_pll_clk_src}, + {"CODEC_CLKIN", NULL, "MCLK", aic3204_check_codec_clk_src}, + {"CODEC_CLKIN", NULL, "BCLK", aic3204_check_codec_clk_src}, + {"CODEC_CLKIN", NULL, "GPIO", aic3204_check_codec_clk_src}, + {"CODEC_CLKIN", NULL, "PLL_CLK", aic3204_check_codec_clk_src}, + {"DAC_CLK", NULL, "CODEC_CLKIN"}, + {"DAC_MOD_CLK", NULL, "DAC_CLK"}, + {"DAC_FS", NULL, "DAC_MOD_CLK"}, + {"ADC_CLK", NULL, "CODEC_CLKIN"}, + {"ADC_MOD_CLK", NULL, "ADC_CLK"}, + {"ADC_FS", NULL, "ADC_MOD_CLK"}, + {"BCLK", NULL, "DAC_CLK", aic3204_check_bclk_src}, + {"BCLK", NULL, "DAC_MOD_CLK", aic3204_check_bclk_src}, + {"BCLK", NULL, "ADC_CLK", aic3204_check_bclk_src}, + {"BCLK", NULL, "ADC_MOD_CLK", aic3204_check_bclk_src}, + {"WCLK", NULL, "DAC_FS", aic3204_check_wclk_src}, + {"WCLK", NULL, "ADC_FS", aic3204_check_wclk_src}, + + /* Clock sinks */ + {"Left DAC", NULL, "DAC_MOD_CLK"}, + {"Right DAC", NULL, "DAC_MOD_CLK"}, + {"Left ADC", NULL, "ADC_MOD_CLK"}, + {"Right ADC", NULL, "ADC_MOD_CLK"}, + {"Left Data Out", NULL, "BCLK", aic3204_check_bclk_is_output}, + {"Right Data Out", NULL, "BCLK", aic3204_check_bclk_is_output}, + {"Left Data Out", NULL, "WCLK", aic3204_check_wclk_is_output}, + {"Right Data Out", NULL, "WCLK", aic3204_check_wclk_is_output}, + {"Left Data In", NULL, "BCLK", aic3204_check_bclk_is_output}, + {"Right Data In", NULL, "BCLK", aic3204_check_bclk_is_output}, + {"Left Data In", NULL, "WCLK", aic3204_check_wclk_is_output}, + {"Right Data In", NULL, "WCLK", aic3204_check_wclk_is_output}, + + /* Data Connections */ + {"Left Data Out", NULL, "Left ADC"}, + {"Right Data Out", NULL, "Right ADC"}, + {"Left DAC", NULL, "Left Data In"}, + {"Right DAC", NULL, "Right Data In"}, + + /* Line Output */ + {"Left Line Output Mixer", "LOR Switch", "Right Line Output Mixer"}, + {"Left Line Output Mixer", "MAL Switch", "Left MICPGA"}, + {"Left Line Output Mixer", "LDAC+ Switch", "Left DAC"}, + {"Left Line Output Mixer", "RDAC- Switch", "Right DAC"}, + {"Right Line Output Mixer", "MAR Switch", "Right MICPGA"}, + {"Right Line Output Mixer", "RDAC+ Switch", "Right DAC"}, + {"LOL", "LOL Playback Switch", "Left Line Output Mixer"}, + {"LOR", "LOR Playback Switch", "Right Line Output Mixer"}, + + /* Headphone Output */ + {"Left Headphone Output Mixer", "MAR Switch", "Right MICPGA"}, + {"Left Headphone Output Mixer", "MAL Switch", "Left MICPGA"}, + {"Left Headphone Output Mixer", "IN1L Switch", "IN1L Bypass PGA"}, + {"Left Headphone Output Mixer", "LDAC+ Switch", "Left DAC"}, + {"Right Headphone Output Mixer", "HPL Switch", + "Left Headphone Output Mixer"}, + {"Right Headphone Output Mixer", "MAR Switch", "Right MICPGA"}, + {"Right Headphone Output Mixer", "IN1R Switch", "IN1R Bypass PGA"}, + {"Right Headphone Output Mixer", "RDAC+ Switch", "Right DAC"}, + {"Right Headphone Output Mixer", "LDAC- Switch", "Left DAC"}, + {"HPL", "HPL Playback Switch", "Left Headphone Output Mixer"}, + {"HPR", "HPR Playback Switch", "Right Headphone Output Mixer"}, + + /* MICPGA Input */ + {"Left MICPGA+ Output Mixer", "IN1L Switch", "IN1L"}, + {"Left MICPGA+ Output Mixer", "IN2L Switch", "IN2L"}, + {"Left MICPGA+ Output Mixer", "IN3L Switch", "IN3L"}, + {"Left MICPGA+ Output Mixer", "IN1R Switch", "IN1R"}, + {"Left MICPGA- Output Mixer", "CM1L Switch", "CM1L"}, + {"Left MICPGA- Output Mixer", "IN2R Switch", "IN2R"}, + {"Left MICPGA- Output Mixer", "IN3R Switch", "IN3R"}, + {"Left MICPGA- Output Mixer", "CM2L Switch", "CM2L"}, + {"Right MICPGA+ Output Mixer", "IN1R Switch", "IN1R"}, + {"Right MICPGA+ Output Mixer", "IN2R Switch", "IN2R"}, + {"Right MICPGA+ Output Mixer", "IN3R Switch", "IN3R"}, + {"Right MICPGA+ Output Mixer", "IN2L Switch", "IN2L"}, + {"Right MICPGA- Output Mixer", "CM1R Switch", "CM1R"}, + {"Right MICPGA- Output Mixer", "IN1L Switch", "IN1L"}, + {"Right MICPGA- Output Mixer", "IN3L Switch", "IN3L"}, + {"Right MICPGA- Output Mixer", "CM2R Switch", "CM2R"}, + {"Left MICPGA", "MAL Playback Switch", "Left MICPGA+ Output Mixer"}, + {"Right MICPGA", "MAR Playback Switch", "Right MICPGA+ Output Mixer"}, + {"Left MICPGA", "MAL Playback Switch", "Left MICPGA- Output Mixer"}, + {"Right MICPGA", "MAR Playback Switch", "Right MICPGA- Output Mixer"}, + + /* ADC Input */ + {"Left ADC", NULL, "Left MICPGA"}, + {"Right ADC", NULL, "Right MICPGA"}, +}; + +static int aic3204_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, aic3204_dapm_widgets, + ARRAY_SIZE(aic3204_dapm_widgets)); + + /* set up audio path interconnects */ + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + return 0; +} + +static int aic3204_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct aic3204_priv *aic3204 = snd_soc_codec_get_drvdata(codec); + int dac_clk = 0, bit_clk = 0; + int codec_clk = 0, bypass_pll = 0, last_clk = 0, last_error = 0; + u8 data = 0, ndac = 0, mdac = 0, bdiv = 1; + u8 pll_p = 1, pll_r = 1, pll_j = 1; + u16 pll_d = 0; + + int this_clk = 0, this_error = 0; + unsigned int this_abs_error; + u8 j, this_ndac; + u16 d; + + /* Determine the DAC clock and bit clock needed */ + dac_clk = aic3204->pdata.osr * params_rate(params); + bit_clk = params_rate(params) * params_channels(params); + + /* + * Select data word length. + * Note that the number of bits per frame used + * to determine BDIV is double the number of bits per sample, as there + * are two samples per frame. + */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + pr_debug("%s: Sample format 16 bits\n", __func__); + bit_clk *= 16; + data = AIC3204_AISR1_WL_16BITS; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + pr_debug("%s: Sample format 20 bits\n", __func__); + bit_clk *= 32; + data = AIC3204_AISR1_WL_20BITS; + break; + case SNDRV_PCM_FORMAT_S24_LE: + pr_debug("%s: Sample format 24 bits\n", __func__); + bit_clk *= 40; + data = AIC3204_AISR1_WL_24BITS; + break; + case SNDRV_PCM_FORMAT_S32_LE: + pr_debug("%s: Sample format 32 bits\n", __func__); + bit_clk *= 48; + data = AIC3204_AISR1_WL_32BITS; + break; + } + snd_soc_update_bits(codec, AIC3204_AISR1, AIC3204_AISR1_WL, data); + + pr_debug("%s: DAC Clock = %d Hz, Bit clock = %d Hz\n", __func__, + dac_clk, bit_clk); + + /* Try to find a value for div which allows us to bypass the PLL and + * generate CODEC_CLK directly. */ + for (this_ndac = 128; this_ndac >= 1; this_ndac--) { + this_clk = aic3204->sysclk / this_ndac; + + if (this_clk == dac_clk) { + pr_debug("%s: Scored exact match. NDAC=%d; " + "DAC_CLK=%d\n", + __func__, this_ndac, this_clk); + bypass_pll = 1; + ndac = this_ndac; + break; + } + } + + if (bypass_pll) { + /* Select MCLK as CODEC_CLKIN */ + aic3204_write(codec, AIC3204_CLK1, AIC3204_CLK1_CODECCLK_MCLK); + codec_clk = aic3204->sysclk; + goto setup_codec; + } + + /* + * Determine PLL Parameters... the input/output frequency ratio + * of the PLL is given in the datasheet: + * + * out R * J * (D/10000) J D + * --- = ----------------- = R * - * ------- + * in P P 10000 + * + * Limitations: + * - R range: 1..4 + * - J range: 4..63 + * - D range: 0..9999 + * - P range: 1..8 + * - If D == 0; + * 512 kHz <= in / P <= 20 MHz + * else + * 10 MHz <= in / P <= 20 MHz + * + * We will try for 8* the target frequency; then use NDAC/NADC to divide + * that down. If we set P = 1, and R = 1; we simplify the solution. + */ + pll_p = 1; + pll_r = 1; + for (this_ndac = 1; this_ndac <= 128; this_ndac++) { + int ratio, init_ratio; + + codec_clk = dac_clk * this_ndac; + + /* Ensure maximum CODEC frequency is not exceeded */ + if (codec_clk > 137000000) + continue; + if ((this_ndac % 2) && (codec_clk > 110000000)) + continue; + + /* Initial Fixed-point ratio ... this will be slightly lower */ + init_ratio = codec_clk / (aic3204->sysclk / 10000); + + pr_debug("%s: NDAC = %d, PLL J.D * 10000 = %d\n", + __func__, this_ndac, init_ratio); + if (init_ratio < 40000) + continue; + if (init_ratio > 639999) + continue; + + for (ratio = init_ratio; (ratio < init_ratio + 10000) + && (ratio < 639999); ratio++) { + j = ratio / 10000; + d = ratio % 10000; + + this_clk = aic3204->sysclk / 10000; + this_clk *= (10000 * j) + d; + this_error = this_clk - codec_clk; + this_abs_error = abs(this_error); + + if (this_abs_error > 1000) + continue; + + pr_debug("%s: Fractional PLL search; " + "P=%d R=%d J=%d D=%04d => " + "(%d * %d) / 10000 => %d " + "(%d error) [NDAC=%d]\n", + __func__, pll_p, pll_r, + j, d, aic3204->sysclk, + ratio, this_clk, this_error, + this_ndac); + if (!last_clk || (this_abs_error < last_error)) { + last_clk = this_clk; + last_error = this_abs_error; + ndac = this_ndac; + pll_j = j; + pll_d = d; + /* Early finish for exact match */ + if (!this_abs_error) + break; + } + } + } + + /* If we still haven't found anything; bail out here! */ + if (!last_clk) + goto fail; + + pr_debug("%s: Best Output: %d (%d Hz Error)\n", + __func__, last_clk, last_error); + pr_debug("%s: setting up PLL: P=%d R=%d J.D=%d.%04d\n", + __func__, pll_p, pll_r, pll_j, pll_d); + + codec_clk = last_clk; + + aic3204_write(codec, AIC3204_CLK4, (pll_d >> AIC3204_CLK4_PLL_D_VSHIFT) + & AIC3204_CLK4_PLL_D); /* PLL D[14:8] */ + aic3204_write(codec, AIC3204_CLK5, pll_d & AIC3204_CLK5_PLL_D); + /* PLL D[7:0] */ + aic3204_write(codec, AIC3204_CLK3, pll_j & AIC3204_CLK3_PLL_J); + /* PLL J */ + aic3204_write(codec, AIC3204_CLK2, + (pll_r & AIC3204_CLK2_PLL_R) /* PLL R */ + | ((pll_p << AIC3204_CLK2_PLL_P_SHIFT) + & AIC3204_CLK2_PLL_P) + /* PLL P */ + | AIC3204_CLK2_PLL_ON); /* PLL on */ + + /* Select PLL as CODEC_CLKIN */ + aic3204_write(codec, AIC3204_CLK1, AIC3204_CLK1_CODECCLK_PLL); + +setup_codec: + pr_debug("%s: CODEC CLK = %d => DAC CLK = %d\n", + __func__, codec_clk, codec_clk / ndac); + /* Calculate BDIV and NDAC */ + mdac = codec_clk / (ndac * dac_clk); + if (!mdac) + mdac = 1; + + bdiv = dac_clk / bit_clk; + if (!bdiv) + bdiv = 1; + + /* Set AOSR and DOSR */ + aic3204_write(codec, AIC3204_DOSR1, + (aic3204->pdata.osr >> AIC3204_DOSR1_MSB_VSHIFT) + & AIC3204_DOSR1_MSB); /* DOSR[9:8] */ + aic3204_write(codec, AIC3204_DOSR2, aic3204->pdata.osr + & AIC3204_DOSR2_LSB); /* DOSR[7:0] */ + aic3204_write(codec, AIC3204_AOSR, aic3204->pdata.osr); /* AOSR */ + + pr_debug("%s: NDAC = %d\n", __func__, ndac); + /* Set NDAC to divider value */ + aic3204_write(codec, AIC3204_CLK6, AIC3204_CLK6_NDAC_STATE_ON | ndac); + /* Set NADC to match NDAC */ + aic3204_write(codec, AIC3204_CLK8, AIC3204_CLK8_NADC_STATE_ON | ndac); + /* Set MDAC and turn on */ + aic3204_write(codec, AIC3204_CLK7, AIC3204_CLK7_MDAC_STATE_ON | mdac); + /* Use MDAC for MADC */ + aic3204_write(codec, AIC3204_CLK9, AIC3204_CLK7_MDAC_STATE_ON | mdac); + + /* Set BCLK and WCLK */ + pr_debug("%s: Bit clock divider = %d\n", __func__, bdiv); + /* Turn on and set BCLK N divider */ + aic3204_write(codec, AIC3204_CLK12, bdiv + | AIC3204_CLK12_BCLK_STATE_ON); + + /* + * Set BCLK and WCLK sources... + * + * Despite DAPM; this is still needed, as DAPM doesn't yet set the + * source at the right time. + * + * TODO: See if we can change the order of initialisation so this + * selection is made after bringing up the ADCs/DACs. Alternative: + * see if we can find out ahead of time which one to use. + */ + snd_soc_update_bits(codec, AIC3204_AISR3, AIC3204_AISR3_BDIV, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ? AIC3204_AISR3_BDIV_DAC + : AIC3204_AISR3_BDIV_ADC); + snd_soc_update_bits(codec, AIC3204_AISR6, AIC3204_AISR6_WCLKOUT, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ? AIC3204_AISR6_WCLKOUT_DAC + : AIC3204_AISR6_WCLKOUT_ADC); + return 0; +fail: + printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); + return -EINVAL; +} + +static int aic3204_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u8 dacs2; + + dacs2 = aic3204_read_reg_cache(codec, AIC3204_DACS2); + + if (mute) { + dacs2 |= (1 << AIC3204_DACS2_LEFT_MUTE_SHIFT) + | (1 << AIC3204_DACS2_RIGHT_MUTE_SHIFT); + } else { + dacs2 &= ~((1 << AIC3204_DACS2_LEFT_MUTE_SHIFT) + | (1 << AIC3204_DACS2_RIGHT_MUTE_SHIFT)); + } + + aic3204_write(codec, AIC3204_DACS2, dacs2); /* Unmute DAC */ + return 0; +} + +static int aic3204_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct aic3204_priv *aic3204 = snd_soc_codec_get_drvdata(codec); + + aic3204->sysclk = freq; + return 0; +} + +static int aic3204_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u8 aisr1 = 0, aisr2 = 0, aisr3 = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + aisr1 |= AIC3204_AISR1_BCLK_OUT + | AIC3204_AISR1_WCLK_OUT; + break; + case SND_SOC_DAIFMT_CBM_CFS: + aisr1 |= AIC3204_AISR1_BCLK_OUT + | AIC3204_AISR1_WCLK_IN; + break; + case SND_SOC_DAIFMT_CBS_CFM: + aisr1 |= AIC3204_AISR1_BCLK_IN + | AIC3204_AISR1_WCLK_OUT; + break; + case SND_SOC_DAIFMT_CBS_CFS: + aisr1 |= AIC3204_AISR1_BCLK_IN + | AIC3204_AISR1_WCLK_IN; + break; + default: + printk(KERN_ERR "%s: Clock mode not supported " + "(fmt=0x%08x)\n", __func__, fmt); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + aisr1 |= AIC3204_AISR1_INT_I2S; + break; + case SND_SOC_DAIFMT_DSP_A: + aisr2 = 1; + case SND_SOC_DAIFMT_DSP_B: + aisr1 |= AIC3204_AISR1_INT_DSP; + break; + case SND_SOC_DAIFMT_RIGHT_J: + aisr1 |= AIC3204_AISR1_INT_RJF; + break; + case SND_SOC_DAIFMT_LEFT_J: + aisr1 |= AIC3204_AISR1_INT_LJF; + break; + default: + printk(KERN_ERR "%s: SSI mode not supported " + "(fmt=0x%08x)\n", __func__, fmt); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + aisr3 |= AIC3204_AISR3_BCLKPOL_NOR; + break; + case SND_SOC_DAIFMT_IB_NF: + aisr3 |= AIC3204_AISR3_BCLKPOL_INV; + break; + default: + printk(KERN_ERR "%s: Clock inversion mode not " + "supported (fmt=0x%08x)\n", __func__, fmt); + return -EINVAL; + } + + /* set iface */ + aic3204_write(codec, AIC3204_AISR1, aisr1); + aic3204_write(codec, AIC3204_AISR2, aisr2); + aic3204_write(codec, AIC3204_AISR3, aisr3); + + return 0; +} + +#define AIC3204_RATES SNDRV_PCM_RATE_8000_96000 +#define AIC3204_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops aic3204_dai_ops = { + .hw_params = aic3204_hw_params, + .digital_mute = aic3204_mute, + .set_sysclk = aic3204_set_dai_sysclk, + .set_fmt = aic3204_set_dai_fmt, +}; + +struct snd_soc_dai aic3204_dai = { + .name = "tlv320aic3204", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = AIC3204_RATES, + .formats = AIC3204_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = AIC3204_RATES, + .formats = AIC3204_FORMATS,}, + .ops = &aic3204_dai_ops, +}; +EXPORT_SYMBOL_GPL(aic3204_dai); + +static int aic3204_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + int i; + u8 data[2]; + u8 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware */ + for (i = 0; i < AIC3204_CACHEREGNUM; i++) { + data[0] = i; + data[1] = cache[i]; + codec->hw_write(codec->control_data, data, 2); + } + + return 0; +} + +/* + * initialise the AIC3204 driver + * register the mixer and dsp interfaces with the kernel + */ +static int aic3204_init(struct snd_soc_codec *codec) +{ + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + codec->name = "tlv320aic3204"; + codec->owner = THIS_MODULE; + codec->read = aic3204_read_reg_cache; + codec->write = aic3204_write; + codec->dai = &aic3204_dai; + codec->num_dai = 1; + codec->reg_cache_size = AIC3204_CACHEREGNUM; + codec->reg_cache = kmemdup(aic3204_default_reg_data, + AIC3204_CACHEREGNUM, GFP_KERNEL); + codec->readable_register = aic3204_reg_is_readable; + codec->display_register = aic3204_show_reg; + if (codec->reg_cache == NULL) + return -ENOMEM; + + /* Reset the CODEC */ + aic3204_write(codec, AIC3204_PAGE_SELECT, 0); + aic3204_write(codec, AIC3204_RESET, AIC3204_RESET_SOFT); + + return 0; +} + +static struct snd_soc_codec *aic3204_codec; + +static int aic3204_register(struct snd_soc_codec *codec) +{ + int ret; + + ret = aic3204_init(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to initialise device\n"); + return ret; + } + + aic3204_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret) { + dev_err(codec->dev, "Failed to register codec\n"); + return ret; + } + + ret = snd_soc_register_dai(&aic3204_dai); + if (ret) { + dev_err(codec->dev, "Failed to register dai\n"); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; +} + +static int aic3204_unregister(struct aic3204_priv *aic3204) +{ + snd_soc_unregister_dai(&aic3204_dai); + snd_soc_unregister_codec(&aic3204->codec); + + if (aic3204->pdata.gpio_reset >= 0) { + gpio_set_value(aic3204->pdata.gpio_reset, 0); + gpio_free(aic3204->pdata.gpio_reset); + } + regulator_bulk_disable(ARRAY_SIZE(aic3204->supplies), + aic3204->supplies); + regulator_bulk_free(ARRAY_SIZE(aic3204->supplies), aic3204->supplies); + + kfree(aic3204); + aic3204_codec = NULL; + + return 0; +} + +static int aic3204_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct snd_soc_codec *codec; + struct aic3204_priv *aic3204; + struct aic3204_pdata *pdata = i2c->dev.platform_data; + int ret, i; + + aic3204 = kzalloc(sizeof(struct aic3204_priv), GFP_KERNEL); + if (aic3204 == NULL) { + dev_err(&i2c->dev, "failed to create private data\n"); + return -ENOMEM; + } + + codec = &aic3204->codec; + codec->dev = &i2c->dev; + snd_soc_codec_set_drvdata(codec, aic3204); + codec->control_data = i2c; + codec->hw_write = (hw_write_t) i2c_master_send; + + i2c_set_clientdata(i2c, aic3204); + + dev_dbg(&i2c->dev, "%s: platform data at %p\n", + __func__, pdata); + if (pdata) + memcpy(&aic3204->pdata, pdata, sizeof(struct aic3204_pdata)); + else + memcpy(&aic3204->pdata, &aic3204_default_pdata, + sizeof(struct aic3204_pdata)); + + if (aic3204->pdata.gpio_reset >= 0) { + ret = gpio_request(aic3204->pdata.gpio_reset, + "tlv320aic3204 reset"); + if (ret != 0) + goto err_gpio; + gpio_direction_output(aic3204->pdata.gpio_reset, 0); + } + + for (i = 0; i < ARRAY_SIZE(aic3204->supplies); i++) + aic3204->supplies[i].supply = aic3204_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3204->supplies), + aic3204->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + goto err_get; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(aic3204->supplies), + aic3204->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_enable; + } + + if (aic3204->pdata.gpio_reset >= 0) { + udelay(1); + gpio_set_value(aic3204->pdata.gpio_reset, 1); + } + + return aic3204_register(codec); + +err_enable: + regulator_bulk_free(ARRAY_SIZE(aic3204->supplies), aic3204->supplies); +err_get: + if (aic3204->pdata.gpio_reset >= 0) + gpio_free(aic3204->pdata.gpio_reset); +err_gpio: + kfree(aic3204); + return ret; +} + +static int aic3204_i2c_remove(struct i2c_client *client) +{ + struct aic3204_priv *aic3204 = i2c_get_clientdata(client); + + return aic3204_unregister(aic3204); +} + +static const struct i2c_device_id aic3204_i2c_id[] = { + { "tlv320aic3204", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aic3204_i2c_id); + +/* machine i2c codec control layer */ +static struct i2c_driver aic3204_i2c_driver = { + .driver = { + .name = "tlv320aic3204-i2c", + .owner = THIS_MODULE, + }, + .probe = aic3204_i2c_probe, + .remove = aic3204_i2c_remove, + .id_table = aic3204_i2c_id, +}; + +static inline void aic3204_i2c_init(void) +{ + int ret; + + ret = i2c_add_driver(&aic3204_i2c_driver); + if (ret) + printk(KERN_ERR "%s: error regsitering i2c driver, %d\n", + __func__, ret); +} + +static inline void aic3204_i2c_exit(void) +{ + i2c_del_driver(&aic3204_i2c_driver); +} + +static int aic3204_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct aic3204_setup_data *setup; + struct snd_soc_codec *codec; + struct aic3204_priv *aic3204; + int ret = 0; + + codec = aic3204_codec; + if (!codec) { + dev_err(&pdev->dev, "Codec not registered\n"); + return -ENODEV; + } + + socdev->card->codec = codec; + setup = socdev->codec_data; + aic3204 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: private data at %p\n", + __func__, aic3204); + /* Initialise the CODEC with the given settings */ + /* Analogue Input Quick-Charge Power-Up delay */ + ret = aic3204_write(codec, AIC3204_AIQC, + aic3204->pdata.ain_pwrup_delay); + if (ret) + return ret; + + /* Analogue Reference Power-Up delay */ + aic3204_write(codec, AIC3204_REFPU, + aic3204->pdata.ref_pwrup_delay); + if (ret) + return ret; + + /* AVDD<->DVDD link */ + snd_soc_update_bits(codec, AIC3204_POWER, + AIC3204_POWER_AVDD_DVDD_UNLINK, + aic3204->pdata.avdd_link_en ? + 0 : AIC3204_POWER_AVDD_DVDD_UNLINK); + + /* LDO enable, analogue blocks enable */ + snd_soc_update_bits(codec, AIC3204_LDO, + AIC3204_LDO_ANALOG | AIC3204_LDO_AVDD_UP, + AIC3204_LDO_ANALOG_ENABLED | + (aic3204->pdata.ldo_en + ? AIC3204_LDO_AVDD_UP : 0)); + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + printk(KERN_ERR "aic3204: failed to create pcms\n"); + goto pcm_err; + } + + snd_soc_add_controls(codec, aic3204_snd_controls, + ARRAY_SIZE(aic3204_snd_controls)); + + aic3204_add_widgets(codec); + + return ret; + +pcm_err: + kfree(codec->reg_cache); + return ret; +} + +static int aic3204_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + kfree(codec->reg_cache); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_aic3204 = { + .probe = aic3204_probe, + .remove = aic3204_remove, + .resume = aic3204_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_aic3204); + +static int __init aic3204_modinit(void) +{ + aic3204_i2c_init(); + + return 0; +} +module_init(aic3204_modinit); + +static void __exit aic3204_exit(void) +{ + aic3204_i2c_exit(); +} +module_exit(aic3204_exit); + +MODULE_DESCRIPTION("ASoC TLV320AIC3204 codec driver"); +MODULE_AUTHOR("Jacques Electronics Pty Ltd"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tlv320aic3204.h b/sound/soc/codecs/tlv320aic3204.h new file mode 100644 index 0000000..8f9ee43 --- /dev/null +++ b/sound/soc/codecs/tlv320aic3204.h @@ -0,0 +1,1350 @@ +/* + * ALSA SoC TLV320AIC3204 codec driver + * + * Author: Stuart Longland, redhatter@gentoo.org + * Copyright: (C) 2010 Jacques Electronics, Pty, Ltd. + * + * Author: Vladimir Barinov, vbarinov@embeddedalley.com + * Copyright: (C) 2007 MontaVista Software, Inc., source@mvista.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _AIC3204_H +#define _AIC3204_H + +/* + * The AIC3204's registers are divided into separate pages, the first page of + * every register is a "page select", which sets the current page being + * accessed. For the purposes of simplicity; we shall consider all registers + * as being addressed by a 16-bit value, consisting of the page number as + * most-significant 9 bits, followed by the register number as given in the + * datasheet. + * + * The register access functions will look after page flipping from here. + */ + +/* + * AIC3204 register space; 128 registers each page, we pages 0..127. It's not + * clear from the datasheet exactly how many pages are in use... and it's a + * sparse register map! Ideally, I'd like to just cache the pages that are + * needed, but the ALSA framework doesn't allow this easily. + * + * It does look as if up to and including page 70 is needed. For now, we will + * cache up to page 128 however; as this ensures we get *everything*. + */ +#define AIC3204_CACHEREGNUM (128*128) + +/* Page select register */ +#define AIC3204_PAGE_SELECT 0 + +/* Register Page/Number => Address Mapping Macro */ +#define AIC3204_PGREG(page, reg) (((page) << 7) | ((reg) & 0x7f)) + +/* Software reset register */ +#define AIC3204_RESET AIC3204_PGREG(0, 1) +/* Perform software reset */ +#define AIC3204_RESET_SOFT 1 + +/* Clock Setting Register 1, Multiplexers */ +#define AIC3204_CLK1 AIC3204_PGREG(0, 4) +/* PLL Range Select: Low Range */ +#define AIC3204_CLK1_PLLRANGE_LOW (0 << 6) +/* PLL Range Select: High Range */ +#define AIC3204_CLK1_PLLRANGE_HIGH (1 << 6) +/* PLL Range Select Mask */ +#define AIC3204_CLK1_PLLRANGE (1 << 6) +/* PLL Input Clock Select: MCLK */ +#define AIC3204_CLK1_PLLSRC_MCLK (0 << 2) +/* PLL Input Clock Select: BCLK */ +#define AIC3204_CLK1_PLLSRC_BCLK (1 << 2) +/* PLL Input Clock Select: GPIO */ +#define AIC3204_CLK1_PLLSRC_GPIO (2 << 2) +/* PLL Input Clock Select: Data In */ +#define AIC3204_CLK1_PLLSRC_DIN (3 << 2) +/* PLL Input Clock Select Mask */ +#define AIC3204_CLK1_PLLSRC (3 << 2) +/* CODEC Clock Source Select: MCLK */ +#define AIC3204_CLK1_CODECCLK_MCLK (0) +/* CODEC Clock Source Select: BCLK */ +#define AIC3204_CLK1_CODECCLK_BCLK (1) +/* CODEC Clock Source Select: GPIO */ +#define AIC3204_CLK1_CODECCLK_GPIO (2) +/* CODEC Clock Source Select: PLL */ +#define AIC3204_CLK1_CODECCLK_PLL (3) +/* CODEC Clock Source Select Mask */ +#define AIC3204_CLK1_CODECCLK (3) + +/* Clock Setting Register 2, PLL P & R Values */ +#define AIC3204_CLK2 AIC3204_PGREG(0, 5) +/* PLL State: Powered Down */ +#define AIC3204_CLK2_PLL_OFF (0 << 7) +/* PLL State: Powered Up */ +#define AIC3204_CLK2_PLL_ON (1 << 7) +/* PLL State Mask */ +#define AIC3204_CLK2_PLL (1 << 7) +/* PLL State bitfield location */ +#define AIC3204_CLK2_PLL_SHIFT (7) +/* PLL P Divider value bitfield location */ +#define AIC3204_CLK2_PLL_P_SHIFT (4) +/* PLL P Divider value bitfield mask */ +#define AIC3204_CLK2_PLL_P (7 << 4) +/* PLL R Divider value bitfield location */ +#define AIC3204_CLK2_PLL_R_SHIFT (0) +/* PLL R Divider value bitfield mask */ +#define AIC3204_CLK2_PLL_R (0xf) + +/* Clock Setting Register 3, PLL J Values */ +#define AIC3204_CLK3 AIC3204_PGREG(0, 6) +/* PLL J Divider value bitfield location */ +#define AIC3204_CLK3_PLL_J_SHIFT (0) +/* PLL J Divider value bitfield mask */ +#define AIC3204_CLK3_PLL_J (0x3f) + +/* Clock Setting Register 4, PLL D MSB */ +#define AIC3204_CLK4 AIC3204_PGREG(0, 7) +/* PLL D most significant portion bitfield location */ +#define AIC3204_CLK4_PLL_D_SHIFT (0) +/* PLL D most significant portion bitfield mask */ +#define AIC3204_CLK4_PLL_D (0x3f) +/* PLL D most significant portion value shift */ +#define AIC3204_CLK4_PLL_D_VSHIFT (8) + +/* Clock Setting Register 5, PLL D LSB */ +#define AIC3204_CLK5 AIC3204_PGREG(0, 8) +/* PLL D least significant portion bitfield location */ +#define AIC3204_CLK5_PLL_D_SHIFT (0) +/* PLL D least significant portion bitfield mask */ +#define AIC3204_CLK5_PLL_D (0xff) +/* PLL D least significant portion value shift */ +#define AIC3204_CLK5_PLL_D_VSHIFT (0) + +/* Clock Setting Register 6, NDAC Values */ +#define AIC3204_CLK6 AIC3204_PGREG(0, 11) +/* NDAC State: Powered Down */ +#define AIC3204_CLK6_NDAC_STATE_OFF (0 << 7) +/* NDAC State: Powered Up */ +#define AIC3204_CLK6_NDAC_STATE_ON (1 << 7) +/* NDAC State Mask */ +#define AIC3204_CLK6_NDAC_STATE (1 << 7) +/* NDAC State bitfield location */ +#define AIC3204_CLK6_NDAC_STATE_SHIFT (7) +/* NDAC value bitfield location */ +#define AIC3204_CLK6_NDAC_SHIFT (0) +/* NDAC value bitfield mask */ +#define AIC3204_CLK6_NDAC (0x7f) + +/* Clock Setting Register 7, MDAC Values */ +#define AIC3204_CLK7 AIC3204_PGREG(0, 12) +/* MDAC State: Powered Down */ +#define AIC3204_CLK7_MDAC_STATE_OFF (0 << 7) +/* MDAC State: Powered Up */ +#define AIC3204_CLK7_MDAC_STATE_ON (1 << 7) +/* MDAC State Mask */ +#define AIC3204_CLK7_MDAC_STATE (1 << 7) +/* MDAC State bitfield location */ +#define AIC3204_CLK7_MDAC_STATE_SHIFT (7) +/* MDAC value bitfield location */ +#define AIC3204_CLK7_MDAC_SHIFT (0) +/* MDAC value bitfield mask */ +#define AIC3204_CLK7_MDAC (0x7f) + +/* DAC OSR Setting Register 1, MSB */ +#define AIC3204_DOSR1 AIC3204_PGREG(0, 13) +/* DOSR most significant portion bitfield location */ +#define AIC3204_DOSR1_MSB_SHIFT (0) +/* DOSR most significant portion bitfield mask */ +#define AIC3204_DOSR1_MSB (3) +/* DOSR most significant portion value shift */ +#define AIC3204_DOSR1_MSB_VSHIFT (8) + +/* DAC OSR Setting Register 2, LSB */ +#define AIC3204_DOSR2 AIC3204_PGREG(0, 14) +/* DOSR least significant portion bitfield location */ +#define AIC3204_DOSR2_LSB_SHIFT (0) +/* DOSR least significant portion bitfield mask */ +#define AIC3204_DOSR2_LSB (0xff) +/* DOSR least significant portion value shift */ +#define AIC3204_DOSR2_LSB_VSHIFT (0) + +/* Clock Setting Register 8, NADC Values */ +#define AIC3204_CLK8 AIC3204_PGREG(0, 18) +/* NADC State: Powered Down */ +#define AIC3204_CLK8_NADC_STATE_OFF (0 << 7) +/* NADC State: Powered Up */ +#define AIC3204_CLK8_NADC_STATE_ON (1 << 7) +/* NADC State Mask */ +#define AIC3204_CLK8_NADC_STATE (1 << 7) +/* NADC State bitfield location */ +#define AIC3204_CLK8_NADC_STATE_SHIFT (7) +/* NADC value bitfield location */ +#define AIC3204_CLK8_NADC_SHIFT (0) +/* NADC value bitfield mask */ +#define AIC3204_CLK8_NADC (0x7f) + +/* Clock Setting Register 9, MADC Values */ +#define AIC3204_CLK9 AIC3204_PGREG(0, 19) +/* MADC State: Powered Down */ +#define AIC3204_CLK9_MADC_STATE_OFF (0 << 7) +/* MADC State: Powered Up */ +#define AIC3204_CLK9_MADC_STATE_ON (1 << 7) +/* MADC State Mask */ +#define AIC3204_CLK9_MADC_STATE (1 << 7) +/* MADC State bitfield location */ +#define AIC3204_CLK9_MADC_STATE_SHIFT (7) +/* MADC value bitfield location */ +#define AIC3204_CLK9_MADC_SHIFT (0) +/* MADC value bitfield mask */ +#define AIC3204_CLK9_MADC (0x7f) + +/* ADC OSR Setting Register */ +#define AIC3204_AOSR AIC3204_PGREG(0, 20) + +/* + * Clock Register setting 10, Multiplexers + * + * XXX: Note that the datasheet goofs up here, calling this register 9, but we + * already had a register 9 just before AOSR. Therefore, we will call this + * register 10, and will increment all following by one to correct TI's + * mistake. + */ +#define AIC3204_CLK10 AIC3204_PGREG(0, 25) +/* CDIV Clock Source: MCLK */ +#define AIC3204_CLK10_CDIV_MCLK (0) +/* CDIV Clock Source: BCLK */ +#define AIC3204_CLK10_CDIV_BCLK (1) +/* CDIV Clock Source: Data IN */ +#define AIC3204_CLK10_CDIV_DIN (2) +/* CDIV Clock Source: PLL */ +#define AIC3204_CLK10_CDIV_PLL (3) +/* CDIV Clock Source: DAC */ +#define AIC3204_CLK10_CDIV_DAC (4) +/* CDIV Clock Source: DAC Modulation */ +#define AIC3204_CLK10_CDIV_DAC_MOD (5) +/* CDIV Clock Source: ADC */ +#define AIC3204_CLK10_CDIV_ADC (6) +/* CDIV Clock Source: ADC Modulation */ +#define AIC3204_CLK10_CDIV_ADC_MOD (7) +/* CDIV Clock Source Mask */ +#define AIC3204_CLK10_CDIV (7) + +/* Clock Register setting 11, CLKOUT M divider value */ +#define AIC3204_CLK11 AIC3204_PGREG(0, 26) +/* CLKOUT Divider State: Off */ +#define AIC3204_CLK11_CLKOUT_OFF (0 << 7) +/* CLKOUT Divider State: On */ +#define AIC3204_CLK11_CLKOUT_ON (1 << 7) +/* CLKOUT Divider State Mask */ +#define AIC3204_CLK11_CLKOUT (1 << 7) +/* CLKOUT Divider M value bitfield location */ +#define AIC3204_CLK11_CLKOUTM_SHIFT (0) +/* CLKOUT Divider M value bitfield mask */ +#define AIC3204_CLK11_CLKOUTM (0x7f) + +/* Audio Interface Setting Register 1 */ +#define AIC3204_AISR1 AIC3204_PGREG(0, 27) +/* Audio Interface Select: I2S */ +#define AIC3204_AISR1_INT_I2S (0 << 6) +/* Audio Interface Select: DSP */ +#define AIC3204_AISR1_INT_DSP (1 << 6) +/* Audio Interface Select: Right-Justified Format */ +#define AIC3204_AISR1_INT_RJF (2 << 6) +/* Audio Interface Select: Left-Justified Format */ +#define AIC3204_AISR1_INT_LJF (3 << 6) +/* Audio Interface Select Mask */ +#define AIC3204_AISR1_INT (3 << 6) +/* Audio Data Word Length: 16 bits */ +#define AIC3204_AISR1_WL_16BITS (0 << 4) +/* Audio Data Word Length: 20 bits */ +#define AIC3204_AISR1_WL_20BITS (1 << 4) +/* Audio Data Word Length: 24 bits */ +#define AIC3204_AISR1_WL_24BITS (2 << 4) +/* Audio Data Word Length: 32 bits */ +#define AIC3204_AISR1_WL_32BITS (3 << 4) +/* Audio Data Word Length Mask */ +#define AIC3204_AISR1_WL (3 << 4) +/* BCLK Direction Control: Input */ +#define AIC3204_AISR1_BCLK_IN (0 << 3) +/* BCLK Direction Control: Output */ +#define AIC3204_AISR1_BCLK_OUT (1 << 3) +/* BCLK Direction Control: Mask */ +#define AIC3204_AISR1_BCLK (1 << 3) +/* WCLK Direction Control: Input */ +#define AIC3204_AISR1_WCLK_IN (0 << 2) +/* WCLK Direction Control: Output */ +#define AIC3204_AISR1_WCLK_OUT (1 << 2) +/* WCLK Direction Control: Mask */ +#define AIC3204_AISR1_WCLK (1 << 2) +/* DOUT High Impedance Output Control: Never high impedance */ +#define AIC3204_AISR1_HIZ_NEVER (0 << 0) +/* DOUT High Impedance Output Control: High impedance when idle */ +#define AIC3204_AISR1_HIZ_IDLE (1 << 0) +/* DOUT High Impedance Output Control Mask */ +#define AIC3204_AISR1_HIZ (1 << 0) + +/* Audio Interface Register 2, Data offset setting */ +#define AIC3204_AISR2 AIC3204_PGREG(0, 28) + +/* Audio Interface Register 3 */ +#define AIC3204_AISR3 AIC3204_PGREG(0, 29) +/* Audio Data Loopback Control: Disabled */ +#define AIC3204_AISR3_ADLO_OFF (0 << 5) +/* Audio Data Loopback Control: Enabled */ +#define AIC3204_AISR3_ADLO_ON (1 << 5) +/* Audio Data Loopback Control Mask */ +#define AIC3204_AISR3_ADLO (1 << 5) +/* ADC->DAC Loopback Control: Disabled */ +#define AIC3204_AISR3_ADDALO_OFF (0 << 4) +/* ADC->DAC Loopback Control: Enabled */ +#define AIC3204_AISR3_ADDALO_ON (1 << 4) +/* ADC->DAC Loopback Control Mask */ +#define AIC3204_AISR3_ADDALO (1 << 4) +/* Audio Bit Clock Polarity: Normal */ +#define AIC3204_AISR3_BCLKPOL_NOR (0 << 3) +/* Audio Bit Clock Polarity: Inverted */ +#define AIC3204_AISR3_BCLKPOL_INV (1 << 3) +/* Audio Bit Clock Polarity Mask */ +#define AIC3204_AISR3_BCLKPOL (1 << 3) +/* Audio Data Interface Clock Buffers: Always powered */ +#define AIC3204_AISR3_ADICLK_ALWAYS (0 << 2) +/* Audio Data Interface Clock Buffers: Powered with CODEC only */ +#define AIC3204_AISR3_ADICLK_CODEC (1 << 2) +/* Audio Data Interface Clock Buffers' State */ +#define AIC3204_AISR3_ADICLK (1 << 2) +/* Audio Bit Clock Divider Source: DAC */ +#define AIC3204_AISR3_BDIV_DAC (0 << 0) +/* Audio Bit Clock Divider Source: DAC Modulation */ +#define AIC3204_AISR3_BDIV_DAC_MOD (1 << 0) +/* Audio Bit Clock Divider Source: ADC */ +#define AIC3204_AISR3_BDIV_ADC (2 << 0) +/* Audio Bit Clock Divider Source: ADC Modulation */ +#define AIC3204_AISR3_BDIV_ADC_MOD (3 << 0) +/* Audio Bit Clock Divider Source Mask */ +#define AIC3204_AISR3_BDIV (3 << 0) + +/* Clock Setting Register 12, BCLK N Divider */ +#define AIC3204_CLK12 AIC3204_PGREG(0, 30) +/* BCLK N State: Powered Down */ +#define AIC3204_PG0_CLK12_BCLK_STATE_OFF (0 << 7) +/* BCLK N State: Powered Up */ +#define AIC3204_CLK12_BCLK_STATE_ON (1 << 7) +/* BCLK N State Mask */ +#define AIC3204_CLK12_BCLK_STATE (1 << 7) +/* BCLK N State bitfield location */ +#define AIC3204_CLK12_BCLK_STATE_SHIFT (7) +/* BCLK N value bitfield location */ +#define AIC3204_CLK12_BCLK_SHIFT (0) +/* BCLK N value bitfield mask */ +#define AIC3204_CLK12_BCLK (0x7f) + +/* Audio Interface Setting Register 4, Secondary Audio Interface */ +#define AIC3204_AISR4 AIC3204_PGREG(0, 31) +/* Secondary Bit Clock: GPIO */ +#define AIC3204_AISR4_SECBCLK_GPIO (0 << 5) +/* Secondary Bit Clock: SCLK */ +#define AIC3204_AISR4_SECBCLK_SCLK (1 << 5) +/* Secondary Bit Clock: MISO */ +#define AIC3204_AISR4_SECBCLK_MISO (2 << 5) +/* Secondary Bit Clock: DOUT */ +#define AIC3204_AISR4_SECBCLK_DOUT (3 << 5) +/* Secondary Bit Clock Mask */ +#define AIC3204_AISR4_SECBCLK (3 << 5) +/* Secondary Word Clock: GPIO */ +#define AIC3204_AISR4_SECWCLK_GPIO (0 << 3) +/* Secondary Word Clock: SCLK */ +#define AIC3204_AISR4_SECWCLK_SCLK (1 << 3) +/* Secondary Word Clock: MISO */ +#define AIC3204_AISR4_SECWCLK_MISO (2 << 3) +/* Secondary Word Clock: DOUT */ +#define AIC3204_AISR4_SECWCLK_DOUT (3 << 3) +/* Secondary Word Clock Mask */ +#define AIC3204_AISR4_SECWCLK (3 << 3) +/* ADC Word Clock: GPIO */ +#define AIC3204_AISR4_ADCWCLK_GPIO (0 << 3) +/* ADC Word Clock: SCLK */ +#define AIC3204_AISR4_ADCWCLK_SCLK (1 << 3) +/* ADC Word Clock: MISO */ +#define AIC3204_AISR4_ADCWCLK_MISO (2 << 3) +/* ADC Word Clock Mask */ +#define AIC3204_AISR4_ADCWCLK (3 << 3) +/* Secondary Data Input: GPIO */ +#define AIC3204_AISR4_SECDIN_GPIO (0 << 0) +/* Secondary Data Input: SCLK */ +#define AIC3204_AISR4_SECDIN_SCLK (1 << 0) +/* Secondary Data Input Mask */ +#define AIC3204_AISR4_SECDIN (1 << 0) + +/* Audio Interface Setting Register 5 */ +#define AIC3204_AISR5 AIC3204_PGREG(0, 32) +/* Audio Interface Bit Clock: Primary (BCLK) */ +#define AIC3204_AISR5_BCLKIN_PRI (0 << 3) +/* Audio Interface Bit Clock: Secondary */ +#define AIC3204_AISR5_BCLKIN_SEC (1 << 3) +/* Audio Interface Bit Clock Mask */ +#define AIC3204_AISR5_WCLKIN (1 << 2) +/* Audio Interface Word Clock: Primary (BCLK) */ +#define AIC3204_AISR5_WCLKIN_PRI (0 << 2) +/* Audio Interface Word Clock: Secondary */ +#define AIC3204_AISR5_WCLKIN_SEC (1 << 2) +/* Audio Interface Word Clock Mask */ +#define AIC3204_AISR5_WCLKIN (1 << 2) +/* ADC Word Clock Control: ADC WCLK = DAC WCLK */ +#define ADC3204_PG0_AISR5_ADCWCLK_DAC (0 << 1) +/* ADC Word Clock Control: ADC WCLK = Secondary ADC WCLK */ +#define ADC3204_PG0_AISR5_ADCWCLK_SEC (1 << 1) +/* ADC Word Clock Control Mask */ +#define ADC3204_PG0_AISR5_ADCWCLK (1 << 1) +/* Audio Data In: Primary Data In */ +#define ADC3204_PG0_AISR5_DIN_PRI (0 << 0) +/* Audio Data In: Secondary Data In */ +#define ADC3204_PG0_AISR5_DIN_SEC (1 << 0) +/* Audio Data In Mask */ +#define ADC3204_PG0_AISR5_DIN (1 << 0) + +/* Audio Interface Setting Register 6 */ +#define AIC3204_AISR6 AIC3204_PGREG(0, 33) +/* BCLK Output Control: Generated Primary Bit Clock */ +#define AIC3204_AISR6_BCLKOUT_GEN (0 << 7) +/* BCLK Output Control: Secondary Bit Clock */ +#define AIC3204_AISR6_BCLKOUT_SEC (1 << 7) +/* BCLK Output Control Mask */ +#define AIC3204_AISR6_BCLKOUT (1 << 7) +/* Secondary BCLK Output Control: Primary Bit Clock Input */ +#define AIC3204_AISR6_SBCLKOUT_BCLK (0 << 6) +/* Secondary BCLK Output Control: Generated Primary Bit Clock */ +#define AIC3204_AISR6_SBCLKOUT_GEN (1 << 6) +/* Secondary BCLK Output Control Mask */ +#define AIC3204_AISR6_SBCLKOUT (1 << 6) +/* WCLK Output Control: Generated DAC_FS */ +#define AIC3204_AISR6_WCLKOUT_DAC (0 << 4) +/* WCLK Output Control: Generated ADC_FS */ +#define AIC3204_AISR6_WCLKOUT_ADC (1 << 4) +/* WCLK Output Control: Secondary WCLK Input */ +#define AIC3204_AISR6_WCLKOUT_SWCLK (2 << 4) +/* WCLK Output Control Mask */ +#define AIC3204_AISR6_WCLKOUT (3 << 4) +/* Secondary WCLK Output Control: WCLK Input */ +#define AIC3204_AISR6_SWCLKOUT_WCLK (0 << 2) +/* Secondary WCLK Output Control: Generated DAC_FS */ +#define AIC3204_AISR6_SWCLKOUT_DAC (1 << 2) +/* Secondary WCLK Output Control: Generated ADC_FS */ +#define AIC3204_AISR6_SWCLKOUT_ADC (2 << 2) +/* Secondary WCLK Output Control Mask */ +#define AIC3204_AISR6_SWCLKOUT (3 << 2) +/* Primary Data Output Control: Serial Interface */ +#define AIC3204_AISR6_DOUT_INT (0 << 1) +/* Primary Data Output Control: Secondary Data Input */ +#define AIC3204_AISR6_DOUT_SDIN (1 << 1) +/* Primary Data Output Control Mask */ +#define AIC3204_AISR6_DOUT (1 << 1) +/* Secondary Data Output Control: Primary Data In */ +#define AIC3204_AISR6_SDOUT_DIN (0 << 0) +/* Secondary Data Output Control: Serial Interface */ +#define AIC3204_AISR6_SDOUT_INT (1 << 0) +/* Secondary Data Output Control Mask */ +#define AIC3204_AISR6_SDOUT (1 << 0) + +/* Digital Interface Misc. Setting Register */ +#define AIC3204_DIMISC AIC3204_PGREG(0, 34) +/* I2C General Call Address Configuration: Ignore */ +#define AIC3204_DIMISC_I2CGC_IGNORE (0 << 5) +/* I2C General Call Address Configuration: Accept */ +#define AIC3204_DIMISC_I2CGC_ACCEPT (1 << 5) + +/* ADC Flag Register */ +#define AIC3204_ADCF AIC3204_PGREG(0, 36) +/* Left ADC PGA Status: Gain is set */ +#define AIC3204_ADCF_LEFT_PGASET (1 << 7) +/* Left ADC Power Status: Powered Up */ +#define AIC3204_ADCF_LEFT_UP (1 << 6) +/* Left ADC AGC Status: Gain is saturated */ +#define AIC3204_ADCF_LEFT_AGCSAT (1 << 5) +/* Right ADC PGA Status: Gain is set */ +#define AIC3204_ADCF_RIGHT_PGASET (1 << 3) +/* Right ADC Power Status: Powered Up */ +#define AIC3204_ADCF_RIGHT_UP (1 << 2) +/* Right ADC AGC Status: Gain is saturated */ +#define AIC3204_ADCF_RIGHT_AGCSAT (1 << 1) + +/* DAC Flag Register 1 */ +#define AIC3204_DACF1 AIC3204_PGREG(0, 37) +/* Left DAC powered up */ +#define AIC3204_DACF1_LEFT_UP (1 << 7) +/* Left Line Output Driver powered up */ +#define AIC3204_DACF1_LOL_UP (1 << 6) +/* Left Headphone Output Driver powered up */ +#define AIC3204_DACF1_HPL_UP (1 << 5) +/* Right DAC powered up */ +#define AIC3204_DACF1_RIGHT_UP (1 << 7) +/* Right Line Output Driver powered up */ +#define AIC3204_DACF1_LOR_UP (1 << 6) +/* Right Headphone Output Driver powered up */ +#define AIC3204_DACF1_HPR_UP (1 << 5) + +/* DAC Flag Register 2 */ +#define AIC3204_DACF2 AIC3204_PGREG(0, 38) +/* Left DAC PGA Status: Gain is set */ +#define AIC3204_DACF2_LEFT_PGASET (1 << 4) +/* Right DAC PGA Status: Gain is set */ +#define AIC3204_DACF2_RIGHT_PGASET (1 << 0) + +/* Sticky Flag Register 1 */ +#define AIC3204_STICK1 AIC3204_PGREG(0, 42) +/* Left DAC Overflow */ +#define AIC3204_STICK1_LDAC_OVER (1 << 7) +/* Right DAC Overflow */ +#define AIC3204_STICK1_RDAC_OVER (1 << 6) +/* Left ADC Overflow */ +#define AIC3204_STICK1_LADC_OVER (1 << 3) +/* Right ADC Overflow */ +#define AIC3204_STICK1_RADC_OVER (1 << 2) + +/* Interrupt Flag Register 1 */ +#define AIC3204_INTF1 AIC3204_PGREG(0, 43) +/* Left DAC Overflow */ +#define AIC3204_INTF1_LDAC_OVER (1 << 7) +/* Right DAC Overflow */ +#define AIC3204_INTF1_RDAC_OVER (1 << 6) +/* Left ADC Overflow */ +#define AIC3204_INTF1_LADC_OVER (1 << 3) +/* Right ADC Overflow */ +#define AIC3204_INTF1_RADC_OVER (1 << 2) + +/* Sticky Flag Register 2 */ +#define AIC3204_STICK2 AIC3204_PGREG(0, 44) +/* Left Headphone Driver Over Current */ +#define AIC3204_STICK2_HPL_OVER (1 << 7) +/* Right Headphone Driver Over Current */ +#define AIC3204_STICK2_HPR_OVER (1 << 6) +/* Headset button pressed */ +#define AIC3204_STICK2_HS_BUTTON (1 << 5) +/* Headset plug inserted/removed */ +#define AIC3204_STICK2_HS_PLUGGED (1 << 4) +/* Left Channel DRC: Over threshold */ +#define AIC3204_STICK2_LDRC_OVER (1 << 3) +/* Right Channel DRC: Over threshold */ +#define AIC3204_STICK2_RDRC_OVER (1 << 2) + +/* Sticky Flag Register 3 */ +#define AIC3204_STICK3 AIC3204_PGREG(0, 45) +/* Left AGC Noise Threshold Flag: Over threshold */ +#define AIC3204_STICK3_LAGC_OVER (1 << 6) +/* Right AGC Noise Threshold Flag: Over threshold */ +#define AIC3204_STICK3_RAGC_OVER (1 << 5) +/* Left ADC DC Measurement Available */ +#define AIC3204_STICK3_LADC_DC (1 << 2) +/* Right ADC DC Measurement Available */ +#define AIC3204_STICK3_RADC_DC (1 << 1) + +/* Interrupt Flag Register 2 */ +#define AIC3204_INTF2 AIC3204_PGREG(0, 46) +/* Left Headphone Driver Over Current */ +#define AIC3204_INTF2_HPL_OVER (1 << 7) +/* Right Headphone Driver Over Current */ +#define AIC3204_INTF2_HPR_OVER (1 << 6) +/* Headset button pressed */ +#define AIC3204_INTF2_HS_BUTTON (1 << 5) +/* Headset plug inserted/removed */ +#define AIC3204_INTF2_HS_PLUGGED (1 << 4) +/* Left Channel DRC: Over threshold */ +#define AIC3204_INTF2_LDRC_OVER (1 << 3) +/* Right Channel DRC: Over threshold */ +#define AIC3204_INTF2_RDRC_OVER (1 << 2) + +/* Interrupt Flag Register 3 */ +#define AIC3204_INTF3 AIC3204_PGREG(0, 47) +/* Left AGC Noise Threshold Flag: Over threshold */ +#define AIC3204_INTF3_LAGC_OVER (1 << 6) +/* Right AGC Noise Threshold Flag: Over threshold */ +#define AIC3204_INTF3_RAGC_OVER (1 << 5) +/* Left ADC DC Measurement Available */ +#define AIC3204_INTF3_LADC_DC (1 << 2) +/* Right ADC DC Measurement Available */ +#define AIC3204_INTF3_RADC_DC (1 << 1) + +/* INT1 Interrupt Control Register */ +#define AIC3204_INT1 AIC3204_PGREG(0, 48) +/* INT1 Generated on Headset insertion */ +#define AIC3204_INT1_HS_PLUG (1 << 7) +/* INT1 Generated on Headset Button press */ +#define AIC3204_INT1_HS_BUTTON (1 << 6) +/* INT1 Generated on DAC DRC Signal Threshold */ +#define AIC3204_INT1_DAC_DRC (1 << 5) +/* INT1 Generated on AGC Noise Interrupt */ +#define AIC3204_INT1_ADC_NOISE (1 << 4) +/* INT1 Generated on Over Current */ +#define AIC3204_INT1_HP_OVERCURRENT (1 << 3) +/* INT1 Generated on overflow event */ +#define AIC3204_INT1_OVERFLOW (1 << 2) +/* INT1 Generated on DC measurement */ +#define AIC3204_INT1_DC (1 << 1) +/* INT1 pulse control: Continuous pulse train */ +#define AIC3204_INT1_CONT_PULSE (1 << 0) + +/* INT2 Interrupt Control Register */ +#define AIC3204_INT2 AIC3204_PGREG(0, 49) +/* INT2 Generated on Headset insertion */ +#define AIC3204_INT2_HS_PLUG (1 << 7) +/* INT2 Generated on Headset Button press */ +#define AIC3204_INT2_HS_BUTTON (1 << 6) +/* INT2 Generated on DAC DRC Signal Threshold */ +#define AIC3204_INT2_DAC_DRC (1 << 5) +/* INT2 Generated on AGC Noise Interrupt */ +#define AIC3204_INT2_ADC_NOISE (1 << 4) +/* INT2 Generated on Over Current */ +#define AIC3204_INT2_HP_OVERCURRENT (1 << 3) +/* INT2 Generated on overflow event */ +#define AIC3204_INT2_OVERFLOW (1 << 2) +/* INT2 Generated on DC measurement */ +#define AIC3204_INT2_DC (1 << 1) +/* INT2 pulse control: Continuous pulse train */ +#define AIC3204_INT2_CONT_PULSE (1 << 0) + +/* GPIO/MFP5 Control Register */ +#define AIC3204_MFP5 AIC3204_PGREG(0, 52) +/* GPIO Control: Disabled */ +#define AIC3204_MFP5_FUNC_DISABLED (0 << 2) +/* GPIO Control: Secondary audio interface/digital microphone/clock input */ +#define AIC3204_MFP5_FUNC_SAI_DM_CI (1 << 2) +/* GPIO Control: General Purpose Input */ +#define AIC3204_MFP5_FUNC_INPUT (2 << 2) +/* GPIO Control: General Purpose Output */ +#define AIC3204_MFP5_FUNC_OUTPUT (3 << 2) +/* GPIO Control: CLKOUT Output */ +#define AIC3204_MFP5_FUNC_CLKOUT (4 << 2) +/* GPIO Control: INT1 Output */ +#define AIC3204_MFP5_FUNC_INT1 (4 << 2) +/* GPIO Control: INT2 Output */ +#define AIC3204_MFP5_FUNC_INT2 (4 << 2) +/* GPIO Control: ADC_WCLK */ +#define AIC3204_MFP5_FUNC_ADC_WCLK (4 << 2) +/* GPIO Control: Secondary Bit Clock */ +#define AIC3204_MFP5_FUNC_SEC_BCLK (4 << 2) +/* GPIO Control: Secondary Word Clock */ +#define AIC3204_MFP5_FUNC_SEC_WCLK (4 << 2) +/* GPIO Control: Digital Microphone Clock */ +#define AIC3204_MFP5_FUNC_DMIC_CLK (4 << 2) +/* GPIO Control Mask */ +#define AIC3204_MFP5_FUNC (15 << 2) +/* GPIO Input State */ +#define AIC3204_MFP5_IN (1 << 1) +/* GPIO Output State */ +#define AIC3204_MFP5_OUT (1 << 0) + +/* DOUT/MFP2 Function Control Register */ +#define AIC3204_MFP2 AIC3204_PGREG(0, 53) +/* DOUT Bus Keeper Enabled */ +#define AIC3204_MFP2_BK (1 << 4) +/* DOUT MUX Control: Disabled */ +#define AIC3204_MFP2_FUNC_DISABLED (0 << 1) +/* DOUT MUX Control: Primary DOUT */ +#define AIC3204_MFP2_FUNC_PRI_DOUT (1 << 1) +/* DOUT MUX Control: General Purpose Output */ +#define AIC3204_MFP2_FUNC_OUTPUT (2 << 1) +/* DOUT MUX Control: CLKOUT Clock Output */ +#define AIC3204_MFP2_FUNC_CLKOUT (3 << 1) +/* DOUT MUX Control: INT1 Output */ +#define AIC3204_MFP2_FUNC_INT1 (4 << 1) +/* DOUT MUX Control: INT2 Output */ +#define AIC3204_MFP2_FUNC_INT2 (5 << 1) +/* DOUT MUX Control: Secondary Bit Clock */ +#define AIC3204_MFP2_FUNC_SEC_BCLK (6 << 1) +/* DOUT MUX Control: Secondary Word Clock */ +#define AIC3204_MFP2_FUNC_SEC_WCLK (7 << 1) +/* DOUT MUX Control Mask */ +#define AIC3204_MFP2_FUNC (7 << 1) +/* DOUT General Purpose Output State */ +#define AIC3204_MFP2_OUT (1 << 0) + +/* DIN/MFP1 Function Control Register */ +#define AIC3204_MFP1 AIC3204_PGREG(0, 54) +/* DIN Function Control: Disabled */ +#define AIC3204_MFP1_FUNC_DISABLED (0 << 1) +/* DIN Function Control: Primary Data Input/Digital Microphone/Clock Input */ +#define AIC3204_MFP1_FUNC_DIN_DM_CI (1 << 1) +/* DIN Function Control: General Purpose Input */ +#define AIC3204_MFP1_FUNC_INPUT (2 << 1) +/* DIN Function Control Mask */ +#define AIC3204_MFP1_FUNC (3 << 1) +/* DIN Input State */ +#define AIC3204_MFP1_IN (1 << 0) + +/* MISO/MFP4 Function Control Register */ +#define AIC3204_MFP4 AIC3204_PGREG(0, 55) +/* MISO Function Control: Disabled */ +#define AIC3204_MFP4_FUNC_DISABLED (0 << 1) +/* MISO Function Control: SPI Data Output (disabled in I2C mode) */ +#define AIC3204_MFP4_FUNC_SPI_OUT (1 << 1) +/* MISO Function Control: General Purpose Output */ +#define AIC3204_MFP4_FUNC_OUTPUT (2 << 1) +/* MISO Function Control: CLKOUT Clock Output */ +#define AIC3204_MFP4_FUNC_CLKOUT (3 << 1) +/* MISO Function Control: INT1 Output */ +#define AIC3204_MFP4_FUNC_INT1 (4 << 1) +/* MISO Function Control: INT2 Output */ +#define AIC3204_MFP4_FUNC_INT2 (5 << 1) +/* MISO Function Control: ADC Word Clock Output */ +#define AIC3204_MFP4_FUNC_ADC_WCLK (6 << 1) +/* MISO Function Control: Digital Microphone Clock Output */ +#define AIC3204_MFP4_FUNC_DMIC_CLK (7 << 1) +/* MISO Function Control: Secondary Data Output */ +#define AIC3204_MFP4_FUNC_SEC_DOUT (8 << 1) +/* MISO Function Control: Secondary Bit Clock */ +#define AIC3204_MFP4_FUNC_SEC_BCLK (9 << 1) +/* MISO Function Control: Secondary Word Clock */ +#define AIC3204_MFP4_FUNC_SEC_WCLK (10 << 1) +/* MISO Function Control Mask */ +#define AIC3204_MFP4_FUNC (15 << 1) +/* MISO Output State */ +#define AIC3204_MFP4_OUT (1 << 0) + +/* SCLK/MFP3 Function Control Register */ +#define AIC3204_MFP3 AIC3204_PGREG(0, 56) +/* SCLK Function Control: Disabled */ +#define AIC3204_MFP3_FUNC_DISABLED (0 << 1) +/* SCLK Function Control: SPI Clock / Secondary Interface / Digital Mic Input */ +#define AIC3204_MFP3_FUNC_SPI_SI_DM (1 << 1) +/* SCLK Function Control: General Purpose Input */ +#define AIC3204_MFP3_FUNC_INPUT (2 << 1) +/* SCLK Function Control Mask */ +#define AIC3204_MFP3_FUNC (3 << 1) +/* SCLK Input State */ +#define AIC3204_MFP3_IN (1 << 0) + +/* DAC Signal Processing Block Control Register */ +#define AIC3204_DACSPB AIC3204_PGREG(0, 60) +/* DAC Signal Processing Block Mask */ +#define AIC3204_DACSPB_MASK 0x1f + +/* ADC Signal Processing Block Control Register */ +#define AIC3204_ADCSPB AIC3204_PGREG(0, 61) +/* ADC Signal Processing Block Mask */ +#define AIC3204_ADCSPB_MASK 0x1f + +/* DAC Channel Setup Register 1 */ +#define AIC3204_DACS1 AIC3204_PGREG(0, 63) +/* Left DAC Powered Up */ +#define AIC3204_DACS1_LDAC_UP_SHIFT (7) +/* Right DAC Powered Up */ +#define AIC3204_DACS1_RDAC_UP_SHIFT (6) +/* Left DAC Data Path Control: Disabled */ +#define AIC3204_DACS1_LDACD_DIS (0 << 4) +/* Left DAC Data Path Control: Left Data */ +#define AIC3204_DACS1_LDACD_LEFT (1 << 4) +/* Left DAC Data Path Control: Right Data */ +#define AIC3204_DACS1_LDACD_RIGHT (2 << 4) +/* Left DAC Data Path Control: Left + Right */ +#define AIC3204_DACS1_LDACD_MIX (3 << 4) +/* Left DAC Data Path Control Mask */ +#define AIC3204_DACS1_LDACD (3 << 4) +/* Right DAC Data Path Control: Disabled */ +#define AIC3204_DACS1_RDACD_DIS (0 << 2) +/* Right DAC Data Path Control: Right Data */ +#define AIC3204_DACS1_RDACD_RIGHT (1 << 2) +/* Right DAC Data Path Control: Left Data */ +#define AIC3204_DACS1_RDACD_LEFT (2 << 2) +/* Right DAC Data Path Control: Left + Right */ +#define AIC3204_DACS1_RDACD_MIX (3 << 2) +/* Right DAC Data Path Control Mask */ +#define AIC3204_DACS1_RDACD (3 << 2) +/* DAC Soft-Step: Disabled */ +#define AIC3204_DACS1_SOFT_DIS (0 << 0) +/* DAC Soft-Step: 1 step every clock */ +#define AIC3204_DACS1_SOFT_1SEC (1 << 0) +/* DAC Soft-Step: 1 step every 2 clocks */ +#define AIC3204_DACS1_SOFT_1SE2C (2 << 0) +/* DAC Soft-Step Mask */ +#define AIC3204_DACS1_SOFT (3 << 0) + +/* DAC Channel Setup Register 2 */ +#define AIC3204_DACS2 AIC3204_PGREG(0, 64) +/* Right Modulator Output Control: Output is inverted left output */ +#define AIC3204_DACS2_RMOD_INV_SHIFT (7) +/* DAC Auto Mute: Disabled */ +#define AIC3204_DACS2_AMUTE_DIS (0 << 4) +/* DAC Auto Mute: After 100 samples of DC */ +#define AIC3204_DACS2_AMUTE_100 (1 << 4) +/* DAC Auto Mute: After 200 samples of DC */ +#define AIC3204_DACS2_AMUTE_200 (2 << 4) +/* DAC Auto Mute: After 400 samples of DC */ +#define AIC3204_DACS2_AMUTE_400 (3 << 4) +/* DAC Auto Mute: After 800 samples of DC */ +#define AIC3204_DACS2_AMUTE_800 (4 << 4) +/* DAC Auto Mute: After 1600 samples of DC */ +#define AIC3204_DACS2_AMUTE_1600 (5 << 4) +/* DAC Auto Mute: After 3200 samples of DC */ +#define AIC3204_DACS2_AMUTE_3200 (6 << 4) +/* DAC Auto Mute: After 6400 samples of DC */ +#define AIC3204_DACS2_AMUTE_6400 (7 << 4) +/* DAC Auto Mute Mask */ +#define AIC3204_DACS2_AMUTE (7 << 4) +/* Left DAC Muted */ +#define AIC3204_DACS2_LEFT_MUTE_SHIFT (3) +/* Right DAC Muted */ +#define AIC3204_DACS2_RIGHT_MUTE_SHIFT (2) +/* DAC Master Volume Control: Independant */ +#define AIC3204_DACS2_VOL_IND (0 << 0) +/* DAC Master Volume Control: Left controls right */ +#define AIC3204_DACS2_VOL_LEFT (1 << 0) +/* DAC Master Volume Control: Right controls left */ +#define AIC3204_DACS2_VOL_RIGHT (2 << 0) +/* DAC Master Volume Control Mask */ +#define AIC3204_DACS2_VOL (3 << 0) + +/* Left DAC Digital Volume Control */ +#define AIC3204_LDACVOL AIC3204_PGREG(0, 65) + +/* Right DAC Digital Volume Control */ +#define AIC3204_RDACVOL AIC3204_PGREG(0, 66) + +/* Headset Detection Configuration Register */ +#define AIC3204_HSDET AIC3204_PGREG(0, 67) +/* Enable Headset Detection */ +#define AIC3204_HSDET_ENABLE (1 << 7) +/* Headset Type: No Headset */ +#define AIC3204_HSDET_NONE (0 << 5) +/* Headset Type: Stereo Headset */ +#define AIC3204_HSDET_STEREO (1 << 5) +/* Headset Type: Cellular Stereo Headset */ +#define AIC3204_HSDET_CELLSTEREO (3 << 5) +/* Headset Detection Debounce Time: 16ms */ +#define AIC3204_HSDET_PLUGDT_16 (0 << 2) +/* Headset Detection Debounce Time: 32ms */ +#define AIC3204_HSDET_PLUGDT_32 (1 << 2) +/* Headset Detection Debounce Time: 64ms */ +#define AIC3204_HSDET_PLUGDT_64 (2 << 2) +/* Headset Detection Debounce Time: 128ms */ +#define AIC3204_HSDET_PLUGDT_128 (3 << 2) +/* Headset Detection Debounce Time: 256ms */ +#define AIC3204_HSDET_PLUGDT_256 (4 << 2) +/* Headset Detection Debounce Time: 512ms */ +#define AIC3204_HSDET_PLUGDT_512 (5 << 2) +/* Headset Detection Debounce Time Mask */ +#define AIC3204_HSDET_PLUGDT (7 << 2) +/* Headset Button Debounce Time: 8ms */ +#define AIC3204_HSDET_BTNDT_8 (0 << 0) +/* Headset Button Debounce Time: 16ms */ +#define AIC3204_HSDET_BTNDT_16 (1 << 0) +/* Headset Button Debounce Time: 32ms */ +#define AIC3204_HSDET_BTNDT_32 (2 << 0) +/* Headset Button Debounce Time Mask */ +#define AIC3204_HSDET_BTNDT (3 << 0) + +/* DRC Control Register 1 */ +#define AIC3204_DRC1 AIC3204_PGREG(0, 68) +/* Left Channel DRC Enable */ +#define AIC3204_DRC1_LEFT_EN (1 << 6) +/* Right Channel DRC Enable */ +#define AIC3204_DRC1_RIGHT_EN (1 << 5) +/* DRC Threshold: -3dBFS */ +#define AIC3204_DRC1_THOLD_3DBFS (0 << 2) +/* DRC Threshold: -6dBFS */ +#define AIC3204_DRC1_THOLD_6DBFS (1 << 2) +/* DRC Threshold: -9dBFS */ +#define AIC3204_DRC1_THOLD_9DBFS (2 << 2) +/* DRC Threshold: -12dBFS */ +#define AIC3204_DRC1_THOLD_12DBFS (3 << 2) +/* DRC Threshold: -15dBFS */ +#define AIC3204_DRC1_THOLD_15DBFS (4 << 2) +/* DRC Threshold: -18dBFS */ +#define AIC3204_DRC1_THOLD_18DBFS (5 << 2) +/* DRC Threshold: -21dBFS */ +#define AIC3204_DRC1_THOLD_21DBFS (6 << 2) +/* DRC Threshold: -24dBFS */ +#define AIC3204_DRC1_THOLD_24DBFS (7 << 2) +/* DRC Threshold Mask */ +#define AIC3204_DRC1_THOLD (7 << 2) +/* DRC Hysteresis: 0dB */ +#define AIC3204_DRC1_HYST_0DB (0 << 0) +/* DRC Hysteresis: 1dB */ +#define AIC3204_DRC1_HYST_1DB (1 << 0) +/* DRC Hysteresis: 2dB */ +#define AIC3204_DRC1_HYST_2DB (2 << 0) +/* DRC Hysteresis: 3dB */ +#define AIC3204_DRC1_HYST_3DB (3 << 0) +/* DRC Hysteresis Mask */ +#define AIC3204_DRC1_HYST (3 << 0) + +/* DRC Control Register 2 */ +#define AIC3204_DRC2 AIC3204_PGREG(0, 69) +/* DRC Hold: Disabled */ +#define AIC3204_DRC2_HOLD_DISABLED (0 << 3) +/* DRC Hold: 32 Word Clocks */ +#define AIC3204_DRC2_HOLD_32WC (1 << 3) +/* DRC Hold: 64 Word Clocks */ +#define AIC3204_DRC2_HOLD_64WC (2 << 3) +/* DRC Hold: 128 Word Clocks */ +#define AIC3204_DRC2_HOLD_128WC (3 << 3) +/* DRC Hold: 256 Word Clocks */ +#define AIC3204_DRC2_HOLD_256WC (4 << 3) +/* DRC Hold: 512 Word Clocks */ +#define AIC3204_DRC2_HOLD_512WC (5 << 3) +/* DRC Hold: 1024 Word Clocks */ +#define AIC3204_DRC2_HOLD_1024WC (6 << 3) +/* DRC Hold: 2048 Word Clocks */ +#define AIC3204_DRC2_HOLD_2048WC (7 << 3) +/* DRC Hold: 4096 Word Clocks */ +#define AIC3204_DRC2_HOLD_4096WC (8 << 3) +/* DRC Hold: 8192 Word Clocks */ +#define AIC3204_DRC2_HOLD_8192WC (9 << 3) +/* DRC Hold: 16384 Word Clocks */ +#define AIC3204_DRC2_HOLD_16384WC (10 << 3) +/* DRC Hold: 32768 Word Clocks */ +#define AIC3204_DRC2_HOLD_32768WC (11 << 3) +/* DRC Hold: 65536 Word Clocks */ +#define AIC3204_DRC2_HOLD_65536WC (12 << 3) +/* DRC Hold: 98304 Word Clocks */ +#define AIC3204_DRC2_HOLD_98304WC (13 << 3) +/* DRC Hold: 131072 Word Clocks */ +#define AIC3204_DRC2_HOLD_131072WC (14 << 3) +/* DRC Hold: 163840 Word Clocks */ +#define AIC3204_DRC2_HOLD_163840WC (15 << 3) +/* DRC Hold Mask */ +#define AIC3204_DRC2_HOLD (15 << 3) + +/* DRC Control Register 3 */ +#define AIC3204_DRC3 AIC3204_PGREG(0, 70) +/* DRC Attack Rate Shift */ +#define AIC3204_DRC3_ATTACK_SHIFT 4 +/* DRC Attack Rate Mask */ +#define AIC3204_DRC3_ATTACK (15 << AIC3204_DRC3_ATTACK_SHIFT) +/* DRC Decay Rate Shift */ +#define AIC3204_DRC3_DECAY_SHIFT 0 +/* DRC Decay Rate Mask */ +#define AIC3204_DRC3_DECAY (15 << AIC3204_DRC3_DECAY_SHIFT) + +/* Beep Generator Register 1 */ +#define AIC3204_BEEP1 AIC3204_PGREG(0, 71) +/* Enable Beep Generator */ +#define AIC3204_BEEP1_EN (1 << 7) +/* Left Channel Beep Volume Shift */ +#define AIC3204_BEEP1_VOL_SHIFT 0 +/* Left Channel Beep Volume Mask */ +#define AIC3204_BEEP1_VOL (0x3f) + +/* Beep Generator Register 2 */ +#define AIC3204_BEEP2 AIC3204_PGREG(0, 72) +/* Beep Generator Master Volume: Independant Left/Right Channels */ +#define AIC3204_BEEP2_MVOL_IND (0 << 6) +/* Beep Generator Master Volume: Left Channel controls Right */ +#define AIC3204_BEEP2_MVOL_LEFT (1 << 6) +/* Beep Generator Master Volume: Right Channel controls Left */ +#define AIC3204_BEEP2_MVOL_RIGHT (2 << 6) +/* Beep Generator Master Volume Mask */ +#define AIC3204_BEEP2_MVOL (3 << 6) + +/* Beep Generator Register 3 */ +#define AIC3204_BEEP3 AIC3204_PGREG(0, 73) +/* Sample Length Value Shift */ +#define AIC3204_BEEP3_LENGTH_VSHIFT 16 +/* Sample Length Shift */ +#define AIC3204_BEEP3_LENGTH_SHIFT 0 +/* Sample Length Mask */ +#define AIC3204_BEEP3_LENGTH (0xff) + +/* Beep Generator Register 4 */ +#define AIC3204_BEEP4 AIC3204_PGREG(0, 74) +/* Sample Length Value Shift */ +#define AIC3204_BEEP4_LENGTH_VSHIFT 8 +/* Sample Length Shift */ +#define AIC3204_BEEP4_LENGTH_SHIFT 0 +/* Sample Length Mask */ +#define AIC3204_BEEP4_LENGTH (0xff) + +/* Beep Generator Register 5 */ +#define AIC3204_BEEP5 AIC3204_PGREG(0, 75) +/* Sample Length Value Shift */ +#define AIC3204_BEEP5_LENGTH_VSHIFT 0 +/* Sample Length Shift */ +#define AIC3204_BEEP5_LENGTH_SHIFT 0 +/* Sample Length Mask */ +#define AIC3204_BEEP5_LENGTH (0xff) + +/* Beep Generator Register 6 */ +#define AIC3204_BEEP6 AIC3204_PGREG(0, 76) +/* Relative Sine Frequency Value Shift */ +#define AIC3204_BEEP6_SINFREQ_VSHIFT 8 +/* Relative Sine Frequency Shift */ +#define AIC3204_BEEP6_SINFREQ_SHIFT 0 +/* Relative Sine Frequency Mask */ +#define AIC3204_BEEP6_SINFREQ (0xff) + +/* Beep Generator Register 7 */ +#define AIC3204_BEEP7 AIC3204_PGREG(0, 77) +/* Relative Sine Frequency Value Shift */ +#define AIC3204_BEEP7_SINFREQ_VSHIFT 0 +/* Relative Sine Frequency Shift */ +#define AIC3204_BEEP7_SINFREQ_SHIFT 0 +/* Relative Sine Frequency Mask */ +#define AIC3204_BEEP7_SINFREQ (0xff) + +/* Beep Generator Register 8 */ +#define AIC3204_BEEP8 AIC3204_PGREG(0, 78) +/* Relative Cosine Frequency Value Shift */ +#define AIC3204_BEEP8_COSFREQ_VSHIFT 8 +/* Relative Cosine Frequency Shift */ +#define AIC3204_BEEP8_COSFREQ_SHIFT 0 +/* Relative Cosine Frequency Mask */ +#define AIC3204_BEEP8_COSFREQ (0xff) + +/* Beep Generator Register 9 */ +#define AIC3204_BEEP9 AIC3204_PGREG(0, 79) +/* Relative Cosine Frequency Value Shift */ +#define AIC3204_BEEP9_COSFREQ_VSHIFT 0 +/* Relative Cosine Frequency Shift */ +#define AIC3204_BEEP9_COSFREQ_SHIFT 0 +/* Relative Cosine Frequency Mask */ +#define AIC3204_BEEP9_COSFREQ (0xff) + +/* ADC Channel Setup Register */ +#define AIC3204_ADCS AIC3204_PGREG(0, 81) +/* Left Channel ADC Powered Up */ +#define AIC3204_ADCS_LADC_UP_SHIFT (7) +/* Right Channel ADC Powered Up */ +#define AIC3204_ADCS_RADC_UP_SHIFT (6) +/* Digital Microphone Input: GPIO */ +#define AIC3204_ADC5_DMICIN_GPIO (0 << 4) +/* Digital Microphone Input: SCLK */ +#define AIC3204_ADC5_DMICIN_SCLK (1 << 4) +/* Digital Microphone Input: DIN */ +#define AIC3204_ADC5_DMICIN_DIN (2 << 4) +/* Digital Microphone Input Mask */ +#define AIC3204_ADC5_DMICIN (3 << 4) +/* Left ADC Source: Digital Microphone */ +#define AIC3204_ADC5_LADC_DMIC (1 << 3) +/* Right ADC Source: Digital Microphone */ +#define AIC3204_ADC5_RADC_DMIC (1 << 2) +/* ADC Volume Soft Step: 1 step / word clock */ +#define AIC3204_ADC5_VOLSS_1SPWC (0 << 0) +/* ADC Volume Soft Step: 1 step / 2 word clocks */ +#define AIC3204_ADC5_VOLSS_1SP2WC (1 << 0) +/* ADC Volume Soft Step: Disabled */ +#define AIC3204_ADC5_VOLSS_DISABLED (2 << 0) +/* ADC Volume Soft Step Mask */ +#define AIC3204_ADC5_VOLSS (3 << 0) + +/* ADC Fine Gain Adjust Register */ +#define AIC3204_ADCFINE AIC3204_PGREG(0, 82) +/* Left ADC Mute */ +#define AIC3204_ADCFINE_LEFT_MUTE (1 << 7) +/* Left ADC Gain: 0dB */ +#define AIC3204_ADCFINE_LEFT_0DB (0 << 4) +/* Left ADC Gain: -0.1dB */ +#define AIC3204_ADCFINE_LEFT_0DB1 (1 << 4) +/* Left ADC Gain: -0.2dB */ +#define AIC3204_ADCFINE_LEFT_0DB2 (2 << 4) +/* Left ADC Gain: -0.3dB */ +#define AIC3204_ADCFINE_LEFT_0DB3 (2 << 4) +/* Left ADC Gain: -0.4dB */ +#define AIC3204_ADCFINE_LEFT_0DB4 (3 << 4) +/* Left ADC Gain Mask */ +#define AIC3204_ADCFINE_LEFT (7 << 4) +/* Right ADC Mute */ +#define AIC3204_ADCFINE_RIGHT_MUTE (1 << 3) +/* Right ADC Gain: 0dB */ +#define AIC3204_ADCFINE_RIGHT_0DB (0 << 0) +/* Right ADC Gain: -0.1dB */ +#define AIC3204_ADCFINE_RIGHT_0DB1 (1 << 0) +/* Right ADC Gain: -0.2dB */ +#define AIC3204_ADCFINE_RIGHT_0DB2 (2 << 0) +/* Right ADC Gain: -0.3dB */ +#define AIC3204_ADCFINE_RIGHT_0DB3 (2 << 0) +/* Right ADC Gain: -0.4dB */ +#define AIC3204_ADCFINE_RIGHT_0DB4 (3 << 0) +/* Right ADC Gain Mask */ +#define AIC3204_ADCFINE_RIGHT (7 << 0) + +/* Left ADC Channel Volume Register */ +#define AIC3204_LADCVOL AIC3204_PGREG(0, 83) +/* Left ADC Channel Volume Mask */ +#define AIC3204_LADCVOL_MASK 0x7f + +/* Right ADC Channel Volume Register */ +#define AIC3204_RADCVOL AIC3204_PGREG(0, 84) +/* Right ADC Channel Volume Mask */ +#define AIC3204_RADCVOL_MASK 0x7f + +/* ADC Phase Adjust Register */ +#define AIC3204_ADCPHASE AIC3204_PGREG(0, 85) + +/* Left Channel AGC Control Register 1 */ +#define AIC3204_LAGC1 AIC3204_PGREG(0, 86) +/* Left Channel AGC Enabled */ +#define AIC3204_LAGC1_ENABLE (1 << 7) +/* Left Channel Target Level: -5.5dBFS */ +#define AIC3204_LAGC1_LEVEL_5DBFS5 (0 << 4) +/* Left Channel Target Level: -8.0dBFS */ +#define AIC3204_LAGC1_LEVEL_8DBFS (1 << 4) +/* Left Channel Target Level: -10dBFS */ +#define AIC3204_LAGC1_LEVEL_10DBFS (2 << 4) +/* Left Channel Target Level: -12dBFS */ +#define AIC3204_LAGC1_LEVEL_12DBFS (3 << 4) +/* Left Channel Target Level: -14dBFS */ +#define AIC3204_LAGC1_LEVEL_14DBFS (4 << 4) +/* Left Channel Target Level: -17dBFS */ +#define AIC3204_LAGC1_LEVEL_17DBFS (5 << 4) +/* Left Channel Target Level: -20dBFS */ +#define AIC3204_LAGC1_LEVEL_20DBFS (6 << 4) +/* Left Channel Target Level: -24dBFS */ +#define AIC3204_LAGC1_LEVEL_24DBFS (7 << 4) +/* Left Channel Target Level Mask */ +#define AIC3204_LAGC1_LEVEL (7 << 4) +/* Left Channel Gain Hysteresis: Disabled */ +#define AIC3204_LAGC1_GAINHYST_DISABLED (0 << 0) +/* Left Channel Gain Hysteresis: 0.5dB */ +#define AIC3204_LAGC1_GAINHYST_0DB5 (1 << 0) +/* Left Channel Gain Hysteresis: 1dB */ +#define AIC3204_LAGC1_GAINHYST_1DB (2 << 0) +/* Left Channel Gain Hysteresis: 1.5dB */ +#define AIC3204_LAGC1_GAINHYST_1DB5 (3 << 0) +/* Left Channel Gain Hysteresis Mask */ +#define AIC3204_LAGC1_GAINHYST (3 << 0) + +/* Left Channel AGC Control Register 2 */ +#define AIC3204_LAGC2 AIC3204_PGREG(0, 87) +/* Left Channel AGC Hysteresis: 1dB */ +#define AIC3204_LAGC2_HYST_1DB (0 << 6) +/* Left Channel AGC Hysteresis: 2dB */ +#define AIC3204_LAGC2_HYST_2DB (1 << 6) +/* Left Channel AGC Hysteresis: 4dB */ +#define AIC3204_LAGC2_HYST_4DB (2 << 6) +/* Left Channel AGC Hysteresis: Disabled */ +#define AIC3204_LAGC2_HYST_DISABLED (3 << 6) +/* Left Channel AGC Hysteresis Mask */ +#define AIC3204_LAGC2_HYST (3 << 6) +/* Left Channel AGC Noise Gate Threshold Mask */ +#define AIC3204_LAGC2_NGATE (0x1f) +/* Left Channel AGC Noise Gate Threshold Shift */ +#define AIC3204_LAGC2_NGATE_SHIFT 1 + +/* TODO: Remaining AGC registers, DC measurement registers */ + +/* Power Configuration Register */ +#define AIC3204_POWER AIC3204_PGREG(1, 1) +/* Disable AVDD -> DVDD Link */ +#define AIC3204_POWER_AVDD_DVDD_UNLINK (1 << 3) + +/* LDO Control Register */ +#define AIC3204_LDO AIC3204_PGREG(1, 2) +/* DVDD LDO: 1.72V */ +#define AIC3204_LDO_DVDD_1V72 (0 << 6) +/* DVDD LDO: 1.67V */ +#define AIC3204_LDO_DVDD_1V67 (1 << 6) +/* DVDD LDO: 1.77V */ +#define AIC3204_LDO_DVDD_1V77 (2 << 6) +/* DVDD LDO Mask */ +#define AIC3204_LDO_DVDD (3 << 6) +/* AVDD LDO: 1.72V */ +#define AIC3204_LDO_AVDD_1V72 (0 << 4) +/* AVDD LDO: 1.67V */ +#define AIC3204_LDO_AVDD_1V67 (1 << 4) +/* AVDD LDO: 1.77V */ +#define AIC3204_LDO_AVDD_1V77 (2 << 4) +/* AVDD LDO Mask */ +#define AIC3204_LDO_AVDD (3 << 4) +/* Analog Blocks Enabled */ +#define AIC3204_LDO_ANALOG_ENABLED (0 << 3) +/* Analog Blocks Disabled */ +#define AIC3204_LDO_ANALOG_DISABLED (1 << 3) +/* Analog Block Status */ +#define AIC3204_LDO_ANALOG (1 << 3) +/* DVDD Over Current Detect */ +#define AIC3204_LDO_DVDD_OVERCURRENT (1 << 2) +/* AVDD Over Current Detect */ +#define AIC3204_LDO_AVDD_OVERCURRENT (1 << 1) +/* AVDD Powered Up */ +#define AIC3204_LDO_AVDD_UP (1 << 0) + +/* TODO: Playback Configuration Registers */ + +/* Output Driver Power Control Register */ +#define AIC3204_OUTDRV AIC3204_PGREG(1, 9) +/* Left Headphone Driver Up */ +#define AIC3204_OUTDRV_HPL_UP_SHIFT (5) +/* Right Headphone Driver Up */ +#define AIC3204_OUTDRV_HPR_UP_SHIFT (4) +/* Left Line Output Driver Up */ +#define AIC3204_OUTDRV_LOL_UP_SHIFT (3) +/* Right Line Output Driver Up */ +#define AIC3204_OUTDRV_LOR_UP_SHIFT (2) +/* Left Mixer Amplifier Up */ +#define AIC3204_OUTDRV_MAL_UP_SHIFT (1) +/* Right Mixer Amplifier Up */ +#define AIC3204_OUTDRV_MAR_UP_SHIFT (0) + +/* Common Mode Control Register */ +#define AIC3204_CMCTL AIC3204_PGREG(1, 10) +/* Full Chip Common Mode = 0.9V */ +#define AIC3204_CMCTL_FCCM_0V9 (0 << 6) +/* Full Chip Common Mode = 0.75V */ +#define AIC3204_CMCTL_FCCM_0V75 (1 << 6) +/* Full Chip Common Mode Mask */ +#define AIC3204_CMCTL_FCCM (1 << 6) +/* Headphone Output Common Mode = Full Chip Common Mode */ +#define AIC3204_CMCTL_HPCM_FCCM (0 << 4) +/* Headphone Output Common Mode = 1.25V */ +#define AIC3204_CMCTL_HPCM_1V25 (1 << 4) +/* Headphone Output Common Mode = 1.5V */ +#define AIC3204_CMCTL_HPCM_1V5 (2 << 4) +/* Headphone Output Common Mode = 1.65V */ +#define AIC3204_CMCTL_HPCM_1V65 (3 << 4) +/* Headphone Output Common Mode Mask */ +#define AIC3204_CMCTL_HPCM (3 << 4) +/* Line Output Common Mode = Full Chip Common Mode */ +#define AIC3204_CMCTL_LOCM_FCCM (0 << 3) +/* Line Output Common Mode = 1.65V from LDOin */ +#define AIC3204_CMCTL_LOCM_1V65LDOIN (1 << 3) +/* Line Output Common Mode Mask */ +#define AIC3204_CMCTL_LOCM (1 << 3) +/* Headphone Output Common Mode Source = AVDD */ +#define AIC3204_CMCTL_HPCMSRC_AVDD (0 << 1) +/* Headphone Output Common Mode Source = LDOin */ +#define AIC3204_CMCTL_HPCMSRC_LDOIN (1 << 1) +/* Headphone Output Common Mode Source Mask */ +#define AIC3204_CMCTL_HPCMSRC (1 << 1) +/* LDO Input Range = 1.5~1.95V */ +#define AIC3204_CMCTL_LDORANGE_1V5_1V95 (0 << 0) +/* LDO Input Range = 1.8~3.6V */ +#define AIC3204_CMCTL_LDORANGE_1V8_3V6 (1 << 0) +/* LDO Input Range Mask (effective when HPCMSRC = LDOIN) */ +#define AIC3204_CMCTL_LDORANGE (1 << 0) + +/* Over Current Protection Configuration Register TODO */ +#define AIC3204_OCP AIC3204_PGREG(1, 11) + +/* Left Headphone Driver Routing Register */ +#define AIC3204_HPLROUTE AIC3204_PGREG(1, 12) +/* Left Headphone Driver connects to LDAC+ */ +#define AIC3204_HPLROUTE_LDACP_SHIFT (3) +/* Left Headphone Driver connects to IN1L */ +#define AIC3204_HPLROUTE_IN1L_SHIFT (2) +/* Left Headphone Driver connects to MAL */ +#define AIC3204_HPLROUTE_MAL_SHIFT (1) +/* Left Headphone Driver connects to MAR */ +#define AIC3204_HPLROUTE_MAR_SHIFT (0) + +/* Right Headphone Driver Routing Register */ +#define AIC3204_HPRROUTE AIC3204_PGREG(1, 13) +/* Right Headphone Driver connects to LDAC- */ +#define AIC3204_HPRROUTE_LDACN_SHIFT (4) +/* Right Headphone Driver connects to RDAC+ */ +#define AIC3204_HPRROUTE_RDACP_SHIFT (3) +/* Right Headphone Driver connects to IN1L */ +#define AIC3204_HPRROUTE_IN1R_SHIFT (2) +/* Right Headphone Driver connects to MAL */ +#define AIC3204_HPRROUTE_MAR_SHIFT (1) +/* Right Headphone Driver connects to HPL */ +#define AIC3204_HPRROUTE_HPL_SHIFT (0) + +/* Left Line Output Routing Register */ +#define AIC3204_LOLROUTE AIC3204_PGREG(1, 14) +/* Left Line Output Driver connects to RDAC- */ +#define AIC3204_LOLROUTE_RDACN_SHIFT (4) +/* Left Line Output Driver connects to LDAC+ */ +#define AIC3204_LOLROUTE_LDACP_SHIFT (3) +/* Left Line Output Driver connects to MAL */ +#define AIC3204_LOLROUTE_MAL_SHIFT (1) +/* Left Line Output Driver connects to LOR */ +#define AIC3204_LOLROUTE_LOR_SHIFT (0) + +/* Right Line Output Routing Register */ +#define AIC3204_LORROUTE AIC3204_PGREG(1, 15) +/* Right Line Output Driver connects to RDAC+ */ +#define AIC3204_LORROUTE_RDACP_SHIFT (3) +/* Right Line Output Driver connects to MAR */ +#define AIC3204_LORROUTE_MAR_SHIFT (1) + +/* Left Headphone Gain Setting Register */ +#define AIC3204_HPLGAIN AIC3204_PGREG(1, 16) +/* Left Headphone Mute */ +#define AIC3204_HPLGAIN_MUTE_SHIFT (6) +/* Left Headphone Gain Mask */ +#define AIC3204_HPLGAIN_MASK (0x3f) + +/* Right Headphone Gain Setting Register */ +#define AIC3204_HPRGAIN AIC3204_PGREG(1, 17) +/* Right Headphone Mute */ +#define AIC3204_HPRGAIN_MUTE_SHIFT (6) +/* Right Headphone Gain Mask */ +#define AIC3204_HPRGAIN_MASK (0x3f) + +/* Left Line Output Gain Setting Register */ +#define AIC3204_LOLGAIN AIC3204_PGREG(1, 18) +/* Left Line Output Mute */ +#define AIC3204_LOLGAIN_MUTE_SHIFT (6) +/* Left Line Output Gain Mask */ +#define AIC3204_LOLGAIN_MASK (0x3f) + +/* Right Line Output Gain Setting Register */ +#define AIC3204_LORGAIN AIC3204_PGREG(1, 19) +/* Right Line Output Mute */ +#define AIC3204_LORGAIN_MUTE_SHIFT (6) +/* Right Line Output Gain Mask */ +#define AIC3204_LORGAIN_MASK (0x3f) + +/* Left Mixer Amplifier Gain Setting Register */ +#define AIC3204_MALGAIN AIC3204_PGREG(1, 24) +/* Left Mixer Amplifier Gain Mask */ +#define AIC3204_MALGAIN_MASK (0x3f) + +/* Right Mixer Amplifier Gain Setting Register */ +#define AIC3204_MARGAIN AIC3204_PGREG(1, 25) +/* Right Mixer Amplifier Gain Mask */ +#define AIC3204_MARGAIN_MASK (0x3f) + +#define AIC3204_MICBIAS AIC3204_PGREG(1, 51) + +#define AIC3204_LMICPGAPROUTE AIC3204_PGREG(1, 52) +#define AIC3204_LMICPGANROUTE AIC3204_PGREG(1, 54) + +#define AIC3204_RMICPGAPROUTE AIC3204_PGREG(1, 55) +#define AIC3204_RMICPGANROUTE AIC3204_PGREG(1, 57) + +#define AIC3204_LMICPGAVOL AIC3204_PGREG(1, 59) +#define AIC3204_RMICPGAVOL AIC3204_PGREG(1, 60) + +/* ADC Power Tune Mode Register */ +#define AIC3204_ADCPTM AIC3204_PGREG(1, 61) +/* ADC Power Tune Mode: PTM_R4 */ +#define AIC3204_ADCPTM_R4 (0x00) +/* ADC Power Tune Mode: PTM_R3 */ +#define AIC3204_ADCPTM_R3 (0x64) +/* ADC Power Tune Mode: PTM_R2 */ +#define AIC3204_ADCPTM_R2 (0xb6) +/* ADC Power Tune Mode: PTM_R1 */ +#define AIC3204_ADCPTM_R1 (0xff) + +/* Analogue Input Quick Charging Configuration Register */ +#define AIC3204_AIQC AIC3204_PGREG(1, 71) +/* Power up time: Default Value (whatever that is) */ +#define AIC3204_AIQC_PWRUP_DEFAULT (0x00) +/* Power up time: 3.1ms */ +#define AIC3204_AIQC_PWRUP_3M1S (0x31) +/* Power up time: 6.4ms */ +#define AIC3204_AIQC_PWRUP_6M4S (0x32) +/* Power up time: 1.6ms */ +#define AIC3204_AIQC_PWRUP_1M6S (0x33) +/* Power up time mask */ +#define AIC3204_AIQC_PWRUP (0x3f) + +/* Reference Power-Up Configuration Register */ +#define AIC3204_REFPU AIC3204_PGREG(1, 123) +/* Reference Power-Up delay: Slow */ +#define AIC3204_REFPU_DELAY_SLOW (0 << 0) +/* Reference Power-Up delay: 40ms */ +#define AIC3204_REFPU_DELAY_40MS (1 << 0) +/* Reference Power-Up delay: 80ms */ +#define AIC3204_REFPU_DELAY_80MS (2 << 0) +/* Reference Power-Up delay: 120ms */ +#define AIC3204_REFPU_DELAY_120MS (3 << 0) +/* Force power-up */ +#define AIC3204_REFPU_FORCE (1 << 2) + +/* TODO: Define the remaining registers ... this will do for now */ + +extern struct snd_soc_dai aic3204_dai; +extern struct snd_soc_codec_device soc_codec_dev_aic3204; + +#endif /* _AIC3204_H */
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
This all looks pretty good, the comments below are fairly minor.
- /* AVDD <->DVDD Link enable */
- u8 avdd_link_en;
What's this? It looks like a boolean which makes u8 an odd choice.
- /* LDO Enable */
- u8 ldo_en;
Similarly here.
- /* Oversampling rate (both ADC and DAC) */
- u8 osr;
Why is this platform data rather than a runtime configurable option?
+config SND_SOC_TLV320AIC3204
- tristate
- depends on I2C
Drop the depends, it doesn't actually do anything for selected items.
- /* Page 1 */
- if (page == 1) {
if (reg <= 4)
return 1;
I can't help but think that this'd be more legible with switch () statements (GCC has an extension for ranges in switch statements which you could use).
+/*
- Pretty-print the value of a register
- */
+static int aic3204_show_reg(struct snd_soc_codec *codec, char *buf,
int buf_sz, unsigned int reg)
+{
- return snprintf(buf, buf_sz, "%02x",
aic3204_read_reg_cache(codec, reg));
+}
This looks suspiciously close to the standard show_reg() - it seems wrong that you should need it.
- /*
* These registers are not manipulated by us, so we must read them from
* the CODEC directly.
*/
Hrm? Also, it strikes me that this code is also used in the WCLK function and might benefit from being factored out - it's moderately verbose.
+static const char *aic3204_micbias_voltages[] = {
- "Low", "Med", "High", "V+"
+};
I'd be inclined to spell medium out and write "V+" as "Supply" or similar unless there's a strong reason to do otherwise - it seems more legible.
+static const char *aic3204_ldac_srcs[] = {
- "disabled", "left channel", "right channel", "mix"
+};
Capital letters are more idiomatic for enumerations.
+/*
- DAC digital volumes. From -63.5 to +24 dB in 0.5 dB steps.
- Does not mute control.
- */
I'm finding these comments a little too verbose but that's just me - I stop and read them only to find there's nothing odd going on here.
- /*
* Note regarding SOC_DOUBLE_R_SX_TLV...
*
* This is a bit misleading; xshift refers to the bit one bit *past*
* the most significant bit. Or at least that's what it appears to be
* doing the math. Mask needs to select the last 6 bits; which is the
* signed bitfield specifiying the gain in dB.
*/
I suspect that fixing the control may break what you're doing here? It would certainly bitrot the comment.
- SOC_SINGLE("Differential Output Switch", AIC3204_DACS2,
AIC3204_DACS2_RMOD_INV_SHIFT, 1, 0),
This feels like platform data - the use of differential outputs is normally a property of the physical wiring of the board, it's very rare to be able to vary this usefully at runtime.
- /* MICBIAS Options */
- SOC_SINGLE("MICBIAS Enable", AIC3204_MICBIAS, 6, 0x1, 0),
MICBIAS Enable should definitely be DAPM.
- SOC_ENUM("MICBIAS Level", aic3204_enum_micbias_voltage),
- SOC_ENUM("MICBIAS Source", aic3204_enum_micbias_src),
These I would expect to be managed in kernel - they're normally either a property of the board or need to be managed in conjunction with jack detection code which tends to live in kernel.
+static const struct snd_soc_dapm_widget aic3204_dapm_widgets[] = {
- /* Driver/Amplifier Selection */
- SND_SOC_DAPM_SWITCH("HPL Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPL_UP_SHIFT, 0,
&aic3204_hpl_switch),
- SND_SOC_DAPM_SWITCH("HPR Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPR_UP_SHIFT, 0,
&aic3204_hpr_switch),
A lot of these SWITCH controls feel like they ought to be PGAs and the switch controls mutes on those. When muting an output you normally don't want to power up and down the path since that is slow and tends to trigger audible issues, you'd normally control the power for path endpoints and elements that affect routing only.
- SND_SOC_DAPM_AIF_IN("Left Data In", "Left Playback",
0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("Right Data In", "Right Playback",
1, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("Left Data Out", "Left Capture",
0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("Right Data Out", "Right Capture",
1, SND_SOC_NOPM, 0, 0),
You have these AIF widgets but at least the DAC input selection was being done in the regular controls rather than in the DAPM routing.
- /*
* Set BCLK and WCLK sources...
*
* Despite DAPM; this is still needed, as DAPM doesn't yet set the
* source at the right time.
*
* TODO: See if we can change the order of initialisation so this
* selection is made after bringing up the ADCs/DACs. Alternative:
* see if we can find out ahead of time which one to use.
It surprises me that the ordering matters too much here; worst case you leave the interface declocked a little longer when you need to switch sources but that doesn't seem like the end of the world?
- snd_soc_update_bits(codec, AIC3204_AISR3, AIC3204_AISR3_BDIV,
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
? AIC3204_AISR3_BDIV_DAC
: AIC3204_AISR3_BDIV_ADC);
I have to say that I'm really not a fan of the ternery operator for legibility.
+static int aic3204_mute(struct snd_soc_dai *dai, int mute) +{
...
- aic3204_write(codec, AIC3204_DACS2, dacs2); /* Unmute DAC */
...or possibly mute it :)
+static int aic3204_resume(struct platform_device *pdev) +{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- int i;
- u8 data[2];
- u8 *cache = codec->reg_cache;
- /* Sync reg_cache with the hardware */
- for (i = 0; i < AIC3204_CACHEREGNUM; i++) {
data[0] = i;
data[1] = cache[i];
codec->hw_write(codec->control_data, data, 2);
Since you've got a register defaults table you could skip rewriting registers which have their default value.
- /* LDO enable, analogue blocks enable */
- snd_soc_update_bits(codec, AIC3204_LDO,
AIC3204_LDO_ANALOG | AIC3204_LDO_AVDD_UP,
AIC3204_LDO_ANALOG_ENABLED |
(aic3204->pdata.ldo_en
? AIC3204_LDO_AVDD_UP : 0));
This looks a bit fishy since the mask covers more bits than can ever be enabled - it reads like the other two bits should be unconditionally cleared.
On Sat, Jun 19, 2010 at 02:12:21AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
This all looks pretty good, the comments below are fairly minor.
- /* AVDD <->DVDD Link enable */
- u8 avdd_link_en;
What's this? It looks like a boolean which makes u8 an odd choice.
- /* LDO Enable */
- u8 ldo_en;
Similarly here.
Well, I didn't see the point in allocating 32-bits when I'd only be using 1 of them. However, I can change it to an int if need be. I'm not certain that C has a true "bool" type, but I could be wrong.
- /* Oversampling rate (both ADC and DAC) */
- u8 osr;
Why is this platform data rather than a runtime configurable option?
How would the application elect a particular oversampling rate? I'll admit I'm very new to the ALSA framework in general, but I didn't realise there was an oversampling rate setting. I'll have a look at how the other drivers do it.
+config SND_SOC_TLV320AIC3204
- tristate
- depends on I2C
Drop the depends, it doesn't actually do anything for selected items.
- /* Page 1 */
- if (page == 1) {
if (reg <= 4)
return 1;
I can't help but think that this'd be more legible with switch () statements (GCC has an extension for ranges in switch statements which you could use).
I did if statements here for two reasons:
(1) Range selection (I was unaware of the GCC extension) (2) I found by experiment that if is slighly more efficient than switch... at least that was the case on MSP430 (using mspgcc). Other platforms could be very different.
+/*
- Pretty-print the value of a register
- */
+static int aic3204_show_reg(struct snd_soc_codec *codec, char *buf,
int buf_sz, unsigned int reg)
+{
- return snprintf(buf, buf_sz, "%02x",
aic3204_read_reg_cache(codec, reg));
+}
This looks suspiciously close to the standard show_reg() - it seems wrong that you should need it.
Well, the main difference; standard show_reg uses %4x as its format; and therefore wastes two characters printing nothing useful. Given space is already tight for displaying register dumps via debugfs, any little bit helps. :-)
Certainly there's no explicit reason why it is necessary and it can go.
- /*
* These registers are not manipulated by us, so we must read them from
* the CODEC directly.
*/
Hrm? Also, it strikes me that this code is also used in the WCLK function and might benefit from being factored out - it's moderately verbose.
The ADC flags register (and the DAC flags registers) are read-only and manipulated by the CODEC when the ADCs and DACs are actually powered up. I could use the flags set elsewhere, but this reflects what *is* the present state, not what ought to be the present state.
There is common code between the WCLK and BCLK functions; in fact I did consider making it the one callback, but since they are separate in the registers, I kept them separate in the callbacks.
+static const char *aic3204_micbias_voltages[] = {
- "Low", "Med", "High", "V+"
+};
I'd be inclined to spell medium out and write "V+" as "Supply" or similar unless there's a strong reason to do otherwise - it seems more legible.
Fair enough... I was originally going to try and use some shortened version of what's in the datasheet... but the values of "Low", "Medium" and "High" are dependant on the selected source and the power rails. "Supply" is probably just as descriptive, if not as compact as "V+"... I'll update that.
+static const char *aic3204_ldac_srcs[] = {
- "disabled", "left channel", "right channel", "mix"
+};
Capital letters are more idiomatic for enumerations.
+/*
- DAC digital volumes. From -63.5 to +24 dB in 0.5 dB steps.
- Does not mute control.
- */
I'm finding these comments a little too verbose but that's just me - I stop and read them only to find there's nothing odd going on here.
Yeah, some of this is due to the fact that, in the early days, I wasn't too sure if this was the "right way". So I figured I'd describe my intentions, and then if I was doing it wrong, people would at least know what was intended, and could suggest improvements.
Now that the mixer is working okay, I could cut this down... but also I hope that others who follow the same path as me, might find this helpful to determine what's going on.
- /*
* Note regarding SOC_DOUBLE_R_SX_TLV...
*
* This is a bit misleading; xshift refers to the bit one bit *past*
* the most significant bit. Or at least that's what it appears to be
* doing the math. Mask needs to select the last 6 bits; which is the
* signed bitfield specifiying the gain in dB.
*/
I suspect that fixing the control may break what you're doing here? It would certainly bitrot the comment.
Well, when the problem goes, so can the comment. :-) One question though, the shift value derives the mask for further operations on these registers... if we were to change the shift value so it reflected how other widget types work, how does one define the mask?
- SOC_SINGLE("Differential Output Switch", AIC3204_DACS2,
AIC3204_DACS2_RMOD_INV_SHIFT, 1, 0),
This feels like platform data - the use of differential outputs is normally a property of the physical wiring of the board, it's very rare to be able to vary this usefully at runtime.
Arguably, so is the DAC audio path routing. I wasn't sure how to set this up at the time, initially it was CODEC setup data, then I moved it into the mixer.
The other consideration here; is the use case where a device with a mono speaker, but a stereo line-out jack... I wasn't sure how to handle these features.
- /* MICBIAS Options */
- SOC_SINGLE("MICBIAS Enable", AIC3204_MICBIAS, 6, 0x1, 0),
MICBIAS Enable should definitely be DAPM.
- SOC_ENUM("MICBIAS Level", aic3204_enum_micbias_voltage),
- SOC_ENUM("MICBIAS Source", aic3204_enum_micbias_src),
These I would expect to be managed in kernel - they're normally either a property of the board or need to be managed in conjunction with jack detection code which tends to live in kernel.
I'll look into this... I was aware of the MICBIAS widget, but will have to do some further research here. As to the others... I wasn't sure how they should be handled.
+static const struct snd_soc_dapm_widget aic3204_dapm_widgets[] = {
- /* Driver/Amplifier Selection */
- SND_SOC_DAPM_SWITCH("HPL Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPL_UP_SHIFT, 0,
&aic3204_hpl_switch),
- SND_SOC_DAPM_SWITCH("HPR Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPR_UP_SHIFT, 0,
&aic3204_hpr_switch),
A lot of these SWITCH controls feel like they ought to be PGAs and the switch controls mutes on those. When muting an output you normally don't want to power up and down the path since that is slow and tends to trigger audible issues, you'd normally control the power for path endpoints and elements that affect routing only.
They are PGAs connecting the driver to its mixer... I wasn't sure how the PGAs worked in DAPM. I knew this did work however, the only catch is that DAPM won't power up the DACs unless you switch them through via these mixers to one of the output drivers. I'll have a closer look at the PGAs and see what they're doing.
- SND_SOC_DAPM_AIF_IN("Left Data In", "Left Playback",
0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("Right Data In", "Right Playback",
1, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("Left Data Out", "Left Capture",
0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("Right Data Out", "Right Capture",
1, SND_SOC_NOPM, 0, 0),
You have these AIF widgets but at least the DAC input selection was being done in the regular controls rather than in the DAPM routing.
Indeed, DAC inputs are selectable, the ADC is not. I should probably making the DAC inputs a MUX... I'll give this a re-think too.
- /*
* Set BCLK and WCLK sources...
*
* Despite DAPM; this is still needed, as DAPM doesn't yet set the
* source at the right time.
*
* TODO: See if we can change the order of initialisation so this
* selection is made after bringing up the ADCs/DACs. Alternative:
* see if we can find out ahead of time which one to use.
It surprises me that the ordering matters too much here; worst case you leave the interface declocked a little longer when you need to switch sources but that doesn't seem like the end of the world?
Well, what I found is that if I didn't do it there... it would call the WCLK and BCLK functions before powering up the DACs/ADCs. Since they have no idea whether recording or playback is in progress (I wasn't sure how to extract this information), the functions rely on the flags registers to determine this.
Therefore, it only works *after* DAPM has turned on the respective parts. Without manually switching it here, the functions see that neither ADC nor DAC is active, and therefore don't do any switching of the BCLK and WCLK. End result; no clocks, DMA times out and the user is left with deafening silence.
This, is probably one of the biggest areas where the DAPM support in this CODEC driver needs work. I tried to follow what was going on in the other CODEC drivers, and I know what's submitted isn't quite right, but it does at least work.
- snd_soc_update_bits(codec, AIC3204_AISR3, AIC3204_AISR3_BDIV,
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
? AIC3204_AISR3_BDIV_DAC
: AIC3204_AISR3_BDIV_ADC);
I have to say that I'm really not a fan of the ternery operator for legibility.
+static int aic3204_mute(struct snd_soc_dai *dai, int mute) +{
...
- aic3204_write(codec, AIC3204_DACS2, dacs2); /* Unmute DAC */
...or possibly mute it :)
Yes, obsolete comment I guess. :-) This is also a mixer control... which is better... leave it to ASoC core, or the user to control PCM mute? The user can mute using the line driver controls... so I guess I should ditch the "PCM Playback Switch" control.
+static int aic3204_resume(struct platform_device *pdev) +{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- int i;
- u8 data[2];
- u8 *cache = codec->reg_cache;
- /* Sync reg_cache with the hardware */
- for (i = 0; i < AIC3204_CACHEREGNUM; i++) {
data[0] = i;
data[1] = cache[i];
codec->hw_write(codec->control_data, data, 2);
Since you've got a register defaults table you could skip rewriting registers which have their default value.
Indeed, suspend/resume isn't tested at all, so no idea if it works or not. I should probably do a forced reset too just to be on the safe side. This is a reminant from the aic3x driver.
- /* LDO enable, analogue blocks enable */
- snd_soc_update_bits(codec, AIC3204_LDO,
AIC3204_LDO_ANALOG | AIC3204_LDO_AVDD_UP,
AIC3204_LDO_ANALOG_ENABLED |
(aic3204->pdata.ldo_en
? AIC3204_LDO_AVDD_UP : 0));
This looks a bit fishy since the mask covers more bits than can ever be enabled - it reads like the other two bits should be unconditionally cleared.
Would I be better breaking that statement up into two statements? I did them as one for efficiency, but I do recognise there is a potential readability issue. Basically, it clears the "analog power-down" bit in the LDO register (yes, this inverse logic irritates me) and optionally turns on the LDO. I figure some users may wish to provide their own AVDD and thus won't want the LDO.
I wasn't sure about the link between AVDD and DVDD, so I left that configurable. I'm guessing most will probably want it disabled. This was configured using arbitrary register initialisation scripts, passed in via the CODEC setup data... so at least things are headded in the right direction. :-)
Regards,
On Sat, Jun 19, 2010 at 07:49:08PM +1000, Stuart Longland wrote:
On Sat, Jun 19, 2010 at 02:12:21AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
- /* LDO Enable */
- u8 ldo_en;
Similarly here.
Well, I didn't see the point in allocating 32-bits when I'd only be using 1 of them. However, I can change it to an int if need be. I'm not certain that C has a true "bool" type, but I could be wrong.
C99 introduced a bool type, and there's always been bitfields. Besides, you're microoptimising something that doesn't need it. When you write u8 that means you really need this field to be unsigned and 8 bits which is a bit confusing for something that's actually just a flag.
- /* Oversampling rate (both ADC and DAC) */
- u8 osr;
Why is this platform data rather than a runtime configurable option?
How would the application elect a particular oversampling rate? I'll admit I'm very new to the ALSA framework in general, but I didn't realise there was an oversampling rate setting. I'll have a look at how the other drivers do it.
The oversampling rate selection is a performance/power tradeoff. The user may choose to do things like use high performance when listening to music but step back a bit when playing system sounds, for example.
There's no specific ALSA control for it, just make it a Switch.
+/*
- Pretty-print the value of a register
- */
+static int aic3204_show_reg(struct snd_soc_codec *codec, char *buf,
int buf_sz, unsigned int reg)
+{
- return snprintf(buf, buf_sz, "%02x",
aic3204_read_reg_cache(codec, reg));
+}
This looks suspiciously close to the standard show_reg() - it seems wrong that you should need it.
Well, the main difference; standard show_reg uses %4x as its format; and therefore wastes two characters printing nothing useful. Given space is already tight for displaying register dumps via debugfs, any little bit helps. :-)
Certainly there's no explicit reason why it is necessary and it can go.
If you want to do this it'd be better to add support to the core, for example by keying off a register width supplied by the CODEC.
- /*
* These registers are not manipulated by us, so we must read them from
* the CODEC directly.
*/
Hrm? Also, it strikes me that this code is also used in the WCLK function and might benefit from being factored out - it's moderately verbose.
The ADC flags register (and the DAC flags registers) are read-only and manipulated by the CODEC when the ADCs and DACs are actually powered up. I could use the flags set elsewhere, but this reflects what *is* the present state, not what ought to be the present state.
This strikes me as something that's going to hit a race condition at some point - if the two differ I'd hope that the state the driver has set is going to be the actual CODEC state very soon.
There is common code between the WCLK and BCLK functions; in fact I did consider making it the one callback, but since they are separate in the registers, I kept them separate in the callbacks.
I was thinking more a utility function that both callbacks use to work out which of the DACs and ADCs are powered.
Now that the mixer is working okay, I could cut this down... but also I hope that others who follow the same path as me, might find this helpful to determine what's going on.
If we're going to do that we'd need to be doing it for every single TLV control in every single driver...
Well, when the problem goes, so can the comment. :-) One question though, the shift value derives the mask for further operations on these registers... if we were to change the shift value so it reflected how other widget types work, how does one define the mask?
I'd intuitively expect it to be relative to the start of the controlled data rather than the start of the register.
- SOC_SINGLE("Differential Output Switch", AIC3204_DACS2,
AIC3204_DACS2_RMOD_INV_SHIFT, 1, 0),
This feels like platform data - the use of differential outputs is normally a property of the physical wiring of the board, it's very rare to be able to vary this usefully at runtime.
Arguably, so is the DAC audio path routing. I wasn't sure how to set this up at the time, initially it was CODEC setup data, then I moved it into the mixer.
The DAC routing can be usefully varied at runtime depending on the use case - for example, sometimes people choose to route a mono signal into both DACs to give stereo output. It would be very unusual hardware that provided a way of switching between single ended and differential in a similar fashion.
The other consideration here; is the use case where a device with a mono speaker, but a stereo line-out jack... I wasn't sure how to handle these features.
Presumably you can make individual outputs differential and single ended then?
- SOC_ENUM("MICBIAS Level", aic3204_enum_micbias_voltage),
- SOC_ENUM("MICBIAS Source", aic3204_enum_micbias_src),
These I would expect to be managed in kernel - they're normally either a property of the board or need to be managed in conjunction with jack detection code which tends to live in kernel.
I'll look into this... I was aware of the MICBIAS widget, but will have to do some further research here. As to the others... I wasn't sure how they should be handled.
Platform data initially then provide a runtime API for machine drivers if requireed.
+static const struct snd_soc_dapm_widget aic3204_dapm_widgets[] = {
- /* Driver/Amplifier Selection */
- SND_SOC_DAPM_SWITCH("HPL Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPL_UP_SHIFT, 0,
&aic3204_hpl_switch),
- SND_SOC_DAPM_SWITCH("HPR Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPR_UP_SHIFT, 0,
&aic3204_hpr_switch),
A lot of these SWITCH controls feel like they ought to be PGAs and the switch controls mutes on those. When muting an output you normally don't want to power up and down the path since that is slow and tends to trigger audible issues, you'd normally control the power for path endpoints and elements that affect routing only.
They are PGAs connecting the driver to its mixer... I wasn't sure how the PGAs worked in DAPM. I knew this did work however, the only catch
These should definitely be PGA widgets as described above.
is that DAPM won't power up the DACs unless you switch them through via these mixers to one of the output drivers. I'll have a closer look at the PGAs and see what they're doing.
Not powering up the DACs unless there is a connected output path is the expected behaviour.
It surprises me that the ordering matters too much here; worst case you leave the interface declocked a little longer when you need to switch sources but that doesn't seem like the end of the world?
Well, what I found is that if I didn't do it there... it would call the WCLK and BCLK functions before powering up the DACs/ADCs. Since they have no idea whether recording or playback is in progress (I wasn't sure how to extract this information), the functions rely on the flags registers to determine this.
If you track this in the audio path setup/teardown path instead of looking at the DAC power status you should find everything works fine.
+static int aic3204_mute(struct snd_soc_dai *dai, int mute) +{
...
- aic3204_write(codec, AIC3204_DACS2, dacs2); /* Unmute DAC */
...or possibly mute it :)
Yes, obsolete comment I guess. :-) This is also a mixer control... which is better... leave it to ASoC core, or the user to control PCM mute? The user can mute using the line driver controls... so I guess I should ditch the "PCM Playback Switch" control.
Remove the mixer control. The automatic management ensures that no noise that is generated when starting up the audio stream propagates into the output path and that any soft unmute support in the CODEC gets used to stop you having a hard power up with an active signal.
- for (i = 0; i < AIC3204_CACHEREGNUM; i++) {
data[0] = i;
data[1] = cache[i];
codec->hw_write(codec->control_data, data, 2);
Since you've got a register defaults table you could skip rewriting registers which have their default value.
Indeed, suspend/resume isn't tested at all, so no idea if it works or not. I should probably do a forced reset too just to be on the safe side. This is a reminant from the aic3x driver.
The reset should not be required, either the device will be as you left it or the power will have gone so it will be in the reset state anyway.
- /* LDO enable, analogue blocks enable */
- snd_soc_update_bits(codec, AIC3204_LDO,
AIC3204_LDO_ANALOG | AIC3204_LDO_AVDD_UP,
AIC3204_LDO_ANALOG_ENABLED |
(aic3204->pdata.ldo_en
? AIC3204_LDO_AVDD_UP : 0));
This looks a bit fishy since the mask covers more bits than can ever be enabled - it reads like the other two bits should be unconditionally cleared.
Would I be better breaking that statement up into two statements? I did
Yes, it would be much more legible.
I wasn't sure about the link between AVDD and DVDD, so I left that configurable. I'm guessing most will probably want it disabled. This was configured using arbitrary register initialisation scripts, passed in via the CODEC setup data... so at least things are headded in the right direction. :-)
What does this register actually do? Does it describe the hardware configuration to the device?
[Dropping Linux kernel mailing lists, since this is ALSA-specific.]
On Sat, Jun 19, 2010 at 11:57:07AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 07:49:08PM +1000, Stuart Longland wrote:
On Sat, Jun 19, 2010 at 02:12:21AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
- /* LDO Enable */
- u8 ldo_en;
Similarly here.
Well, I didn't see the point in allocating 32-bits when I'd only be using 1 of them. However, I can change it to an int if need be. I'm not certain that C has a true "bool" type, but I could be wrong.
C99 introduced a bool type, and there's always been bitfields. Besides, you're microoptimising something that doesn't need it. When you write u8 that means you really need this field to be unsigned and 8 bits which is a bit confusing for something that's actually just a flag.
No worries, I'll swap it for a bool then. :-)
- /* Oversampling rate (both ADC and DAC) */
- u8 osr;
Why is this platform data rather than a runtime configurable option?
How would the application elect a particular oversampling rate? I'll admit I'm very new to the ALSA framework in general, but I didn't realise there was an oversampling rate setting. I'll have a look at how the other drivers do it.
The oversampling rate selection is a performance/power tradeoff. The user may choose to do things like use high performance when listening to music but step back a bit when playing system sounds, for example.
There's no specific ALSA control for it, just make it a Switch.
Are switches variable? For what its worth, I've simplified things by assuming the oversampling rate is identical for DAC and ADC. It is possible to have DAC OSRs up to 1024... but the ADC OSR is limited to 128. I keep them identical as it simplifies clock generation.
I'm thinking if I make this a control, it'd have to be some numeric control (not a TLV, but something similar with a linear scale).
This looks suspiciously close to the standard show_reg() - it seems wrong that you should need it.
Well, the main difference; standard show_reg uses %4x as its format; and therefore wastes two characters printing nothing useful. Given space is already tight for displaying register dumps via debugfs, any little bit helps. :-)
Certainly there's no explicit reason why it is necessary and it can go.
If you want to do this it'd be better to add support to the core, for example by keying off a register width supplied by the CODEC.
I'll give this some thought... as it'd also be useful to format the register numbers as being 16-bits wide rather than 8-bits too.
- /*
* These registers are not manipulated by us, so we must read them from
* the CODEC directly.
*/
Hrm? Also, it strikes me that this code is also used in the WCLK function and might benefit from being factored out - it's moderately verbose.
The ADC flags register (and the DAC flags registers) are read-only and manipulated by the CODEC when the ADCs and DACs are actually powered up. I could use the flags set elsewhere, but this reflects what *is* the present state, not what ought to be the present state.
This strikes me as something that's going to hit a race condition at some point - if the two differ I'd hope that the state the driver has set is going to be the actual CODEC state very soon.
Yeah... it's problematic... by far this is the thing that needs the most work out of all of it.
There is common code between the WCLK and BCLK functions; in fact I did consider making it the one callback, but since they are separate in the registers, I kept them separate in the callbacks.
I was thinking more a utility function that both callbacks use to work out which of the DACs and ADCs are powered.
Ahh yes, makes sense.
Now that the mixer is working okay, I could cut this down... but also I hope that others who follow the same path as me, might find this helpful to determine what's going on.
If we're going to do that we'd need to be doing it for every single TLV control in every single driver...
Understood, I'll tidy this up in the next revision.
Well, when the problem goes, so can the comment. :-) One question though, the shift value derives the mask for further operations on these registers... if we were to change the shift value so it reflected how other widget types work, how does one define the mask?
I'd intuitively expect it to be relative to the start of the controlled data rather than the start of the register.
Correct... but how do you define the mask's width? Would that be derived from min or max (or both)?
- SOC_SINGLE("Differential Output Switch", AIC3204_DACS2,
AIC3204_DACS2_RMOD_INV_SHIFT, 1, 0),
This feels like platform data - the use of differential outputs is normally a property of the physical wiring of the board, it's very rare to be able to vary this usefully at runtime.
Arguably, so is the DAC audio path routing. I wasn't sure how to set this up at the time, initially it was CODEC setup data, then I moved it into the mixer.
The DAC routing can be usefully varied at runtime depending on the use case - for example, sometimes people choose to route a mono signal into both DACs to give stereo output. It would be very unusual hardware that provided a way of switching between single ended and differential in a similar fashion.
Indeed the routing controls I've provided via standard SOC controls, allows this. It also allows routing a stereo signal to a mono output (which is what we do; since the I²S bus doesn't seem to like mono).
I wasn't sure how else to do it, and this seemed to be the most flexible option. However, if it's better as platform data, then platform data it is. ;-)
- SOC_ENUM("MICBIAS Level", aic3204_enum_micbias_voltage),
- SOC_ENUM("MICBIAS Source", aic3204_enum_micbias_src),
These I would expect to be managed in kernel - they're normally either a property of the board or need to be managed in conjunction with jack detection code which tends to live in kernel.
I'll look into this... I was aware of the MICBIAS widget, but will have to do some further research here. As to the others... I wasn't sure how they should be handled.
Platform data initially then provide a runtime API for machine drivers if requireed.
Okay, sounds reasonable. :-)
+static const struct snd_soc_dapm_widget aic3204_dapm_widgets[] = {
- /* Driver/Amplifier Selection */
- SND_SOC_DAPM_SWITCH("HPL Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPL_UP_SHIFT, 0,
&aic3204_hpl_switch),
- SND_SOC_DAPM_SWITCH("HPR Playback Switch", AIC3204_OUTDRV,
AIC3204_OUTDRV_HPR_UP_SHIFT, 0,
&aic3204_hpr_switch),
A lot of these SWITCH controls feel like they ought to be PGAs and the switch controls mutes on those. When muting an output you normally don't want to power up and down the path since that is slow and tends to trigger audible issues, you'd normally control the power for path endpoints and elements that affect routing only.
They are PGAs connecting the driver to its mixer... I wasn't sure how the PGAs worked in DAPM. I knew this did work however, the only catch
These should definitely be PGA widgets as described above.
No problems, I'll convert these.
is that DAPM won't power up the DACs unless you switch them through via these mixers to one of the output drivers. I'll have a closer look at the PGAs and see what they're doing.
Not powering up the DACs unless there is a connected output path is the expected behaviour.
Yeah, this is to be expected, doesn't mean I haven't been caught out by it more than once. The thing with the TLV320AIC3204... the bit clock is derived from one of two sources (actually four)... the ADC's clock, or the DAC's clock. If the ADCs are powered down, there's no ADC clock. Likewise for the DAC.
The end result is that when ALSA tries recording or playback with the DACs and ADCs powered down, it falls flat on its face because the clocks aren't present. Easily fixed ... you just connect the PGAs up in alsamixer, but it's one of the gotchas with this driver. ;-)
It surprises me that the ordering matters too much here; worst case you leave the interface declocked a little longer when you need to switch sources but that doesn't seem like the end of the world?
Well, what I found is that if I didn't do it there... it would call the WCLK and BCLK functions before powering up the DACs/ADCs. Since they have no idea whether recording or playback is in progress (I wasn't sure how to extract this information), the functions rely on the flags registers to determine this.
If you track this in the audio path setup/teardown path instead of looking at the DAC power status you should find everything works fine.
I'll have a closer look then. I figured I was "doing it wrong", but couldn't see what the right way was. Would the event-handling widgets be of use here?
+static int aic3204_mute(struct snd_soc_dai *dai, int mute) +{
...
- aic3204_write(codec, AIC3204_DACS2, dacs2); /* Unmute DAC */
...or possibly mute it :)
Yes, obsolete comment I guess. :-) This is also a mixer control... which is better... leave it to ASoC core, or the user to control PCM mute? The user can mute using the line driver controls... so I guess I should ditch the "PCM Playback Switch" control.
Remove the mixer control. The automatic management ensures that no noise that is generated when starting up the audio stream propagates into the output path and that any soft unmute support in the CODEC gets used to stop you having a hard power up with an active signal.
Okay, it'll be gone in the next patch.
- for (i = 0; i < AIC3204_CACHEREGNUM; i++) {
data[0] = i;
data[1] = cache[i];
codec->hw_write(codec->control_data, data, 2);
Since you've got a register defaults table you could skip rewriting registers which have their default value.
Indeed, suspend/resume isn't tested at all, so no idea if it works or not. I should probably do a forced reset too just to be on the safe side. This is a reminant from the aic3x driver.
The reset should not be required, either the device will be as you left it or the power will have gone so it will be in the reset state anyway.
Yep, fair enough... I guess I like making absolutely sure. Another hacky way of doing this would be to fiddle with the cache so that the reset register has the correct value to cause a soft reset, but let's not go there. ;-)
- /* LDO enable, analogue blocks enable */
- snd_soc_update_bits(codec, AIC3204_LDO,
AIC3204_LDO_ANALOG | AIC3204_LDO_AVDD_UP,
AIC3204_LDO_ANALOG_ENABLED |
(aic3204->pdata.ldo_en
? AIC3204_LDO_AVDD_UP : 0));
This looks a bit fishy since the mask covers more bits than can ever be enabled - it reads like the other two bits should be unconditionally cleared.
Would I be better breaking that statement up into two statements? I did
Yes, it would be much more legible.
No worries, I'll break this up.
I wasn't sure about the link between AVDD and DVDD, so I left that configurable. I'm guessing most will probably want it disabled. This was configured using arbitrary register initialisation scripts, passed in via the CODEC setup data... so at least things are headded in the right direction. :-)
What does this register actually do? Does it describe the hardware configuration to the device?
This is where I'm not clear on exactly what's going on... TI's documentation seems to have a fair bit to be desired. When the CODEC powers up, the AVDD and DVDD are weakly connected together by some high resistance inside the chip.
This register allows you to break that link so that AVDD and DVDD are separate. I'm guessing this would be the norm, perhaps I'll just ditch the relevant platform data configuration.
BTW: thanks for the advice thus far. :-)
On Sun, Jun 20, 2010 at 09:28:41PM +1000, Stuart Longland wrote:
On Sat, Jun 19, 2010 at 11:57:07AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 07:49:08PM +1000, Stuart Longland wrote:
On Sat, Jun 19, 2010 at 02:12:21AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
There's no specific ALSA control for it, just make it a Switch.
Are switches variable? For what its worth, I've simplified things by assuming the oversampling rate is identical for DAC and ADC. It is possible to have DAC OSRs up to 1024... but the ADC OSR is limited to 128. I keep them identical as it simplifies clock generation.
I'm thinking if I make this a control, it'd have to be some numeric control (not a TLV, but something similar with a linear scale).
If there's a range of selectable options then use an enum. Otherwise a regular ALSA control gives a linear mapping, but you can't skip any values.
Well, when the problem goes, so can the comment. :-) One question though, the shift value derives the mask for further operations on these registers... if we were to change the shift value so it reflected how other widget types work, how does one define the mask?
I'd intuitively expect it to be relative to the start of the controlled data rather than the start of the register.
Correct... but how do you define the mask's width? Would that be derived from min or max (or both)?
I'd expect it to define the bits to be overwritten by the update - it'd be related to the min and the max in that both need to be stored in a value masked out but not directly (note that I've not gone so far as to look at the actual control definition here).
I wasn't sure how else to do it, and this seemed to be the most flexible option. However, if it's better as platform data, then platform data it is. ;-)
It's flexible but it's flexibility that it's not possible to actually use - like I say, these things get fixed when the board is laid out in almost all cases.
Yeah, this is to be expected, doesn't mean I haven't been caught out by it more than once. The thing with the TLV320AIC3204... the bit clock is derived from one of two sources (actually four)... the ADC's clock, or the DAC's clock. If the ADCs are powered down, there's no ADC clock. Likewise for the DAC.
Consider creating supply widgets for the actual DACs and ADCs then using those to supply the clocks and NOPM DAC/ADC widgets. Not thought that through fully but I think it'd do the right thing.
If you track this in the audio path setup/teardown path instead of looking at the DAC power status you should find everything works fine.
I'll have a closer look then. I figured I was "doing it wrong", but couldn't see what the right way was. Would the event-handling widgets be of use here?
Possibly, another way of dealing with it might be to set the sources for all the clocks whenever you power up or down a DAC or ADC rather than based off the clock widgets themselves.
I wasn't sure about the link between AVDD and DVDD, so I left that configurable. I'm guessing most will probably want it disabled. This was configured using arbitrary register initialisation scripts, passed in via the CODEC setup data... so at least things are headded in the right direction. :-)
What does this register actually do? Does it describe the hardware configuration to the device?
This is where I'm not clear on exactly what's going on... TI's documentation seems to have a fair bit to be desired. When the CODEC powers up, the AVDD and DVDD are weakly connected together by some high resistance inside the chip.
This register allows you to break that link so that AVDD and DVDD are separate. I'm guessing this would be the norm, perhaps I'll just ditch the relevant platform data configuration.
That sounds... intresting. I note that there's an LDO in there - is this for bootstrapping the LDO by any chance? Power DVDD from AVDD until the LDO has been enabled by software and then disable the link.
On Sat, Jun 19, 2010 at 02:12:21AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
- /* Page 1 */
- if (page == 1) {
if (reg <= 4)
return 1;
I can't help but think that this'd be more legible with switch () statements (GCC has an extension for ranges in switch statements which you could use).
I gave this some further thought... I'm not certain that a switch statement is going to be much clearer. There are two ways I can tackle this.
One is to go on a page-by-page basis, which is how I do it using the if statements. Here; I define my ranges so that I start from the very end... anything beyond page 70 is invalid ... voila, I eliminate those early on. A number of pages have a similar register pattern, and so I make use of nested if statements to explain this. The if block for pages following always use the block before to define the upper, non-inclusive bound.
The register tests start from register 0. I could perhaps reverse the outer ifs to start at page 0 and work forwards too... but I instead work backwards from page 70.
I exit the function as early as possible to skip unneeded checks, as soon as I know a range is valid or not, I return 1 or 0. Perhaps the 1 or 0 could be made clearer (a couple of #defines maybe?) but to me, it looks fairly clear.
I could use switch statements to replace some or all of the if statements. There'd be a small benefit I suppose in making the outer if statements a switch, but little anywhere else from what I can see.
The other way is that I ignore pages completely; and use the AIC3204_PGREG macro to define ranges of absolute register addresses. This may have a small benefit in speed since these are compiled in... as opposed to runtime masking/shifting, but I don't see that being much clearer either. I'd still come to a case statement, then return.
This is a function largely intended for debugging, in fact, I'm thinking I should probably wrap it in #ifdef CONFIG_DEBUG_FS, since the function isn't called unless debugfs is enabled. So I'm not certain that performance is worth chasing here given the intended purpose -- it's not something that's called all the time, nor something that will be used in a production environment.
That's my thoughts on the issue, perhaps naïve, but I'm not sure there's any real gain in refactoring this.
On Tue, Jun 22, 2010 at 09:43:14AM +1000, Stuart Longland wrote:
On Sat, Jun 19, 2010 at 02:12:21AM +0100, Mark Brown wrote:
On Sat, Jun 19, 2010 at 08:24:36AM +1000, Stuart Longland wrote:
- /* Page 1 */
- if (page == 1) {
if (reg <= 4)
return 1;
I can't help but think that this'd be more legible with switch () statements (GCC has an extension for ranges in switch statements which you could use).
One is to go on a page-by-page basis, which is how I do it using the if statements. Here; I define my ranges so that I start from the very end... anything beyond page 70 is invalid ... voila, I eliminate those early on. A number of pages have a similar register pattern, and so I make use of nested if statements to explain this. The if block for pages following always use the block before to define the upper, non-inclusive bound.
It's not so much the outer ifs that were bothering me, it's the inner ones where you're doing the final register ranges as just a sequence of if statements (not even if ... else) which really bothered me here. The code just doesn't look like what it's trying to do.
This is a function largely intended for debugging, in fact, I'm thinking I should probably wrap it in #ifdef CONFIG_DEBUG_FS, since the function isn't called unless debugfs is enabled. So I'm not certain that performance is worth chasing here given the intended purpose -- it's not something that's called all the time, nor something that will be used in a production environment.
Oh, I thought you were using it to filter the CODEC register displays?
That's my thoughts on the issue, perhaps naïve, but I'm not sure there's any real gain in refactoring this.
It's fairly hard to read at the minute -
participants (2)
-
Mark Brown
-
Stuart Longland