From dd1b3d53c2e5b9cccec9001fc0b63f6b686a4ac9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Dec 2009 14:22:03 +0000 Subject: ASoC: Export snd_soc_update_bits_unlocked() Allows custom controls to use it. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index 0d7718f9280d..08909ccd235b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -253,6 +253,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, /* codec register bit access */ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, unsigned int mask, unsigned int value); +int snd_soc_update_bits_locked(struct snd_soc_codec *codec, + unsigned short reg, unsigned int mask, + unsigned int value); int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, unsigned int mask, unsigned int value); -- cgit v1.2.3 From a91eb199e4dc8a2ab3fb7a53f1a23ce82b29fc04 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 26 Nov 2009 11:56:07 +0000 Subject: ASoC: Initial WM8904 CODEC driver The WM8904 is a high performance ultra-low power stereo CODEC optimised for portable audio applications, with features including a class W amplifier, FLL with free running mode, Mobile ReTune and ground referenced headphone and line outputs. Support for some features, most particularly the digital microphone interface, is not yet present. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/wm8904.h | 57 + sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8904.c | 2538 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8904.h | 1681 ++++++++++++++++++++++++++++++ 5 files changed, 4282 insertions(+) create mode 100644 include/sound/wm8904.h create mode 100644 sound/soc/codecs/wm8904.c create mode 100644 sound/soc/codecs/wm8904.h (limited to 'include') diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h new file mode 100644 index 000000000000..d66575a601be --- /dev/null +++ b/include/sound/wm8904.h @@ -0,0 +1,57 @@ +/* + * Platform data for WM8904 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __MFD_WM8994_PDATA_H__ +#define __MFD_WM8994_PDATA_H__ + +#define WM8904_DRC_REGS 4 +#define WM8904_EQ_REGS 25 + +/** + * DRC configurations are specified with a label and a set of register + * values to write (the enable bits will be ignored). At runtime an + * enumerated control will be presented for each DRC block allowing + * the user to choose the configration to use. + * + * Configurations may be generated by hand or by using the DRC control + * panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/ + * for details. + */ +struct wm8904_drc_cfg { + const char *name; + u16 regs[WM8904_DRC_REGS]; +}; + +/** + * ReTune Mobile configurations are specified with a label, sample + * rate and set of values to write (the enable bits will be ignored). + * + * Configurations are expected to be generated using the ReTune Mobile + * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/ + */ +struct wm8904_retune_mobile_cfg { + const char *name; + unsigned int rate; + u16 regs[WM8904_EQ_REGS]; +}; + +struct wm8904_pdata { + int num_drc_cfgs; + struct wm8904_drc_cfg *drc_cfgs; + + int num_retune_mobile_cfgs; + struct wm8904_retune_mobile_cfg *retune_mobile_cfgs; +}; + +#endif diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 52b005f8fed4..011d3ab7e64a 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -49,6 +49,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C + select SND_SOC_WM8904 if I2C select SND_SOC_WM8940 if I2C select SND_SOC_WM8960 if I2C select SND_SOC_WM8961 if I2C @@ -203,6 +204,9 @@ config SND_SOC_WM8900 config SND_SOC_WM8903 tristate +config SND_SOC_WM8904 + tristate + config SND_SOC_WM8940 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index dbaecb133ac7..0471d9044205 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -36,6 +36,7 @@ snd-soc-wm8753-objs := wm8753.o snd-soc-wm8776-objs := wm8776.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o +snd-soc-wm8904-objs := wm8904.o snd-soc-wm8940-objs := wm8940.o snd-soc-wm8960-objs := wm8960.o snd-soc-wm8961-objs := wm8961.o @@ -92,6 +93,7 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o +obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c new file mode 100644 index 000000000000..8310e5d14b83 --- /dev/null +++ b/sound/soc/codecs/wm8904.c @@ -0,0 +1,2538 @@ +/* + * wm8904.c -- WM8904 ALSA SoC Audio driver + * + * Copyright 2009 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8904.h" + +static struct snd_soc_codec *wm8904_codec; +struct snd_soc_codec_device soc_codec_dev_wm8904; + +#define WM8904_NUM_DCS_CHANNELS 4 + +#define WM8904_NUM_SUPPLIES 5 +static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { + "DCVDD", + "DBVDD", + "AVDD", + "CPVDD", + "MICVDD", +}; + +/* codec private data */ +struct wm8904_priv { + struct snd_soc_codec codec; + u16 reg_cache[WM8904_MAX_REGISTER + 1]; + + struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; + + struct wm8904_pdata *pdata; + + int deemph; + + /* Platform provided DRC configuration */ + const char **drc_texts; + int drc_cfg; + struct soc_enum drc_enum; + + /* Platform provided ReTune mobile configuration */ + int num_retune_mobile_texts; + const char **retune_mobile_texts; + int retune_mobile_cfg; + struct soc_enum retune_mobile_enum; + + /* FLL setup */ + int fll_src; + int fll_fref; + int fll_fout; + + /* Clocking configuration */ + unsigned int mclk_rate; + int sysclk_src; + unsigned int sysclk_rate; + + int tdm_width; + int tdm_slots; + int bclk; + int fs; + + /* DC servo configuration - cached offset values */ + int dcs_state[WM8904_NUM_DCS_CHANNELS]; +}; + +static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = { + 0x8904, /* R0 - SW Reset and ID */ + 0x0000, /* R1 - Revision */ + 0x0000, /* R2 */ + 0x0000, /* R3 */ + 0x0018, /* R4 - Bias Control 0 */ + 0x0000, /* R5 - VMID Control 0 */ + 0x0000, /* R6 - Mic Bias Control 0 */ + 0x0000, /* R7 - Mic Bias Control 1 */ + 0x0001, /* R8 - Analogue DAC 0 */ + 0x9696, /* R9 - mic Filter Control */ + 0x0001, /* R10 - Analogue ADC 0 */ + 0x0000, /* R11 */ + 0x0000, /* R12 - Power Management 0 */ + 0x0000, /* R13 */ + 0x0000, /* R14 - Power Management 2 */ + 0x0000, /* R15 - Power Management 3 */ + 0x0000, /* R16 */ + 0x0000, /* R17 */ + 0x0000, /* R18 - Power Management 6 */ + 0x0000, /* R19 */ + 0x945E, /* R20 - Clock Rates 0 */ + 0x0C05, /* R21 - Clock Rates 1 */ + 0x0006, /* R22 - Clock Rates 2 */ + 0x0000, /* R23 */ + 0x0050, /* R24 - Audio Interface 0 */ + 0x000A, /* R25 - Audio Interface 1 */ + 0x00E4, /* R26 - Audio Interface 2 */ + 0x0040, /* R27 - Audio Interface 3 */ + 0x0000, /* R28 */ + 0x0000, /* R29 */ + 0x00C0, /* R30 - DAC Digital Volume Left */ + 0x00C0, /* R31 - DAC Digital Volume Right */ + 0x0000, /* R32 - DAC Digital 0 */ + 0x0008, /* R33 - DAC Digital 1 */ + 0x0000, /* R34 */ + 0x0000, /* R35 */ + 0x00C0, /* R36 - ADC Digital Volume Left */ + 0x00C0, /* R37 - ADC Digital Volume Right */ + 0x0010, /* R38 - ADC Digital 0 */ + 0x0000, /* R39 - Digital Microphone 0 */ + 0x01AF, /* R40 - DRC 0 */ + 0x3248, /* R41 - DRC 1 */ + 0x0000, /* R42 - DRC 2 */ + 0x0000, /* R43 - DRC 3 */ + 0x0085, /* R44 - Analogue Left Input 0 */ + 0x0085, /* R45 - Analogue Right Input 0 */ + 0x0044, /* R46 - Analogue Left Input 1 */ + 0x0044, /* R47 - Analogue Right Input 1 */ + 0x0000, /* R48 */ + 0x0000, /* R49 */ + 0x0000, /* R50 */ + 0x0000, /* R51 */ + 0x0000, /* R52 */ + 0x0000, /* R53 */ + 0x0000, /* R54 */ + 0x0000, /* R55 */ + 0x0000, /* R56 */ + 0x002D, /* R57 - Analogue OUT1 Left */ + 0x002D, /* R58 - Analogue OUT1 Right */ + 0x0039, /* R59 - Analogue OUT2 Left */ + 0x0039, /* R60 - Analogue OUT2 Right */ + 0x0000, /* R61 - Analogue OUT12 ZC */ + 0x0000, /* R62 */ + 0x0000, /* R63 */ + 0x0000, /* R64 */ + 0x0000, /* R65 */ + 0x0000, /* R66 */ + 0x0000, /* R67 - DC Servo 0 */ + 0x0000, /* R68 - DC Servo 1 */ + 0xAAAA, /* R69 - DC Servo 2 */ + 0x0000, /* R70 */ + 0xAAAA, /* R71 - DC Servo 4 */ + 0xAAAA, /* R72 - DC Servo 5 */ + 0x0000, /* R73 - DC Servo 6 */ + 0x0000, /* R74 - DC Servo 7 */ + 0x0000, /* R75 - DC Servo 8 */ + 0x0000, /* R76 - DC Servo 9 */ + 0x0000, /* R77 - DC Servo Readback 0 */ + 0x0000, /* R78 */ + 0x0000, /* R79 */ + 0x0000, /* R80 */ + 0x0000, /* R81 */ + 0x0000, /* R82 */ + 0x0000, /* R83 */ + 0x0000, /* R84 */ + 0x0000, /* R85 */ + 0x0000, /* R86 */ + 0x0000, /* R87 */ + 0x0000, /* R88 */ + 0x0000, /* R89 */ + 0x0000, /* R90 - Analogue HP 0 */ + 0x0000, /* R91 */ + 0x0000, /* R92 */ + 0x0000, /* R93 */ + 0x0000, /* R94 - Analogue Lineout 0 */ + 0x0000, /* R95 */ + 0x0000, /* R96 */ + 0x0000, /* R97 */ + 0x0000, /* R98 - Charge Pump 0 */ + 0x0000, /* R99 */ + 0x0000, /* R100 */ + 0x0000, /* R101 */ + 0x0000, /* R102 */ + 0x0000, /* R103 */ + 0x0004, /* R104 - Class W 0 */ + 0x0000, /* R105 */ + 0x0000, /* R106 */ + 0x0000, /* R107 */ + 0x0000, /* R108 - Write Sequencer 0 */ + 0x0000, /* R109 - Write Sequencer 1 */ + 0x0000, /* R110 - Write Sequencer 2 */ + 0x0000, /* R111 - Write Sequencer 3 */ + 0x0000, /* R112 - Write Sequencer 4 */ + 0x0000, /* R113 */ + 0x0000, /* R114 */ + 0x0000, /* R115 */ + 0x0000, /* R116 - FLL Control 1 */ + 0x0007, /* R117 - FLL Control 2 */ + 0x0000, /* R118 - FLL Control 3 */ + 0x2EE0, /* R119 - FLL Control 4 */ + 0x0004, /* R120 - FLL Control 5 */ + 0x0014, /* R121 - GPIO Control 1 */ + 0x0010, /* R122 - GPIO Control 2 */ + 0x0010, /* R123 - GPIO Control 3 */ + 0x0000, /* R124 - GPIO Control 4 */ + 0x0000, /* R125 */ + 0x0000, /* R126 - Digital Pulls */ + 0x0000, /* R127 - Interrupt Status */ + 0xFFFF, /* R128 - Interrupt Status Mask */ + 0x0000, /* R129 - Interrupt Polarity */ + 0x0000, /* R130 - Interrupt Debounce */ + 0x0000, /* R131 */ + 0x0000, /* R132 */ + 0x0000, /* R133 */ + 0x0000, /* R134 - EQ1 */ + 0x000C, /* R135 - EQ2 */ + 0x000C, /* R136 - EQ3 */ + 0x000C, /* R137 - EQ4 */ + 0x000C, /* R138 - EQ5 */ + 0x000C, /* R139 - EQ6 */ + 0x0FCA, /* R140 - EQ7 */ + 0x0400, /* R141 - EQ8 */ + 0x00D8, /* R142 - EQ9 */ + 0x1EB5, /* R143 - EQ10 */ + 0xF145, /* R144 - EQ11 */ + 0x0B75, /* R145 - EQ12 */ + 0x01C5, /* R146 - EQ13 */ + 0x1C58, /* R147 - EQ14 */ + 0xF373, /* R148 - EQ15 */ + 0x0A54, /* R149 - EQ16 */ + 0x0558, /* R150 - EQ17 */ + 0x168E, /* R151 - EQ18 */ + 0xF829, /* R152 - EQ19 */ + 0x07AD, /* R153 - EQ20 */ + 0x1103, /* R154 - EQ21 */ + 0x0564, /* R155 - EQ22 */ + 0x0559, /* R156 - EQ23 */ + 0x4000, /* R157 - EQ24 */ + 0x0000, /* R158 */ + 0x0000, /* R159 */ + 0x0000, /* R160 */ + 0x0000, /* R161 - Control Interface Test 1 */ + 0x0000, /* R162 */ + 0x0000, /* R163 */ + 0x0000, /* R164 */ + 0x0000, /* R165 */ + 0x0000, /* R166 */ + 0x0000, /* R167 */ + 0x0000, /* R168 */ + 0x0000, /* R169 */ + 0x0000, /* R170 */ + 0x0000, /* R171 */ + 0x0000, /* R172 */ + 0x0000, /* R173 */ + 0x0000, /* R174 */ + 0x0000, /* R175 */ + 0x0000, /* R176 */ + 0x0000, /* R177 */ + 0x0000, /* R178 */ + 0x0000, /* R179 */ + 0x0000, /* R180 */ + 0x0000, /* R181 */ + 0x0000, /* R182 */ + 0x0000, /* R183 */ + 0x0000, /* R184 */ + 0x0000, /* R185 */ + 0x0000, /* R186 */ + 0x0000, /* R187 */ + 0x0000, /* R188 */ + 0x0000, /* R189 */ + 0x0000, /* R190 */ + 0x0000, /* R191 */ + 0x0000, /* R192 */ + 0x0000, /* R193 */ + 0x0000, /* R194 */ + 0x0000, /* R195 */ + 0x0000, /* R196 */ + 0x0000, /* R197 */ + 0x0000, /* R198 */ + 0x0000, /* R199 */ + 0x0000, /* R200 */ + 0x0000, /* R201 */ + 0x0000, /* R202 */ + 0x0000, /* R203 */ + 0x0000, /* R204 - Analogue Output Bias 0 */ + 0x0000, /* R205 */ + 0x0000, /* R206 */ + 0x0000, /* R207 */ + 0x0000, /* R208 */ + 0x0000, /* R209 */ + 0x0000, /* R210 */ + 0x0000, /* R211 */ + 0x0000, /* R212 */ + 0x0000, /* R213 */ + 0x0000, /* R214 */ + 0x0000, /* R215 */ + 0x0000, /* R216 */ + 0x0000, /* R217 */ + 0x0000, /* R218 */ + 0x0000, /* R219 */ + 0x0000, /* R220 */ + 0x0000, /* R221 */ + 0x0000, /* R222 */ + 0x0000, /* R223 */ + 0x0000, /* R224 */ + 0x0000, /* R225 */ + 0x0000, /* R226 */ + 0x0000, /* R227 */ + 0x0000, /* R228 */ + 0x0000, /* R229 */ + 0x0000, /* R230 */ + 0x0000, /* R231 */ + 0x0000, /* R232 */ + 0x0000, /* R233 */ + 0x0000, /* R234 */ + 0x0000, /* R235 */ + 0x0000, /* R236 */ + 0x0000, /* R237 */ + 0x0000, /* R238 */ + 0x0000, /* R239 */ + 0x0000, /* R240 */ + 0x0000, /* R241 */ + 0x0000, /* R242 */ + 0x0000, /* R243 */ + 0x0000, /* R244 */ + 0x0000, /* R245 */ + 0x0000, /* R246 */ + 0x0000, /* R247 - FLL NCO Test 0 */ + 0x0019, /* R248 - FLL NCO Test 1 */ +}; + +static struct { + int readable; + int writable; + int vol; +} wm8904_access[] = { + { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */ + { 0x0000, 0x0000, 0 }, /* R1 - Revision */ + { 0x0000, 0x0000, 0 }, /* R2 */ + { 0x0000, 0x0000, 0 }, /* R3 */ + { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */ + { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */ + { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */ + { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */ + { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */ + { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */ + { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */ + { 0x0000, 0x0000, 0 }, /* R11 */ + { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */ + { 0x0000, 0x0000, 0 }, /* R13 */ + { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */ + { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */ + { 0x0000, 0x0000, 0 }, /* R16 */ + { 0x0000, 0x0000, 0 }, /* R17 */ + { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */ + { 0x0000, 0x0000, 0 }, /* R19 */ + { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */ + { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */ + { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */ + { 0x0000, 0x0000, 0 }, /* R23 */ + { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */ + { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */ + { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */ + { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */ + { 0x0000, 0x0000, 0 }, /* R28 */ + { 0x0000, 0x0000, 0 }, /* R29 */ + { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */ + { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */ + { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */ + { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */ + { 0x0000, 0x0000, 0 }, /* R34 */ + { 0x0000, 0x0000, 0 }, /* R35 */ + { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */ + { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */ + { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */ + { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */ + { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */ + { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */ + { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */ + { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */ + { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */ + { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */ + { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */ + { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */ + { 0x0000, 0x0000, 0 }, /* R48 */ + { 0x0000, 0x0000, 0 }, /* R49 */ + { 0x0000, 0x0000, 0 }, /* R50 */ + { 0x0000, 0x0000, 0 }, /* R51 */ + { 0x0000, 0x0000, 0 }, /* R52 */ + { 0x0000, 0x0000, 0 }, /* R53 */ + { 0x0000, 0x0000, 0 }, /* R54 */ + { 0x0000, 0x0000, 0 }, /* R55 */ + { 0x0000, 0x0000, 0 }, /* R56 */ + { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */ + { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */ + { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */ + { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */ + { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */ + { 0x0000, 0x0000, 0 }, /* R62 */ + { 0x0000, 0x0000, 0 }, /* R63 */ + { 0x0000, 0x0000, 0 }, /* R64 */ + { 0x0000, 0x0000, 0 }, /* R65 */ + { 0x0000, 0x0000, 0 }, /* R66 */ + { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */ + { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */ + { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */ + { 0x0000, 0x0000, 0 }, /* R70 */ + { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */ + { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */ + { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */ + { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */ + { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */ + { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */ + { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */ + { 0x0000, 0x0000, 0 }, /* R78 */ + { 0x0000, 0x0000, 0 }, /* R79 */ + { 0x0000, 0x0000, 0 }, /* R80 */ + { 0x0000, 0x0000, 0 }, /* R81 */ + { 0x0000, 0x0000, 0 }, /* R82 */ + { 0x0000, 0x0000, 0 }, /* R83 */ + { 0x0000, 0x0000, 0 }, /* R84 */ + { 0x0000, 0x0000, 0 }, /* R85 */ + { 0x0000, 0x0000, 0 }, /* R86 */ + { 0x0000, 0x0000, 0 }, /* R87 */ + { 0x0000, 0x0000, 0 }, /* R88 */ + { 0x0000, 0x0000, 0 }, /* R89 */ + { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */ + { 0x0000, 0x0000, 0 }, /* R91 */ + { 0x0000, 0x0000, 0 }, /* R92 */ + { 0x0000, 0x0000, 0 }, /* R93 */ + { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */ + { 0x0000, 0x0000, 0 }, /* R95 */ + { 0x0000, 0x0000, 0 }, /* R96 */ + { 0x0000, 0x0000, 0 }, /* R97 */ + { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */ + { 0x0000, 0x0000, 0 }, /* R99 */ + { 0x0000, 0x0000, 0 }, /* R100 */ + { 0x0000, 0x0000, 0 }, /* R101 */ + { 0x0000, 0x0000, 0 }, /* R102 */ + { 0x0000, 0x0000, 0 }, /* R103 */ + { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */ + { 0x0000, 0x0000, 0 }, /* R105 */ + { 0x0000, 0x0000, 0 }, /* R106 */ + { 0x0000, 0x0000, 0 }, /* R107 */ + { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */ + { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */ + { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */ + { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */ + { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */ + { 0x0000, 0x0000, 0 }, /* R113 */ + { 0x0000, 0x0000, 0 }, /* R114 */ + { 0x0000, 0x0000, 0 }, /* R115 */ + { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */ + { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */ + { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */ + { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */ + { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */ + { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */ + { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */ + { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */ + { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */ + { 0x0000, 0x0000, 0 }, /* R125 */ + { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */ + { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */ + { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */ + { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */ + { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */ + { 0x0000, 0x0000, 0 }, /* R131 */ + { 0x0000, 0x0000, 0 }, /* R132 */ + { 0x0000, 0x0000, 0 }, /* R133 */ + { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */ + { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */ + { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */ + { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */ + { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */ + { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */ + { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */ + { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */ + { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */ + { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */ + { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */ + { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */ + { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */ + { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */ + { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */ + { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */ + { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */ + { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */ + { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */ + { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */ + { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */ + { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */ + { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */ + { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */ + { 0x0000, 0x0000, 0 }, /* R158 */ + { 0x0000, 0x0000, 0 }, /* R159 */ + { 0x0000, 0x0000, 0 }, /* R160 */ + { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */ + { 0x0000, 0x0000, 0 }, /* R162 */ + { 0x0000, 0x0000, 0 }, /* R163 */ + { 0x0000, 0x0000, 0 }, /* R164 */ + { 0x0000, 0x0000, 0 }, /* R165 */ + { 0x0000, 0x0000, 0 }, /* R166 */ + { 0x0000, 0x0000, 0 }, /* R167 */ + { 0x0000, 0x0000, 0 }, /* R168 */ + { 0x0000, 0x0000, 0 }, /* R169 */ + { 0x0000, 0x0000, 0 }, /* R170 */ + { 0x0000, 0x0000, 0 }, /* R171 */ + { 0x0000, 0x0000, 0 }, /* R172 */ + { 0x0000, 0x0000, 0 }, /* R173 */ + { 0x0000, 0x0000, 0 }, /* R174 */ + { 0x0000, 0x0000, 0 }, /* R175 */ + { 0x0000, 0x0000, 0 }, /* R176 */ + { 0x0000, 0x0000, 0 }, /* R177 */ + { 0x0000, 0x0000, 0 }, /* R178 */ + { 0x0000, 0x0000, 0 }, /* R179 */ + { 0x0000, 0x0000, 0 }, /* R180 */ + { 0x0000, 0x0000, 0 }, /* R181 */ + { 0x0000, 0x0000, 0 }, /* R182 */ + { 0x0000, 0x0000, 0 }, /* R183 */ + { 0x0000, 0x0000, 0 }, /* R184 */ + { 0x0000, 0x0000, 0 }, /* R185 */ + { 0x0000, 0x0000, 0 }, /* R186 */ + { 0x0000, 0x0000, 0 }, /* R187 */ + { 0x0000, 0x0000, 0 }, /* R188 */ + { 0x0000, 0x0000, 0 }, /* R189 */ + { 0x0000, 0x0000, 0 }, /* R190 */ + { 0x0000, 0x0000, 0 }, /* R191 */ + { 0x0000, 0x0000, 0 }, /* R192 */ + { 0x0000, 0x0000, 0 }, /* R193 */ + { 0x0000, 0x0000, 0 }, /* R194 */ + { 0x0000, 0x0000, 0 }, /* R195 */ + { 0x0000, 0x0000, 0 }, /* R196 */ + { 0x0000, 0x0000, 0 }, /* R197 */ + { 0x0000, 0x0000, 0 }, /* R198 */ + { 0x0000, 0x0000, 0 }, /* R199 */ + { 0x0000, 0x0000, 0 }, /* R200 */ + { 0x0000, 0x0000, 0 }, /* R201 */ + { 0x0000, 0x0000, 0 }, /* R202 */ + { 0x0000, 0x0000, 0 }, /* R203 */ + { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */ + { 0x0000, 0x0000, 0 }, /* R205 */ + { 0x0000, 0x0000, 0 }, /* R206 */ + { 0x0000, 0x0000, 0 }, /* R207 */ + { 0x0000, 0x0000, 0 }, /* R208 */ + { 0x0000, 0x0000, 0 }, /* R209 */ + { 0x0000, 0x0000, 0 }, /* R210 */ + { 0x0000, 0x0000, 0 }, /* R211 */ + { 0x0000, 0x0000, 0 }, /* R212 */ + { 0x0000, 0x0000, 0 }, /* R213 */ + { 0x0000, 0x0000, 0 }, /* R214 */ + { 0x0000, 0x0000, 0 }, /* R215 */ + { 0x0000, 0x0000, 0 }, /* R216 */ + { 0x0000, 0x0000, 0 }, /* R217 */ + { 0x0000, 0x0000, 0 }, /* R218 */ + { 0x0000, 0x0000, 0 }, /* R219 */ + { 0x0000, 0x0000, 0 }, /* R220 */ + { 0x0000, 0x0000, 0 }, /* R221 */ + { 0x0000, 0x0000, 0 }, /* R222 */ + { 0x0000, 0x0000, 0 }, /* R223 */ + { 0x0000, 0x0000, 0 }, /* R224 */ + { 0x0000, 0x0000, 0 }, /* R225 */ + { 0x0000, 0x0000, 0 }, /* R226 */ + { 0x0000, 0x0000, 0 }, /* R227 */ + { 0x0000, 0x0000, 0 }, /* R228 */ + { 0x0000, 0x0000, 0 }, /* R229 */ + { 0x0000, 0x0000, 0 }, /* R230 */ + { 0x0000, 0x0000, 0 }, /* R231 */ + { 0x0000, 0x0000, 0 }, /* R232 */ + { 0x0000, 0x0000, 0 }, /* R233 */ + { 0x0000, 0x0000, 0 }, /* R234 */ + { 0x0000, 0x0000, 0 }, /* R235 */ + { 0x0000, 0x0000, 0 }, /* R236 */ + { 0x0000, 0x0000, 0 }, /* R237 */ + { 0x0000, 0x0000, 0 }, /* R238 */ + { 0x0000, 0x0000, 0 }, /* R239 */ + { 0x0000, 0x0000, 0 }, /* R240 */ + { 0x0000, 0x0000, 0 }, /* R241 */ + { 0x0000, 0x0000, 0 }, /* R242 */ + { 0x0000, 0x0000, 0 }, /* R243 */ + { 0x0000, 0x0000, 0 }, /* R244 */ + { 0x0000, 0x0000, 0 }, /* R245 */ + { 0x0000, 0x0000, 0 }, /* R246 */ + { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */ + { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ +}; + +static int wm8904_volatile_register(unsigned int reg) +{ + return wm8904_access[reg].vol; +} + +static int wm8904_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0); +} + +static int wm8904_configure_clocking(struct snd_soc_codec *codec) +{ + struct wm8904_priv *wm8904 = codec->private_data; + unsigned int clock0, clock2, rate; + + /* Gate the clock while we're updating to avoid misclocking */ + clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2); + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2, + WM8904_SYSCLK_SRC, 0); + + /* This should be done on init() for bypass paths */ + switch (wm8904->sysclk_src) { + case WM8904_CLK_MCLK: + dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate); + + clock2 &= ~WM8904_SYSCLK_SRC; + rate = wm8904->mclk_rate; + + /* Ensure the FLL is stopped */ + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0); + break; + + case WM8904_CLK_FLL: + dev_dbg(codec->dev, "Using %dHz FLL clock\n", + wm8904->fll_fout); + + clock2 |= WM8904_SYSCLK_SRC; + rate = wm8904->fll_fout; + break; + + default: + dev_err(codec->dev, "System clock not configured\n"); + return -EINVAL; + } + + /* SYSCLK shouldn't be over 13.5MHz */ + if (rate > 13500000) { + clock0 = WM8904_MCLK_DIV; + wm8904->sysclk_rate = rate / 2; + } else { + clock0 = 0; + wm8904->sysclk_rate = rate; + } + + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV, + clock0); + + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2, + WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2); + + dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate); + + return 0; +} + +static void wm8904_set_drc(struct snd_soc_codec *codec) +{ + struct wm8904_priv *wm8904 = codec->private_data; + struct wm8904_pdata *pdata = wm8904->pdata; + int save, i; + + /* Save any enables; the configuration should clear them. */ + save = snd_soc_read(codec, WM8904_DRC_0); + + for (i = 0; i < WM8904_DRC_REGS; i++) + snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff, + pdata->drc_cfgs[wm8904->drc_cfg].regs[i]); + + /* Reenable the DRC */ + snd_soc_update_bits(codec, WM8904_DRC_0, + WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save); +} + +static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8904_priv *wm8904 = codec->private_data; + struct wm8904_pdata *pdata = wm8904->pdata; + int value = ucontrol->value.integer.value[0]; + + if (value >= pdata->num_drc_cfgs) + return -EINVAL; + + wm8904->drc_cfg = value; + + wm8904_set_drc(codec); + + return 0; +} + +static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8904_priv *wm8904 = codec->private_data; + + ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; + + return 0; +} + +static void wm8904_set_retune_mobile(struct snd_soc_codec *codec) +{ + struct wm8904_priv *wm8904 = codec->private_data; + struct wm8904_pdata *pdata = wm8904->pdata; + int best, best_val, save, i, cfg; + + if (!pdata || !wm8904->num_retune_mobile_texts) + return; + + /* Find the version of the currently selected configuration + * with the nearest sample rate. */ + cfg = wm8904->retune_mobile_cfg; + best = 0; + best_val = INT_MAX; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8904->retune_mobile_texts[cfg]) == 0 && + abs(pdata->retune_mobile_cfgs[i].rate + - wm8904->fs) < best_val) { + best = i; + best_val = abs(pdata->retune_mobile_cfgs[i].rate + - wm8904->fs); + } + } + + dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n", + pdata->retune_mobile_cfgs[best].name, + pdata->retune_mobile_cfgs[best].rate, + wm8904->fs); + + /* The EQ will be disabled while reconfiguring it, remember the + * current configuration. + */ + save = snd_soc_read(codec, WM8904_EQ1); + + for (i = 0; i < WM8904_EQ_REGS; i++) + snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff, + pdata->retune_mobile_cfgs[best].regs[i]); + + snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save); +} + +static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8904_priv *wm8904 = codec->private_data; + struct wm8904_pdata *pdata = wm8904->pdata; + int value = ucontrol->value.integer.value[0]; + + if (value >= pdata->num_retune_mobile_cfgs) + return -EINVAL; + + wm8904->retune_mobile_cfg = value; + + wm8904_set_retune_mobile(codec); + + return 0; +} + +static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8904_priv *wm8904 = codec->private_data; + + ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; + + return 0; +} + +static int deemph_settings[] = { 0, 32000, 44100, 48000 }; + +static int wm8904_set_deemph(struct snd_soc_codec *codec) +{ + struct wm8904_priv *wm8904 = codec->private_data; + int val, i, best; + + /* If we're using deemphasis select the nearest available sample + * rate. + */ + if (wm8904->deemph) { + best = 1; + for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) { + if (abs(deemph_settings[i] - wm8904->fs) < + abs(deemph_settings[best] - wm8904->fs)) + best = i; + } + + val = best << WM8904_DEEMPH_SHIFT; + } else { + val = 0; + } + + dev_dbg(codec->dev, "Set deemphasis %d\n", val); + + return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, + WM8904_DEEMPH_MASK, val); +} + +static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8904_priv *wm8904 = codec->private_data; + + return wm8904->deemph; +} + +static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8904_priv *wm8904 = codec->private_data; + int deemph = ucontrol->value.enumerated.item[0]; + + if (deemph > 1) + return -EINVAL; + + wm8904->deemph = deemph; + + return wm8904_set_deemph(codec); +} + +static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0); +static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); +static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0); +static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); + +static const char *input_mode_text[] = { + "Single-Ended", "Differential Line", "Differential Mic" +}; + +static const struct soc_enum lin_mode = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text); + +static const struct soc_enum rin_mode = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text); + +static const char *hpf_mode_text[] = { + "Hi-fi", "Voice 1", "Voice 2", "Voice 3" +}; + +static const struct soc_enum hpf_mode = + SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); + +static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = { +SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, + WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), + +SOC_ENUM("Left Caputure Mode", lin_mode), +SOC_ENUM("Right Capture Mode", rin_mode), + +/* No TLV since it depends on mode */ +SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, + WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), +SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, + WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0), + +SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), +SOC_ENUM("High Pass Filter Mode", hpf_mode), + +SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0), +}; + +static const char *drc_path_text[] = { + "ADC", "DAC" +}; + +static const struct soc_enum drc_path = + SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text); + +static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = { +SOC_SINGLE_TLV("Digital Playback Boost Volume", + WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv), +SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT, + WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), + +SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT, + WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv), +SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT, + WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1), +SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT, + WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0), + +SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT, + WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv), +SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT, + WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1), +SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT, + WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0), + +SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0), +SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0), +SOC_ENUM("DRC Path", drc_path), +SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0), +SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, + wm8904_get_deemph, wm8904_put_deemph), +}; + +static const struct snd_kcontrol_new wm8904_snd_controls[] = { +SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0, + sidetone_tlv), +}; + +static const struct snd_kcontrol_new wm8904_eq_controls[] = { +SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv), +}; + +static int cp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + BUG_ON(event != SND_SOC_DAPM_POST_PMU); + + /* Maximum startup time */ + udelay(500); + + return 0; +} + +static int sysclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8904_priv *wm8904 = codec->private_data; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* If we're using the FLL then we only start it when + * required; we assume that the configuration has been + * done previously and all we need to do is kick it + * off. + */ + switch (wm8904->sysclk_src) { + case WM8904_CLK_FLL: + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_OSC_ENA, + WM8904_FLL_OSC_ENA); + + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_ENA, + WM8904_FLL_ENA); + break; + + default: + break; + } + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0); + break; + } + + return 0; +} + +static int out_pga_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8904_priv *wm8904 = codec->private_data; + int reg, val; + int dcs_mask; + int dcs_l, dcs_r; + int dcs_l_reg, dcs_r_reg; + int timeout; + + /* This code is shared between HP and LINEOUT; we do all our + * power management in stereo pairs to avoid latency issues so + * we reuse shift to identify which rather than strcmp() the + * name. */ + reg = w->shift; + + switch (reg) { + case WM8904_ANALOGUE_HP_0: + dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1; + dcs_r_reg = WM8904_DC_SERVO_8; + dcs_l_reg = WM8904_DC_SERVO_9; + dcs_l = 0; + dcs_r = 1; + break; + case WM8904_ANALOGUE_LINEOUT_0: + dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3; + dcs_r_reg = WM8904_DC_SERVO_6; + dcs_l_reg = WM8904_DC_SERVO_7; + dcs_l = 2; + dcs_r = 3; + break; + default: + BUG(); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Power on the amplifier */ + snd_soc_update_bits(codec, reg, + WM8904_HPL_ENA | WM8904_HPR_ENA, + WM8904_HPL_ENA | WM8904_HPR_ENA); + + /* Enable the first stage */ + snd_soc_update_bits(codec, reg, + WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY, + WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY); + + /* Power up the DC servo */ + snd_soc_update_bits(codec, WM8904_DC_SERVO_0, + dcs_mask, dcs_mask); + + /* Either calibrate the DC servo or restore cached state + * if we have that. + */ + if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) { + dev_dbg(codec->dev, "Restoring DC servo state\n"); + + snd_soc_write(codec, dcs_l_reg, + wm8904->dcs_state[dcs_l]); + snd_soc_write(codec, dcs_r_reg, + wm8904->dcs_state[dcs_r]); + + snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask); + + timeout = 20; + } else { + dev_dbg(codec->dev, "Calibrating DC servo\n"); + + snd_soc_write(codec, WM8904_DC_SERVO_1, + dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT); + + timeout = 500; + } + + /* Wait for DC servo to complete */ + dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT; + do { + val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0); + if ((val & dcs_mask) == dcs_mask) + break; + + msleep(1); + } while (--timeout); + + if ((val & dcs_mask) != dcs_mask) + dev_warn(codec->dev, "DC servo timed out\n"); + else + dev_dbg(codec->dev, "DC servo ready\n"); + + /* Enable the output stage */ + snd_soc_update_bits(codec, reg, + WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP, + WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP); + + /* Unshort the output itself */ + snd_soc_update_bits(codec, reg, + WM8904_HPL_RMV_SHORT | + WM8904_HPR_RMV_SHORT, + WM8904_HPL_RMV_SHORT | + WM8904_HPR_RMV_SHORT); + + break; + + case SND_SOC_DAPM_PRE_PMD: + /* Short the output */ + snd_soc_update_bits(codec, reg, + WM8904_HPL_RMV_SHORT | + WM8904_HPR_RMV_SHORT, 0); + + /* Cache the DC servo configuration; this will be + * invalidated if we change the configuration. */ + wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg); + wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg); + + snd_soc_update_bits(codec, WM8904_DC_SERVO_0, + dcs_mask, 0); + + /* Disable the amplifier input and output stages */ + snd_soc_update_bits(codec, reg, + WM8904_HPL_ENA | WM8904_HPR_ENA | + WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY | + WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP, + 0); + break; + } + + return 0; +} + +static const char *lin_text[] = { + "IN1L", "IN2L", "IN3L" +}; + +static const struct soc_enum lin_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text); + +static const struct snd_kcontrol_new lin_mux = + SOC_DAPM_ENUM("Left Capture Mux", lin_enum); + +static const struct soc_enum lin_inv_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text); + +static const struct snd_kcontrol_new lin_inv_mux = + SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum); + +static const char *rin_text[] = { + "IN1R", "IN2R", "IN3R" +}; + +static const struct soc_enum rin_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text); + +static const struct snd_kcontrol_new rin_mux = + SOC_DAPM_ENUM("Right Capture Mux", rin_enum); + +static const struct soc_enum rin_inv_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text); + +static const struct snd_kcontrol_new rin_inv_mux = + SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum); + +static const char *aif_text[] = { + "Left", "Right" +}; + +static const struct soc_enum aifoutl_enum = + SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text); + +static const struct snd_kcontrol_new aifoutl_mux = + SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum); + +static const struct soc_enum aifoutr_enum = + SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text); + +static const struct snd_kcontrol_new aifoutr_mux = + SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum); + +static const struct soc_enum aifinl_enum = + SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text); + +static const struct snd_kcontrol_new aifinl_mux = + SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum); + +static const struct soc_enum aifinr_enum = + SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text); + +static const struct snd_kcontrol_new aifinr_mux = + SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum); + +static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = { +SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = { +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"), + +SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0), + +SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux), +SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0, + &lin_inv_mux), +SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux), +SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0, + &rin_inv_mux), + +SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0, + NULL, 0), +SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0, + NULL, 0), + +SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0), +SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0), + +SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux), +SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux), + +SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = { +SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0), + +SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux), +SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux), + +SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0), +SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0), + +SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event, + SND_SOC_DAPM_POST_PMU), + +SND_SOC_DAPM_PGA("HPL PGA", WM8904_POWER_MANAGEMENT_2, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA("HPR PGA", WM8904_POWER_MANAGEMENT_2, 0, 0, NULL, 0), + +SND_SOC_DAPM_PGA("LINEL PGA", WM8904_POWER_MANAGEMENT_3, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA("LINER PGA", WM8904_POWER_MANAGEMENT_3, 0, 0, NULL, 0), + +SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0, + 0, NULL, 0, out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0, + 0, NULL, 0, out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_OUTPUT("HPOUTL"), +SND_SOC_DAPM_OUTPUT("HPOUTR"), +SND_SOC_DAPM_OUTPUT("LINEOUTL"), +SND_SOC_DAPM_OUTPUT("LINEOUTR"), +}; + +static const char *out_mux_text[] = { + "DAC", "Bypass" +}; + +static const struct soc_enum hpl_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text); + +static const struct snd_kcontrol_new hpl_mux = + SOC_DAPM_ENUM("HPL Mux", hpl_enum); + +static const struct soc_enum hpr_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text); + +static const struct snd_kcontrol_new hpr_mux = + SOC_DAPM_ENUM("HPR Mux", hpr_enum); + +static const struct soc_enum linel_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text); + +static const struct snd_kcontrol_new linel_mux = + SOC_DAPM_ENUM("LINEL Mux", linel_enum); + +static const struct soc_enum liner_enum = + SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text); + +static const struct snd_kcontrol_new liner_mux = + SOC_DAPM_ENUM("LINEL Mux", liner_enum); + +static const char *sidetone_text[] = { + "None", "Left", "Right" +}; + +static const struct soc_enum dacl_sidetone_enum = + SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text); + +static const struct snd_kcontrol_new dacl_sidetone_mux = + SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum); + +static const struct soc_enum dacr_sidetone_enum = + SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text); + +static const struct snd_kcontrol_new dacr_sidetone_mux = + SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum); + +static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = { +SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0), +SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0), + +SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux), +SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux), + +SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), +SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), +SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux), +SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux), +}; + +static const struct snd_soc_dapm_route core_intercon[] = { + { "CLK_DSP", NULL, "SYSCLK" }, + { "TOCLK", NULL, "SYSCLK" }, +}; + +static const struct snd_soc_dapm_route adc_intercon[] = { + { "Left Capture Mux", "IN1L", "IN1L" }, + { "Left Capture Mux", "IN2L", "IN2L" }, + { "Left Capture Mux", "IN3L", "IN3L" }, + + { "Left Capture Inverting Mux", "IN1L", "IN1L" }, + { "Left Capture Inverting Mux", "IN2L", "IN2L" }, + { "Left Capture Inverting Mux", "IN3L", "IN3L" }, + + { "Right Capture Mux", "IN1R", "IN1R" }, + { "Right Capture Mux", "IN2R", "IN2R" }, + { "Right Capture Mux", "IN3R", "IN3R" }, + + { "Right Capture Inverting Mux", "IN1R", "IN1R" }, + { "Right Capture Inverting Mux", "IN2R", "IN2R" }, + { "Right Capture Inverting Mux", "IN3R", "IN3R" }, + + { "Left Capture PGA", NULL, "Left Capture Mux" }, + { "Left Capture PGA", NULL, "Left Capture Inverting Mux" }, + + { "Right Capture PGA", NULL, "Right Capture Mux" }, + { "Right Capture PGA", NULL, "Right Capture Inverting Mux" }, + + { "AIFOUTL", "Left", "ADCL" }, + { "AIFOUTL", "Right", "ADCR" }, + { "AIFOUTR", "Left", "ADCL" }, + { "AIFOUTR", "Right", "ADCR" }, + + { "ADCL", NULL, "CLK_DSP" }, + { "ADCL", NULL, "Left Capture PGA" }, + + { "ADCR", NULL, "CLK_DSP" }, + { "ADCR", NULL, "Right Capture PGA" }, +}; + +static const struct snd_soc_dapm_route dac_intercon[] = { + { "DACL", "Right", "AIFINR" }, + { "DACL", "Left", "AIFINL" }, + { "DACL", NULL, "CLK_DSP" }, + + { "DACR", "Right", "AIFINR" }, + { "DACR", "Left", "AIFINL" }, + { "DACR", NULL, "CLK_DSP" }, + + { "Charge pump", NULL, "SYSCLK" }, + + { "Headphone Output", NULL, "HPL PGA" }, + { "Headphone Output", NULL, "HPR PGA" }, + { "Headphone Output", NULL, "Charge pump" }, + { "Headphone Output", NULL, "TOCLK" }, + + { "Line Output", NULL, "LINEL PGA" }, + { "Line Output", NULL, "LINER PGA" }, + { "Line Output", NULL, "Charge pump" }, + { "Line Output", NULL, "TOCLK" }, + + { "HPOUTL", NULL, "Headphone Output" }, + { "HPOUTR", NULL, "Headphone Output" }, + + { "LINEOUTL", NULL, "Line Output" }, + { "LINEOUTR", NULL, "Line Output" }, +}; + +static const struct snd_soc_dapm_route wm8904_intercon[] = { + { "Left Sidetone", "Left", "ADCL" }, + { "Left Sidetone", "Right", "ADCR" }, + { "DACL", NULL, "Left Sidetone" }, + + { "Right Sidetone", "Left", "ADCL" }, + { "Right Sidetone", "Right", "ADCR" }, + { "DACR", NULL, "Right Sidetone" }, + + { "Left Bypass", NULL, "Class G" }, + { "Left Bypass", NULL, "Left Capture PGA" }, + + { "Right Bypass", NULL, "Class G" }, + { "Right Bypass", NULL, "Right Capture PGA" }, + + { "HPL Mux", "DAC", "DACL" }, + { "HPL Mux", "Bypass", "Left Bypass" }, + + { "HPR Mux", "DAC", "DACR" }, + { "HPR Mux", "Bypass", "Right Bypass" }, + + { "LINEL Mux", "DAC", "DACL" }, + { "LINEL Mux", "Bypass", "Left Bypass" }, + + { "LINER Mux", "DAC", "DACR" }, + { "LINER Mux", "Bypass", "Right Bypass" }, + + { "HPL PGA", NULL, "HPL Mux" }, + { "HPR PGA", NULL, "HPR Mux" }, + + { "LINEL PGA", NULL, "LINEL Mux" }, + { "LINER PGA", NULL, "LINER Mux" }, +}; + +static int wm8904_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_add_controls(codec, wm8904_adc_snd_controls, + ARRAY_SIZE(wm8904_adc_snd_controls)); + snd_soc_add_controls(codec, wm8904_dac_snd_controls, + ARRAY_SIZE(wm8904_dac_snd_controls)); + snd_soc_add_controls(codec, wm8904_snd_controls, + ARRAY_SIZE(wm8904_snd_controls)); + + snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, + ARRAY_SIZE(wm8904_core_dapm_widgets)); + snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, + ARRAY_SIZE(wm8904_adc_dapm_widgets)); + snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, + ARRAY_SIZE(wm8904_dac_dapm_widgets)); + snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, + ARRAY_SIZE(wm8904_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, core_intercon, + ARRAY_SIZE(core_intercon)); + snd_soc_dapm_add_routes(codec, adc_intercon, ARRAY_SIZE(adc_intercon)); + snd_soc_dapm_add_routes(codec, dac_intercon, ARRAY_SIZE(dac_intercon)); + snd_soc_dapm_add_routes(codec, wm8904_intercon, + ARRAY_SIZE(wm8904_intercon)); + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +static struct { + int ratio; + unsigned int clk_sys_rate; +} clk_sys_rates[] = { + { 64, 0 }, + { 128, 1 }, + { 192, 2 }, + { 256, 3 }, + { 384, 4 }, + { 512, 5 }, + { 786, 6 }, + { 1024, 7 }, + { 1408, 8 }, + { 1536, 9 }, +}; + +static struct { + int rate; + int sample_rate; +} sample_rates[] = { + { 8000, 0 }, + { 11025, 1 }, + { 12000, 1 }, + { 16000, 2 }, + { 22050, 3 }, + { 24000, 3 }, + { 32000, 4 }, + { 44100, 5 }, + { 48000, 5 }, +}; + +static struct { + int div; /* *10 due to .5s */ + int bclk_div; +} bclk_divs[] = { + { 10, 0 }, + { 15, 1 }, + { 20, 2 }, + { 30, 3 }, + { 40, 4 }, + { 50, 5 }, + { 55, 6 }, + { 60, 7 }, + { 80, 8 }, + { 100, 9 }, + { 110, 10 }, + { 120, 11 }, + { 160, 12 }, + { 200, 13 }, + { 220, 14 }, + { 240, 16 }, + { 200, 17 }, + { 320, 18 }, + { 440, 19 }, + { 480, 20 }, +}; + + +static int wm8904_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8904_priv *wm8904 = codec->private_data; + int ret, i, best, best_val, cur_val; + unsigned int aif1 = 0; + unsigned int aif2 = 0; + unsigned int aif3 = 0; + unsigned int clock1 = 0; + unsigned int dac_digital1 = 0; + + /* What BCLK do we need? */ + wm8904->fs = params_rate(params); + if (wm8904->tdm_slots) { + dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n", + wm8904->tdm_slots, wm8904->tdm_width); + wm8904->bclk = snd_soc_calc_bclk(wm8904->fs, + wm8904->tdm_width, 2, + wm8904->tdm_slots); + } else { + wm8904->bclk = snd_soc_params_to_bclk(params); + } + + dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk); + + ret = wm8904_configure_clocking(codec); + if (ret != 0) + return ret; + + /* Select nearest CLK_SYS_RATE */ + best = 0; + best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio) + - wm8904->fs); + for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { + cur_val = abs((wm8904->sysclk_rate / + clk_sys_rates[i].ratio) - wm8904->fs);; + if (cur_val < best_val) { + best = i; + best_val = cur_val; + } + } + dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n", + clk_sys_rates[best].ratio); + clock1 |= (clk_sys_rates[best].clk_sys_rate + << WM8904_CLK_SYS_RATE_SHIFT); + + /* SAMPLE_RATE */ + best = 0; + best_val = abs(wm8904->fs - sample_rates[0].rate); + for (i = 1; i < ARRAY_SIZE(sample_rates); i++) { + /* Closest match */ + cur_val = abs(wm8904->fs - sample_rates[i].rate); + if (cur_val < best_val) { + best = i; + best_val = cur_val; + } + } + dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n", + sample_rates[best].rate); + clock1 |= (sample_rates[best].sample_rate + << WM8904_SAMPLE_RATE_SHIFT); + + /* Enable sloping stopband filter for low sample rates */ + if (wm8904->fs <= 24000) + dac_digital1 |= WM8904_DAC_SB_FILT; + + /* BCLK_DIV */ + best = 0; + best_val = INT_MAX; + for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { + cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div) + - wm8904->bclk; + if (cur_val < 0) /* Table is sorted */ + break; + if (cur_val < best_val) { + best = i; + best_val = cur_val; + } + } + wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div; + dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n", + bclk_divs[best].div, wm8904->bclk); + aif2 |= bclk_divs[best].bclk_div; + + /* LRCLK is a simple fraction of BCLK */ + dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs); + aif3 |= wm8904->bclk / wm8904->fs; + + /* Apply the settings */ + snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, + WM8904_DAC_SB_FILT, dac_digital1); + snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1, + WM8904_AIF_WL_MASK, aif1); + snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2, + WM8904_BCLK_DIV_MASK, aif2); + snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3, + WM8904_LRCLK_RATE_MASK, aif3); + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1, + WM8904_SAMPLE_RATE_MASK | + WM8904_CLK_SYS_RATE_MASK, clock1); + + /* Update filters for the new settings */ + wm8904_set_retune_mobile(codec); + wm8904_set_deemph(codec); + + return 0; +} + + +static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8904_priv *priv = codec->private_data; + + switch (clk_id) { + case WM8904_CLK_MCLK: + priv->sysclk_src = clk_id; + priv->mclk_rate = freq; + break; + + case WM8904_CLK_FLL: + priv->sysclk_src = clk_id; + break; + + default: + return -EINVAL; + } + + dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq); + + wm8904_configure_clocking(codec); + + return 0; +} + +static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + unsigned int aif1 = 0; + unsigned int aif3 = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBS_CFM: + aif3 |= WM8904_LRCLK_DIR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + aif1 |= WM8904_BCLK_DIR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + aif1 |= WM8904_BCLK_DIR; + aif3 |= WM8904_LRCLK_DIR; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: + aif1 |= WM8904_AIF_LRCLK_INV; + case SND_SOC_DAIFMT_DSP_A: + aif1 |= 0x3; + break; + case SND_SOC_DAIFMT_I2S: + aif1 |= 0x2; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + aif1 |= 0x1; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + aif1 |= WM8904_AIF_BCLK_INV; + break; + default: + return -EINVAL; + } + break; + + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + aif1 |= WM8904_AIF_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + aif1 |= WM8904_AIF_LRCLK_INV; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1, + WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV | + WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1); + snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3, + WM8904_LRCLK_DIR, aif3); + + return 0; +} + + +static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, int slot_width) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8904_priv *wm8904 = codec->private_data; + int aif1 = 0; + + /* Don't need to validate anything if we're turning off TDM */ + if (slots == 0) + goto out; + + /* Note that we allow configurations we can't handle ourselves - + * for example, we can generate clocks for slots 2 and up even if + * we can't use those slots ourselves. + */ + aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM; + + switch (rx_mask) { + case 3: + break; + case 0xc: + aif1 |= WM8904_AIFADC_TDM_CHAN; + break; + default: + return -EINVAL; + } + + + switch (tx_mask) { + case 3: + break; + case 0xc: + aif1 |= WM8904_AIFDAC_TDM_CHAN; + break; + default: + return -EINVAL; + } + +out: + wm8904->tdm_width = slot_width; + wm8904->tdm_slots = slots / 2; + + snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1, + WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN | + WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1); + + return 0; +} + +struct _fll_div { + u16 fll_fratio; + u16 fll_outdiv; + u16 fll_clk_ref_div; + u16 n; + u16 k; +}; + +/* The size in bits of the FLL divide multiplied by 10 + * to allow rounding later */ +#define FIXED_FLL_SIZE ((1 << 16) * 10) + +static struct { + unsigned int min; + unsigned int max; + u16 fll_fratio; + int ratio; +} fll_fratios[] = { + { 0, 64000, 4, 16 }, + { 64000, 128000, 3, 8 }, + { 128000, 256000, 2, 4 }, + { 256000, 1000000, 1, 2 }, + { 1000000, 13500000, 0, 1 }, +}; + +static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, + unsigned int Fout) +{ + u64 Kpart; + unsigned int K, Ndiv, Nmod, target; + unsigned int div; + int i; + + /* Fref must be <=13.5MHz */ + div = 1; + fll_div->fll_clk_ref_div = 0; + while ((Fref / div) > 13500000) { + div *= 2; + fll_div->fll_clk_ref_div++; + + if (div > 8) { + pr_err("Can't scale %dMHz input down to <=13.5MHz\n", + Fref); + return -EINVAL; + } + } + + pr_debug("Fref=%u Fout=%u\n", Fref, Fout); + + /* Apply the division for our remaining calculations */ + Fref /= div; + + /* Fvco should be 90-100MHz; don't check the upper bound */ + div = 4; + while (Fout * div < 90000000) { + div++; + if (div > 64) { + pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", + Fout); + return -EINVAL; + } + } + target = Fout * div; + fll_div->fll_outdiv = div - 1; + + pr_debug("Fvco=%dHz\n", target); + + /* Find an appropraite FLL_FRATIO and factor it out of the target */ + for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { + if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { + fll_div->fll_fratio = fll_fratios[i].fll_fratio; + target /= fll_fratios[i].ratio; + break; + } + } + if (i == ARRAY_SIZE(fll_fratios)) { + pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); + return -EINVAL; + } + + /* Now, calculate N.K */ + Ndiv = target / Fref; + + fll_div->n = Ndiv; + Nmod = target % Fref; + pr_debug("Nmod=%d\n", Nmod); + + /* Calculate fractional part - scale up so we can round. */ + Kpart = FIXED_FLL_SIZE * (long long)Nmod; + + do_div(Kpart, Fref); + + K = Kpart & 0xFFFFFFFF; + + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + fll_div->k = K / 10; + + pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n", + fll_div->n, fll_div->k, + fll_div->fll_fratio, fll_div->fll_outdiv, + fll_div->fll_clk_ref_div); + + return 0; +} + +static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source, + unsigned int Fref, unsigned int Fout) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8904_priv *wm8904 = codec->private_data; + struct _fll_div fll_div; + int ret, val; + int clock2, fll1; + + /* Any change? */ + if (source == wm8904->fll_src && Fref == wm8904->fll_fref && + Fout == wm8904->fll_fout) + return 0; + + if (Fout == 0) { + dev_dbg(codec->dev, "FLL disabled\n"); + + wm8904->fll_fref = 0; + wm8904->fll_fout = 0; + + /* Gate SYSCLK to avoid glitches */ + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2, + WM8904_CLK_SYS_ENA, 0); + + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0); + + goto out; + } + + /* Validate the FLL ID */ + switch (source) { + case WM8904_FLL_MCLK: + case WM8904_FLL_LRCLK: + case WM8904_FLL_BCLK: + ret = fll_factors(&fll_div, Fref, Fout); + if (ret != 0) + return ret; + break; + + case WM8904_FLL_FREE_RUNNING: + dev_dbg(codec->dev, "Using free running FLL\n"); + /* Force 12MHz and output/4 for now */ + Fout = 12000000; + Fref = 12000000; + + memset(&fll_div, 0, sizeof(fll_div)); + fll_div.fll_outdiv = 3; + break; + + default: + dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id); + return -EINVAL; + } + + /* Save current state then disable the FLL and SYSCLK to avoid + * misclocking */ + clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2); + fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1); + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2, + WM8904_CLK_SYS_ENA, 0); + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0); + + /* Unlock forced oscilator control to switch it on/off */ + snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1, + WM8904_USER_KEY, WM8904_USER_KEY); + + if (fll_id == WM8904_FLL_FREE_RUNNING) { + val = WM8904_FLL_FRC_NCO; + } else { + val = 0; + } + + snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO, + val); + snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1, + WM8904_USER_KEY, 0); + + switch (fll_id) { + case WM8904_FLL_MCLK: + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5, + WM8904_FLL_CLK_REF_SRC_MASK, 0); + break; + + case WM8904_FLL_LRCLK: + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5, + WM8904_FLL_CLK_REF_SRC_MASK, 1); + break; + + case WM8904_FLL_BCLK: + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5, + WM8904_FLL_CLK_REF_SRC_MASK, 2); + break; + } + + if (fll_div.k) + val = WM8904_FLL_FRACN_ENA; + else + val = 0; + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_FRACN_ENA, val); + + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2, + WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK, + (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) | + (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT)); + + snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k); + + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK, + fll_div.n << WM8904_FLL_N_SHIFT); + + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5, + WM8904_FLL_CLK_REF_DIV_MASK, + fll_div.fll_clk_ref_div + << WM8904_FLL_CLK_REF_DIV_SHIFT); + + dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); + + wm8904->fll_fref = Fref; + wm8904->fll_fout = Fout; + wm8904->fll_src = source; + + /* Enable the FLL if it was previously active */ + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_OSC_ENA, fll1); + snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1, + WM8904_FLL_ENA, fll1); + +out: + /* Reenable SYSCLK if it was previously active */ + snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2, + WM8904_CLK_SYS_ENA, clock2); + + return 0; +} + +static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute) +{ + struct snd_soc_codec *codec = codec_dai->codec; + int val; + + if (mute) + val = WM8904_DAC_MUTE; + else + val = 0; + + snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val); + + return 0; +} + +static int wm8904_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8904_priv *wm8904 = codec->private_data; + int ret, i; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VMID resistance 2*50k */ + snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0, + WM8904_VMID_RES_MASK, + 0x1 << WM8904_VMID_RES_SHIFT); + + /* Normal bias current */ + snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, + WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), + wm8904->supplies); + if (ret != 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + + /* Sync back cached values if they're + * different from the hardware default. + */ + for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) { + if (!wm8904_access[i].writable) + continue; + + if (wm8904->reg_cache[i] == wm8904_reg[i]) + continue; + + snd_soc_write(codec, i, wm8904->reg_cache[i]); + } + + /* Enable bias */ + snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, + WM8904_BIAS_ENA, WM8904_BIAS_ENA); + + /* Enable VMID, VMID buffering, 2*5k resistance */ + snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0, + WM8904_VMID_ENA | + WM8904_VMID_RES_MASK, + WM8904_VMID_ENA | + 0x3 << WM8904_VMID_RES_SHIFT); + + /* Let VMID ramp */ + msleep(1); + } + + /* Maintain VMID with 2*250k */ + snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0, + WM8904_VMID_RES_MASK, + 0x2 << WM8904_VMID_RES_SHIFT); + + /* Bias current *0.5 */ + snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, + WM8904_ISEL_MASK, 0); + break; + + case SND_SOC_BIAS_OFF: + /* Turn off VMID */ + snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0, + WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0); + + /* Stop bias generation */ + snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, + WM8904_BIAS_ENA, 0); + + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), + wm8904->supplies); + break; + } + codec->bias_level = level; + return 0; +} + +#define WM8904_RATES SNDRV_PCM_RATE_8000_96000 + +#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8904_dai_ops = { + .set_sysclk = wm8904_set_sysclk, + .set_fmt = wm8904_set_fmt, + .set_tdm_slot = wm8904_set_tdm_slot, + .set_pll = wm8904_set_fll, + .hw_params = wm8904_hw_params, + .digital_mute = wm8904_digital_mute, +}; + +struct snd_soc_dai wm8904_dai = { + .name = "WM8904", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8904_RATES, + .formats = WM8904_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = WM8904_RATES, + .formats = WM8904_FORMATS, + }, + .ops = &wm8904_dai_ops, + .symmetric_rates = 1, +}; +EXPORT_SYMBOL_GPL(wm8904_dai); + +#ifdef CONFIG_PM +static int wm8904_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int wm8904_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + return 0; +} +#else +#define wm8904_suspend NULL +#define wm8904_resume NULL +#endif + +static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904) +{ + struct snd_soc_codec *codec = &wm8904->codec; + struct wm8904_pdata *pdata = wm8904->pdata; + struct snd_kcontrol_new control = + SOC_ENUM_EXT("EQ Mode", + wm8904->retune_mobile_enum, + wm8904_get_retune_mobile_enum, + wm8904_put_retune_mobile_enum); + int ret, i, j; + const char **t; + + /* We need an array of texts for the enum API but the number + * of texts is likely to be less than the number of + * configurations due to the sample rate dependency of the + * configurations. */ + wm8904->num_retune_mobile_texts = 0; + wm8904->retune_mobile_texts = NULL; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + for (j = 0; j < wm8904->num_retune_mobile_texts; j++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8904->retune_mobile_texts[j]) == 0) + break; + } + + if (j != wm8904->num_retune_mobile_texts) + continue; + + /* Expand the array... */ + t = krealloc(wm8904->retune_mobile_texts, + sizeof(char *) * + (wm8904->num_retune_mobile_texts + 1), + GFP_KERNEL); + if (t == NULL) + continue; + + /* ...store the new entry... */ + t[wm8904->num_retune_mobile_texts] = + pdata->retune_mobile_cfgs[i].name; + + /* ...and remember the new version. */ + wm8904->num_retune_mobile_texts++; + wm8904->retune_mobile_texts = t; + } + + dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", + wm8904->num_retune_mobile_texts); + + wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; + wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; + + ret = snd_soc_add_controls(&wm8904->codec, &control, 1); + if (ret != 0) + dev_err(wm8904->codec.dev, + "Failed to add ReTune Mobile control: %d\n", ret); +} + +static void wm8904_handle_pdata(struct wm8904_priv *wm8904) +{ + struct snd_soc_codec *codec = &wm8904->codec; + struct wm8904_pdata *pdata = wm8904->pdata; + int ret, i; + + if (!pdata) { + snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, + ARRAY_SIZE(wm8904_eq_controls)); + return; + } + + dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs); + + if (pdata->num_drc_cfgs) { + struct snd_kcontrol_new control = + SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum, + wm8904_get_drc_enum, wm8904_put_drc_enum); + + /* We need an array of texts for the enum API */ + wm8904->drc_texts = kmalloc(sizeof(char *) + * pdata->num_drc_cfgs, GFP_KERNEL); + if (!wm8904->drc_texts) { + dev_err(wm8904->codec.dev, + "Failed to allocate %d DRC config texts\n", + pdata->num_drc_cfgs); + return; + } + + for (i = 0; i < pdata->num_drc_cfgs; i++) + wm8904->drc_texts[i] = pdata->drc_cfgs[i].name; + + wm8904->drc_enum.max = pdata->num_drc_cfgs; + wm8904->drc_enum.texts = wm8904->drc_texts; + + ret = snd_soc_add_controls(&wm8904->codec, &control, 1); + if (ret != 0) + dev_err(wm8904->codec.dev, + "Failed to add DRC mode control: %d\n", ret); + + wm8904_set_drc(codec); + } + + dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", + pdata->num_retune_mobile_cfgs); + + if (pdata->num_retune_mobile_cfgs) + wm8904_handle_retune_mobile_pdata(wm8904); + else + snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, + ARRAY_SIZE(wm8904_eq_controls)); +} + +static int wm8904_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + int ret = 0; + + if (wm8904_codec == NULL) { + dev_err(&pdev->dev, "Codec device not registered\n"); + return -ENODEV; + } + + socdev->card->codec = wm8904_codec; + codec = wm8904_codec; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(codec->dev, "failed to create pcms: %d\n", ret); + goto pcm_err; + } + + wm8904_handle_pdata(codec->private_data); + + wm8904_add_widgets(codec); + + return ret; + +pcm_err: + return ret; +} + +static int wm8904_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8904 = { + .probe = wm8904_probe, + .remove = wm8904_remove, + .suspend = wm8904_suspend, + .resume = wm8904_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904); + +static int wm8904_register(struct wm8904_priv *wm8904, + enum snd_soc_control_type control) +{ + int ret; + struct snd_soc_codec *codec = &wm8904->codec; + int i; + + if (wm8904_codec) { + dev_err(codec->dev, "Another WM8904 is registered\n"); + return -EINVAL; + } + + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + codec->private_data = wm8904; + codec->name = "WM8904"; + codec->owner = THIS_MODULE; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = wm8904_set_bias_level; + codec->dai = &wm8904_dai; + codec->num_dai = 1; + codec->reg_cache_size = WM8904_MAX_REGISTER; + codec->reg_cache = &wm8904->reg_cache; + codec->volatile_register = wm8904_volatile_register; + + memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + goto err; + } + + for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) + wm8904->supplies[i].supply = wm8904_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies), + wm8904->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + goto err; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), + wm8904->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID); + if (ret < 0) { + dev_err(codec->dev, "Failed to read ID register\n"); + goto err_enable; + } + if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) { + dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); + ret = -EINVAL; + goto err_enable; + } + + ret = snd_soc_read(codec, WM8904_REVISION); + if (ret < 0) { + dev_err(codec->dev, "Failed to read device revision: %d\n", + ret); + goto err_enable; + } + dev_info(codec->dev, "revision %c\n", ret + 'A'); + + ret = wm8904_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + goto err_enable; + } + + wm8904_dai.dev = codec->dev; + + /* Change some default settings - latch VU and enable ZC */ + wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; + wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; + wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; + wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; + wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | + WM8904_HPOUTLZC; + wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | + WM8904_HPOUTRZC; + wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | + WM8904_LINEOUTLZC; + wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | + WM8904_LINEOUTRZC; + wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; + + /* Set Class W by default - this will be managed by the Class + * G widget at runtime where bypass paths are available. + */ + wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; + + /* Use normal bias source */ + wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; + + wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* Bias level configuration will have done an extra enable */ + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); + + wm8904_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret != 0) { + dev_err(codec->dev, "Failed to register codec: %d\n", ret); + return ret; + } + + ret = snd_soc_register_dai(&wm8904_dai); + if (ret != 0) { + dev_err(codec->dev, "Failed to register DAI: %d\n", ret); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); +err: + kfree(wm8904); + return ret; +} + +static void wm8904_unregister(struct wm8904_priv *wm8904) +{ + wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF); + regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); + snd_soc_unregister_dai(&wm8904_dai); + snd_soc_unregister_codec(&wm8904->codec); + kfree(wm8904); + wm8904_codec = NULL; +} + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8904_priv *wm8904; + struct snd_soc_codec *codec; + + wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); + if (wm8904 == NULL) + return -ENOMEM; + + codec = &wm8904->codec; + codec->hw_write = (hw_write_t)i2c_master_send; + + i2c_set_clientdata(i2c, wm8904); + codec->control_data = i2c; + wm8904->pdata = i2c->dev.platform_data; + + codec->dev = &i2c->dev; + + return wm8904_register(wm8904, SND_SOC_I2C); +} + +static __devexit int wm8904_i2c_remove(struct i2c_client *client) +{ + struct wm8904_priv *wm8904 = i2c_get_clientdata(client); + wm8904_unregister(wm8904); + return 0; +} + +static const struct i2c_device_id wm8904_i2c_id[] = { + { "wm8904", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); + +static struct i2c_driver wm8904_i2c_driver = { + .driver = { + .name = "WM8904", + .owner = THIS_MODULE, + }, + .probe = wm8904_i2c_probe, + .remove = __devexit_p(wm8904_i2c_remove), + .id_table = wm8904_i2c_id, +}; +#endif + +static int __init wm8904_modinit(void) +{ + int ret; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + ret = i2c_add_driver(&wm8904_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n", + ret); + } +#endif + return 0; +} +module_init(wm8904_modinit); + +static void __exit wm8904_exit(void) +{ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&wm8904_i2c_driver); +#endif +} +module_exit(wm8904_exit); + +MODULE_DESCRIPTION("ASoC WM8904 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h new file mode 100644 index 000000000000..b68886df34e4 --- /dev/null +++ b/sound/soc/codecs/wm8904.h @@ -0,0 +1,1681 @@ +/* + * wm8904.h -- WM8904 ASoC driver + * + * Copyright 2009 Wolfson Microelectronics, plc + * + * Author: Mark Brown + * + * 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 _WM8904_H +#define _WM8904_H + +#define WM8904_CLK_MCLK 1 +#define WM8904_CLK_FLL 2 + +#define WM8904_FLL_MCLK 1 +#define WM8904_FLL_BCLK 2 +#define WM8904_FLL_LRCLK 3 +#define WM8904_FLL_FREE_RUNNING 4 + +extern struct snd_soc_dai wm8904_dai; +extern struct snd_soc_codec_device soc_codec_dev_wm8904; + +/* + * Register values. + */ +#define WM8904_SW_RESET_AND_ID 0x00 +#define WM8904_REVISION 0x01 +#define WM8904_BIAS_CONTROL_0 0x04 +#define WM8904_VMID_CONTROL_0 0x05 +#define WM8904_MIC_BIAS_CONTROL_0 0x06 +#define WM8904_MIC_BIAS_CONTROL_1 0x07 +#define WM8904_ANALOGUE_DAC_0 0x08 +#define WM8904_MIC_FILTER_CONTROL 0x09 +#define WM8904_ANALOGUE_ADC_0 0x0A +#define WM8904_POWER_MANAGEMENT_0 0x0C +#define WM8904_POWER_MANAGEMENT_2 0x0E +#define WM8904_POWER_MANAGEMENT_3 0x0F +#define WM8904_POWER_MANAGEMENT_6 0x12 +#define WM8904_CLOCK_RATES_0 0x14 +#define WM8904_CLOCK_RATES_1 0x15 +#define WM8904_CLOCK_RATES_2 0x16 +#define WM8904_AUDIO_INTERFACE_0 0x18 +#define WM8904_AUDIO_INTERFACE_1 0x19 +#define WM8904_AUDIO_INTERFACE_2 0x1A +#define WM8904_AUDIO_INTERFACE_3 0x1B +#define WM8904_DAC_DIGITAL_VOLUME_LEFT 0x1E +#define WM8904_DAC_DIGITAL_VOLUME_RIGHT 0x1F +#define WM8904_DAC_DIGITAL_0 0x20 +#define WM8904_DAC_DIGITAL_1 0x21 +#define WM8904_ADC_DIGITAL_VOLUME_LEFT 0x24 +#define WM8904_ADC_DIGITAL_VOLUME_RIGHT 0x25 +#define WM8904_ADC_DIGITAL_0 0x26 +#define WM8904_DIGITAL_MICROPHONE_0 0x27 +#define WM8904_DRC_0 0x28 +#define WM8904_DRC_1 0x29 +#define WM8904_DRC_2 0x2A +#define WM8904_DRC_3 0x2B +#define WM8904_ANALOGUE_LEFT_INPUT_0 0x2C +#define WM8904_ANALOGUE_RIGHT_INPUT_0 0x2D +#define WM8904_ANALOGUE_LEFT_INPUT_1 0x2E +#define WM8904_ANALOGUE_RIGHT_INPUT_1 0x2F +#define WM8904_ANALOGUE_OUT1_LEFT 0x39 +#define WM8904_ANALOGUE_OUT1_RIGHT 0x3A +#define WM8904_ANALOGUE_OUT2_LEFT 0x3B +#define WM8904_ANALOGUE_OUT2_RIGHT 0x3C +#define WM8904_ANALOGUE_OUT12_ZC 0x3D +#define WM8904_DC_SERVO_0 0x43 +#define WM8904_DC_SERVO_1 0x44 +#define WM8904_DC_SERVO_2 0x45 +#define WM8904_DC_SERVO_4 0x47 +#define WM8904_DC_SERVO_5 0x48 +#define WM8904_DC_SERVO_6 0x49 +#define WM8904_DC_SERVO_7 0x4A +#define WM8904_DC_SERVO_8 0x4B +#define WM8904_DC_SERVO_9 0x4C +#define WM8904_DC_SERVO_READBACK_0 0x4D +#define WM8904_ANALOGUE_HP_0 0x5A +#define WM8904_ANALOGUE_LINEOUT_0 0x5E +#define WM8904_CHARGE_PUMP_0 0x62 +#define WM8904_CLASS_W_0 0x68 +#define WM8904_WRITE_SEQUENCER_0 0x6C +#define WM8904_WRITE_SEQUENCER_1 0x6D +#define WM8904_WRITE_SEQUENCER_2 0x6E +#define WM8904_WRITE_SEQUENCER_3 0x6F +#define WM8904_WRITE_SEQUENCER_4 0x70 +#define WM8904_FLL_CONTROL_1 0x74 +#define WM8904_FLL_CONTROL_2 0x75 +#define WM8904_FLL_CONTROL_3 0x76 +#define WM8904_FLL_CONTROL_4 0x77 +#define WM8904_FLL_CONTROL_5 0x78 +#define WM8904_GPIO_CONTROL_1 0x79 +#define WM8904_GPIO_CONTROL_2 0x7A +#define WM8904_GPIO_CONTROL_3 0x7B +#define WM8904_GPIO_CONTROL_4 0x7C +#define WM8904_DIGITAL_PULLS 0x7E +#define WM8904_INTERRUPT_STATUS 0x7F +#define WM8904_INTERRUPT_STATUS_MASK 0x80 +#define WM8904_INTERRUPT_POLARITY 0x81 +#define WM8904_INTERRUPT_DEBOUNCE 0x82 +#define WM8904_EQ1 0x86 +#define WM8904_EQ2 0x87 +#define WM8904_EQ3 0x88 +#define WM8904_EQ4 0x89 +#define WM8904_EQ5 0x8A +#define WM8904_EQ6 0x8B +#define WM8904_EQ7 0x8C +#define WM8904_EQ8 0x8D +#define WM8904_EQ9 0x8E +#define WM8904_EQ10 0x8F +#define WM8904_EQ11 0x90 +#define WM8904_EQ12 0x91 +#define WM8904_EQ13 0x92 +#define WM8904_EQ14 0x93 +#define WM8904_EQ15 0x94 +#define WM8904_EQ16 0x95 +#define WM8904_EQ17 0x96 +#define WM8904_EQ18 0x97 +#define WM8904_EQ19 0x98 +#define WM8904_EQ20 0x99 +#define WM8904_EQ21 0x9A +#define WM8904_EQ22 0x9B +#define WM8904_EQ23 0x9C +#define WM8904_EQ24 0x9D +#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1 +#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC +#define WM8904_FLL_NCO_TEST_0 0xF7 +#define WM8904_FLL_NCO_TEST_1 0xF8 + +#define WM8904_REGISTER_COUNT 101 +#define WM8904_MAX_REGISTER 0xF8 + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - SW Reset and ID + */ +#define WM8904_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */ +#define WM8904_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */ +#define WM8904_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */ + +/* + * R1 (0x01) - Revision + */ +#define WM8904_REVISION_MASK 0x000F /* REVISION - [3:0] */ +#define WM8904_REVISION_SHIFT 0 /* REVISION - [3:0] */ +#define WM8904_REVISION_WIDTH 16 /* REVISION - [3:0] */ + +/* + * R4 (0x04) - Bias Control 0 + */ +#define WM8904_POBCTRL 0x0010 /* POBCTRL */ +#define WM8904_POBCTRL_MASK 0x0010 /* POBCTRL */ +#define WM8904_POBCTRL_SHIFT 4 /* POBCTRL */ +#define WM8904_POBCTRL_WIDTH 1 /* POBCTRL */ +#define WM8904_ISEL_MASK 0x000C /* ISEL - [3:2] */ +#define WM8904_ISEL_SHIFT 2 /* ISEL - [3:2] */ +#define WM8904_ISEL_WIDTH 2 /* ISEL - [3:2] */ +#define WM8904_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */ +#define WM8904_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */ +#define WM8904_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */ +#define WM8904_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */ +#define WM8904_BIAS_ENA 0x0001 /* BIAS_ENA */ +#define WM8904_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */ +#define WM8904_BIAS_ENA_SHIFT 0 /* BIAS_ENA */ +#define WM8904_BIAS_ENA_WIDTH 1 /* BIAS_ENA */ + +/* + * R5 (0x05) - VMID Control 0 + */ +#define WM8904_VMID_BUF_ENA 0x0040 /* VMID_BUF_ENA */ +#define WM8904_VMID_BUF_ENA_MASK 0x0040 /* VMID_BUF_ENA */ +#define WM8904_VMID_BUF_ENA_SHIFT 6 /* VMID_BUF_ENA */ +#define WM8904_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */ +#define WM8904_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */ +#define WM8904_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */ +#define WM8904_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */ +#define WM8904_VMID_ENA 0x0001 /* VMID_ENA */ +#define WM8904_VMID_ENA_MASK 0x0001 /* VMID_ENA */ +#define WM8904_VMID_ENA_SHIFT 0 /* VMID_ENA */ +#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */ + +/* + * R6 (0x06) - Mic Bias Control 0 + */ +#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */ +#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */ +#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */ +#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */ +#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */ +#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */ +#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */ +#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */ +#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */ +#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */ +#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */ +#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */ +#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */ +#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */ + +/* + * R7 (0x07) - Mic Bias Control 1 + */ +#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */ +#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */ +#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */ +#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */ +#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */ +#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */ +#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */ +#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */ +#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */ +#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */ +#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */ + +/* + * R8 (0x08) - Analogue DAC 0 + */ +#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */ +#define WM8904_DAC_BIAS_SEL_SHIFT 3 /* DAC_BIAS_SEL - [4:3] */ +#define WM8904_DAC_BIAS_SEL_WIDTH 2 /* DAC_BIAS_SEL - [4:3] */ +#define WM8904_DAC_VMID_BIAS_SEL_MASK 0x0006 /* DAC_VMID_BIAS_SEL - [2:1] */ +#define WM8904_DAC_VMID_BIAS_SEL_SHIFT 1 /* DAC_VMID_BIAS_SEL - [2:1] */ +#define WM8904_DAC_VMID_BIAS_SEL_WIDTH 2 /* DAC_VMID_BIAS_SEL - [2:1] */ + +/* + * R9 (0x09) - mic Filter Control + */ +#define WM8904_MIC_DET_SET_THRESHOLD_MASK 0xF000 /* MIC_DET_SET_THRESHOLD - [15:12] */ +#define WM8904_MIC_DET_SET_THRESHOLD_SHIFT 12 /* MIC_DET_SET_THRESHOLD - [15:12] */ +#define WM8904_MIC_DET_SET_THRESHOLD_WIDTH 4 /* MIC_DET_SET_THRESHOLD - [15:12] */ +#define WM8904_MIC_DET_RESET_THRESHOLD_MASK 0x0F00 /* MIC_DET_RESET_THRESHOLD - [11:8] */ +#define WM8904_MIC_DET_RESET_THRESHOLD_SHIFT 8 /* MIC_DET_RESET_THRESHOLD - [11:8] */ +#define WM8904_MIC_DET_RESET_THRESHOLD_WIDTH 4 /* MIC_DET_RESET_THRESHOLD - [11:8] */ +#define WM8904_MIC_SHORT_SET_THRESHOLD_MASK 0x00F0 /* MIC_SHORT_SET_THRESHOLD - [7:4] */ +#define WM8904_MIC_SHORT_SET_THRESHOLD_SHIFT 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */ +#define WM8904_MIC_SHORT_SET_THRESHOLD_WIDTH 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */ +#define WM8904_MIC_SHORT_RESET_THRESHOLD_MASK 0x000F /* MIC_SHORT_RESET_THRESHOLD - [3:0] */ +#define WM8904_MIC_SHORT_RESET_THRESHOLD_SHIFT 0 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */ +#define WM8904_MIC_SHORT_RESET_THRESHOLD_WIDTH 4 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */ + +/* + * R10 (0x0A) - Analogue ADC 0 + */ +#define WM8904_ADC_OSR128 0x0001 /* ADC_OSR128 */ +#define WM8904_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */ +#define WM8904_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */ +#define WM8904_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */ + +/* + * R12 (0x0C) - Power Management 0 + */ +#define WM8904_INL_ENA 0x0002 /* INL_ENA */ +#define WM8904_INL_ENA_MASK 0x0002 /* INL_ENA */ +#define WM8904_INL_ENA_SHIFT 1 /* INL_ENA */ +#define WM8904_INL_ENA_WIDTH 1 /* INL_ENA */ +#define WM8904_INR_ENA 0x0001 /* INR_ENA */ +#define WM8904_INR_ENA_MASK 0x0001 /* INR_ENA */ +#define WM8904_INR_ENA_SHIFT 0 /* INR_ENA */ +#define WM8904_INR_ENA_WIDTH 1 /* INR_ENA */ + +/* + * R14 (0x0E) - Power Management 2 + */ +#define WM8904_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */ +#define WM8904_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */ +#define WM8904_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */ +#define WM8904_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */ +#define WM8904_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */ +#define WM8904_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */ +#define WM8904_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */ +#define WM8904_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */ + +/* + * R15 (0x0F) - Power Management 3 + */ +#define WM8904_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */ +#define WM8904_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */ +#define WM8904_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */ +#define WM8904_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */ +#define WM8904_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */ +#define WM8904_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */ +#define WM8904_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */ +#define WM8904_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */ + +/* + * R18 (0x12) - Power Management 6 + */ +#define WM8904_DACL_ENA 0x0008 /* DACL_ENA */ +#define WM8904_DACL_ENA_MASK 0x0008 /* DACL_ENA */ +#define WM8904_DACL_ENA_SHIFT 3 /* DACL_ENA */ +#define WM8904_DACL_ENA_WIDTH 1 /* DACL_ENA */ +#define WM8904_DACR_ENA 0x0004 /* DACR_ENA */ +#define WM8904_DACR_ENA_MASK 0x0004 /* DACR_ENA */ +#define WM8904_DACR_ENA_SHIFT 2 /* DACR_ENA */ +#define WM8904_DACR_ENA_WIDTH 1 /* DACR_ENA */ +#define WM8904_ADCL_ENA 0x0002 /* ADCL_ENA */ +#define WM8904_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ +#define WM8904_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ +#define WM8904_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ +#define WM8904_ADCR_ENA 0x0001 /* ADCR_ENA */ +#define WM8904_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ +#define WM8904_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ +#define WM8904_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ + +/* + * R20 (0x14) - Clock Rates 0 + */ +#define WM8904_TOCLK_RATE_DIV16 0x4000 /* TOCLK_RATE_DIV16 */ +#define WM8904_TOCLK_RATE_DIV16_MASK 0x4000 /* TOCLK_RATE_DIV16 */ +#define WM8904_TOCLK_RATE_DIV16_SHIFT 14 /* TOCLK_RATE_DIV16 */ +#define WM8904_TOCLK_RATE_DIV16_WIDTH 1 /* TOCLK_RATE_DIV16 */ +#define WM8904_TOCLK_RATE_X4 0x2000 /* TOCLK_RATE_X4 */ +#define WM8904_TOCLK_RATE_X4_MASK 0x2000 /* TOCLK_RATE_X4 */ +#define WM8904_TOCLK_RATE_X4_SHIFT 13 /* TOCLK_RATE_X4 */ +#define WM8904_TOCLK_RATE_X4_WIDTH 1 /* TOCLK_RATE_X4 */ +#define WM8904_SR_MODE 0x1000 /* SR_MODE */ +#define WM8904_SR_MODE_MASK 0x1000 /* SR_MODE */ +#define WM8904_SR_MODE_SHIFT 12 /* SR_MODE */ +#define WM8904_SR_MODE_WIDTH 1 /* SR_MODE */ +#define WM8904_MCLK_DIV 0x0001 /* MCLK_DIV */ +#define WM8904_MCLK_DIV_MASK 0x0001 /* MCLK_DIV */ +#define WM8904_MCLK_DIV_SHIFT 0 /* MCLK_DIV */ +#define WM8904_MCLK_DIV_WIDTH 1 /* MCLK_DIV */ + +/* + * R21 (0x15) - Clock Rates 1 + */ +#define WM8904_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */ +#define WM8904_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */ +#define WM8904_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */ +#define WM8904_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */ +#define WM8904_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */ +#define WM8904_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */ + +/* + * R22 (0x16) - Clock Rates 2 + */ +#define WM8904_MCLK_INV 0x8000 /* MCLK_INV */ +#define WM8904_MCLK_INV_MASK 0x8000 /* MCLK_INV */ +#define WM8904_MCLK_INV_SHIFT 15 /* MCLK_INV */ +#define WM8904_MCLK_INV_WIDTH 1 /* MCLK_INV */ +#define WM8904_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */ +#define WM8904_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */ +#define WM8904_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */ +#define WM8904_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */ +#define WM8904_TOCLK_RATE 0x1000 /* TOCLK_RATE */ +#define WM8904_TOCLK_RATE_MASK 0x1000 /* TOCLK_RATE */ +#define WM8904_TOCLK_RATE_SHIFT 12 /* TOCLK_RATE */ +#define WM8904_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */ +#define WM8904_OPCLK_ENA 0x0008 /* OPCLK_ENA */ +#define WM8904_OPCLK_ENA_MASK 0x0008 /* OPCLK_ENA */ +#define WM8904_OPCLK_ENA_SHIFT 3 /* OPCLK_ENA */ +#define WM8904_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ +#define WM8904_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */ +#define WM8904_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */ +#define WM8904_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */ +#define WM8904_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */ +#define WM8904_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */ +#define WM8904_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */ +#define WM8904_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */ +#define WM8904_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */ +#define WM8904_TOCLK_ENA 0x0001 /* TOCLK_ENA */ +#define WM8904_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */ +#define WM8904_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */ +#define WM8904_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ + +/* + * R24 (0x18) - Audio Interface 0 + */ +#define WM8904_DACL_DATINV 0x1000 /* DACL_DATINV */ +#define WM8904_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */ +#define WM8904_DACL_DATINV_SHIFT 12 /* DACL_DATINV */ +#define WM8904_DACL_DATINV_WIDTH 1 /* DACL_DATINV */ +#define WM8904_DACR_DATINV 0x0800 /* DACR_DATINV */ +#define WM8904_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */ +#define WM8904_DACR_DATINV_SHIFT 11 /* DACR_DATINV */ +#define WM8904_DACR_DATINV_WIDTH 1 /* DACR_DATINV */ +#define WM8904_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */ +#define WM8904_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */ +#define WM8904_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */ +#define WM8904_LOOPBACK 0x0100 /* LOOPBACK */ +#define WM8904_LOOPBACK_MASK 0x0100 /* LOOPBACK */ +#define WM8904_LOOPBACK_SHIFT 8 /* LOOPBACK */ +#define WM8904_LOOPBACK_WIDTH 1 /* LOOPBACK */ +#define WM8904_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */ +#define WM8904_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */ +#define WM8904_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */ +#define WM8904_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */ +#define WM8904_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */ +#define WM8904_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */ +#define WM8904_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */ +#define WM8904_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */ +#define WM8904_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */ +#define WM8904_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */ +#define WM8904_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */ +#define WM8904_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */ +#define WM8904_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */ +#define WM8904_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */ +#define WM8904_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */ +#define WM8904_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */ +#define WM8904_ADC_COMP 0x0008 /* ADC_COMP */ +#define WM8904_ADC_COMP_MASK 0x0008 /* ADC_COMP */ +#define WM8904_ADC_COMP_SHIFT 3 /* ADC_COMP */ +#define WM8904_ADC_COMP_WIDTH 1 /* ADC_COMP */ +#define WM8904_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */ +#define WM8904_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */ +#define WM8904_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */ +#define WM8904_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */ +#define WM8904_DAC_COMP 0x0002 /* DAC_COMP */ +#define WM8904_DAC_COMP_MASK 0x0002 /* DAC_COMP */ +#define WM8904_DAC_COMP_SHIFT 1 /* DAC_COMP */ +#define WM8904_DAC_COMP_WIDTH 1 /* DAC_COMP */ +#define WM8904_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */ +#define WM8904_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */ +#define WM8904_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */ +#define WM8904_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */ + +/* + * R25 (0x19) - Audio Interface 1 + */ +#define WM8904_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */ +#define WM8904_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */ +#define WM8904_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */ +#define WM8904_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */ +#define WM8904_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */ +#define WM8904_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */ +#define WM8904_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */ +#define WM8904_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */ +#define WM8904_AIFADC_TDM 0x0800 /* AIFADC_TDM */ +#define WM8904_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */ +#define WM8904_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */ +#define WM8904_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */ +#define WM8904_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */ +#define WM8904_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */ +#define WM8904_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */ +#define WM8904_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */ +#define WM8904_AIF_TRIS 0x0100 /* AIF_TRIS */ +#define WM8904_AIF_TRIS_MASK 0x0100 /* AIF_TRIS */ +#define WM8904_AIF_TRIS_SHIFT 8 /* AIF_TRIS */ +#define WM8904_AIF_TRIS_WIDTH 1 /* AIF_TRIS */ +#define WM8904_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */ +#define WM8904_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */ +#define WM8904_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */ +#define WM8904_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */ +#define WM8904_BCLK_DIR 0x0040 /* BCLK_DIR */ +#define WM8904_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */ +#define WM8904_BCLK_DIR_SHIFT 6 /* BCLK_DIR */ +#define WM8904_BCLK_DIR_WIDTH 1 /* BCLK_DIR */ +#define WM8904_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */ +#define WM8904_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */ +#define WM8904_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */ +#define WM8904_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */ +#define WM8904_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */ +#define WM8904_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */ +#define WM8904_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */ +#define WM8904_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */ +#define WM8904_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */ +#define WM8904_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */ + +/* + * R26 (0x1A) - Audio Interface 2 + */ +#define WM8904_OPCLK_DIV_MASK 0x0F00 /* OPCLK_DIV - [11:8] */ +#define WM8904_OPCLK_DIV_SHIFT 8 /* OPCLK_DIV - [11:8] */ +#define WM8904_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [11:8] */ +#define WM8904_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */ +#define WM8904_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */ +#define WM8904_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */ + +/* + * R27 (0x1B) - Audio Interface 3 + */ +#define WM8904_LRCLK_DIR 0x0800 /* LRCLK_DIR */ +#define WM8904_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */ +#define WM8904_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */ +#define WM8904_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */ +#define WM8904_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */ +#define WM8904_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */ +#define WM8904_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */ + +/* + * R30 (0x1E) - DAC Digital Volume Left + */ +#define WM8904_DAC_VU 0x0100 /* DAC_VU */ +#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */ +#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */ +#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */ +#define WM8904_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */ +#define WM8904_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */ +#define WM8904_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */ + +/* + * R31 (0x1F) - DAC Digital Volume Right + */ +#define WM8904_DAC_VU 0x0100 /* DAC_VU */ +#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */ +#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */ +#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */ +#define WM8904_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */ +#define WM8904_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */ +#define WM8904_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */ + +/* + * R32 (0x20) - DAC Digital 0 + */ +#define WM8904_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */ +#define WM8904_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */ +#define WM8904_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */ +#define WM8904_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */ +#define WM8904_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */ +#define WM8904_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */ +#define WM8904_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */ +#define WM8904_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */ +#define WM8904_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */ +#define WM8904_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */ +#define WM8904_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */ +#define WM8904_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */ + +/* + * R33 (0x21) - DAC Digital 1 + */ +#define WM8904_DAC_MONO 0x1000 /* DAC_MONO */ +#define WM8904_DAC_MONO_MASK 0x1000 /* DAC_MONO */ +#define WM8904_DAC_MONO_SHIFT 12 /* DAC_MONO */ +#define WM8904_DAC_MONO_WIDTH 1 /* DAC_MONO */ +#define WM8904_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */ +#define WM8904_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */ +#define WM8904_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */ +#define WM8904_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */ +#define WM8904_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */ +#define WM8904_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */ +#define WM8904_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */ +#define WM8904_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ +#define WM8904_DAC_UNMUTE_RAMP 0x0200 /* DAC_UNMUTE_RAMP */ +#define WM8904_DAC_UNMUTE_RAMP_MASK 0x0200 /* DAC_UNMUTE_RAMP */ +#define WM8904_DAC_UNMUTE_RAMP_SHIFT 9 /* DAC_UNMUTE_RAMP */ +#define WM8904_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */ +#define WM8904_DAC_OSR128 0x0040 /* DAC_OSR128 */ +#define WM8904_DAC_OSR128_MASK 0x0040 /* DAC_OSR128 */ +#define WM8904_DAC_OSR128_SHIFT 6 /* DAC_OSR128 */ +#define WM8904_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */ +#define WM8904_DAC_MUTE 0x0008 /* DAC_MUTE */ +#define WM8904_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */ +#define WM8904_DAC_MUTE_SHIFT 3 /* DAC_MUTE */ +#define WM8904_DAC_MUTE_WIDTH 1 /* DAC_MUTE */ +#define WM8904_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */ +#define WM8904_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */ +#define WM8904_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */ + +/* + * R36 (0x24) - ADC Digital Volume Left + */ +#define WM8904_ADC_VU 0x0100 /* ADC_VU */ +#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */ +#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */ +#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */ +#define WM8904_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */ +#define WM8904_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */ +#define WM8904_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */ + +/* + * R37 (0x25) - ADC Digital Volume Right + */ +#define WM8904_ADC_VU 0x0100 /* ADC_VU */ +#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */ +#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */ +#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */ +#define WM8904_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */ +#define WM8904_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */ +#define WM8904_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */ + +/* + * R38 (0x26) - ADC Digital 0 + */ +#define WM8904_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */ +#define WM8904_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */ +#define WM8904_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */ +#define WM8904_ADC_HPF 0x0010 /* ADC_HPF */ +#define WM8904_ADC_HPF_MASK 0x0010 /* ADC_HPF */ +#define WM8904_ADC_HPF_SHIFT 4 /* ADC_HPF */ +#define WM8904_ADC_HPF_WIDTH 1 /* ADC_HPF */ +#define WM8904_ADCL_DATINV 0x0002 /* ADCL_DATINV */ +#define WM8904_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */ +#define WM8904_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */ +#define WM8904_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */ +#define WM8904_ADCR_DATINV 0x0001 /* ADCR_DATINV */ +#define WM8904_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */ +#define WM8904_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */ +#define WM8904_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */ + +/* + * R39 (0x27) - Digital Microphone 0 + */ +#define WM8904_DMIC_ENA 0x1000 /* DMIC_ENA */ +#define WM8904_DMIC_ENA_MASK 0x1000 /* DMIC_ENA */ +#define WM8904_DMIC_ENA_SHIFT 12 /* DMIC_ENA */ +#define WM8904_DMIC_ENA_WIDTH 1 /* DMIC_ENA */ +#define WM8904_DMIC_SRC 0x0800 /* DMIC_SRC */ +#define WM8904_DMIC_SRC_MASK 0x0800 /* DMIC_SRC */ +#define WM8904_DMIC_SRC_SHIFT 11 /* DMIC_SRC */ +#define WM8904_DMIC_SRC_WIDTH 1 /* DMIC_SRC */ + +/* + * R40 (0x28) - DRC 0 + */ +#define WM8904_DRC_ENA 0x8000 /* DRC_ENA */ +#define WM8904_DRC_ENA_MASK 0x8000 /* DRC_ENA */ +#define WM8904_DRC_ENA_SHIFT 15 /* DRC_ENA */ +#define WM8904_DRC_ENA_WIDTH 1 /* DRC_ENA */ +#define WM8904_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */ +#define WM8904_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */ +#define WM8904_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */ +#define WM8904_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */ +#define WM8904_DRC_GS_HYST_LVL_MASK 0x1800 /* DRC_GS_HYST_LVL - [12:11] */ +#define WM8904_DRC_GS_HYST_LVL_SHIFT 11 /* DRC_GS_HYST_LVL - [12:11] */ +#define WM8904_DRC_GS_HYST_LVL_WIDTH 2 /* DRC_GS_HYST_LVL - [12:11] */ +#define WM8904_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */ +#define WM8904_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */ +#define WM8904_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */ +#define WM8904_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */ +#define WM8904_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */ +#define WM8904_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */ +#define WM8904_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */ +#define WM8904_DRC_GS_ENA 0x0008 /* DRC_GS_ENA */ +#define WM8904_DRC_GS_ENA_MASK 0x0008 /* DRC_GS_ENA */ +#define WM8904_DRC_GS_ENA_SHIFT 3 /* DRC_GS_ENA */ +#define WM8904_DRC_GS_ENA_WIDTH 1 /* DRC_GS_ENA */ +#define WM8904_DRC_QR 0x0004 /* DRC_QR */ +#define WM8904_DRC_QR_MASK 0x0004 /* DRC_QR */ +#define WM8904_DRC_QR_SHIFT 2 /* DRC_QR */ +#define WM8904_DRC_QR_WIDTH 1 /* DRC_QR */ +#define WM8904_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */ +#define WM8904_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */ +#define WM8904_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */ +#define WM8904_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */ +#define WM8904_DRC_GS_HYST 0x0001 /* DRC_GS_HYST */ +#define WM8904_DRC_GS_HYST_MASK 0x0001 /* DRC_GS_HYST */ +#define WM8904_DRC_GS_HYST_SHIFT 0 /* DRC_GS_HYST */ +#define WM8904_DRC_GS_HYST_WIDTH 1 /* DRC_GS_HYST */ + +/* + * R41 (0x29) - DRC 1 + */ +#define WM8904_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */ +#define WM8904_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */ +#define WM8904_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */ +#define WM8904_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */ +#define WM8904_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */ +#define WM8904_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */ +#define WM8904_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */ +#define WM8904_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */ +#define WM8904_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */ +#define WM8904_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */ +#define WM8904_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */ +#define WM8904_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */ +#define WM8904_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */ +#define WM8904_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */ +#define WM8904_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */ +#define WM8904_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */ +#define WM8904_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */ +#define WM8904_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */ + +/* + * R42 (0x2A) - DRC 2 + */ +#define WM8904_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */ +#define WM8904_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */ +#define WM8904_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */ +#define WM8904_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */ +#define WM8904_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */ +#define WM8904_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */ + +/* + * R43 (0x2B) - DRC 3 + */ +#define WM8904_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */ +#define WM8904_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */ +#define WM8904_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */ +#define WM8904_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */ +#define WM8904_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */ +#define WM8904_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */ + +/* + * R44 (0x2C) - Analogue Left Input 0 + */ +#define WM8904_LINMUTE 0x0080 /* LINMUTE */ +#define WM8904_LINMUTE_MASK 0x0080 /* LINMUTE */ +#define WM8904_LINMUTE_SHIFT 7 /* LINMUTE */ +#define WM8904_LINMUTE_WIDTH 1 /* LINMUTE */ +#define WM8904_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */ +#define WM8904_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */ +#define WM8904_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */ + +/* + * R45 (0x2D) - Analogue Right Input 0 + */ +#define WM8904_RINMUTE 0x0080 /* RINMUTE */ +#define WM8904_RINMUTE_MASK 0x0080 /* RINMUTE */ +#define WM8904_RINMUTE_SHIFT 7 /* RINMUTE */ +#define WM8904_RINMUTE_WIDTH 1 /* RINMUTE */ +#define WM8904_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */ +#define WM8904_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */ +#define WM8904_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */ + +/* + * R46 (0x2E) - Analogue Left Input 1 + */ +#define WM8904_INL_CM_ENA 0x0040 /* INL_CM_ENA */ +#define WM8904_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */ +#define WM8904_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */ +#define WM8904_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */ +#define WM8904_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */ +#define WM8904_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */ +#define WM8904_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */ +#define WM8904_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */ +#define WM8904_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */ +#define WM8904_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */ +#define WM8904_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */ +#define WM8904_L_MODE_SHIFT 0 /* L_MODE - [1:0] */ +#define WM8904_L_MODE_WIDTH 2 /* L_MODE - [1:0] */ + +/* + * R47 (0x2F) - Analogue Right Input 1 + */ +#define WM8904_INR_CM_ENA 0x0040 /* INR_CM_ENA */ +#define WM8904_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */ +#define WM8904_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */ +#define WM8904_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */ +#define WM8904_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */ +#define WM8904_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */ +#define WM8904_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */ +#define WM8904_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */ +#define WM8904_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */ +#define WM8904_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */ +#define WM8904_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */ +#define WM8904_R_MODE_SHIFT 0 /* R_MODE - [1:0] */ +#define WM8904_R_MODE_WIDTH 2 /* R_MODE - [1:0] */ + +/* + * R57 (0x39) - Analogue OUT1 Left + */ +#define WM8904_HPOUTL_MUTE 0x0100 /* HPOUTL_MUTE */ +#define WM8904_HPOUTL_MUTE_MASK 0x0100 /* HPOUTL_MUTE */ +#define WM8904_HPOUTL_MUTE_SHIFT 8 /* HPOUTL_MUTE */ +#define WM8904_HPOUTL_MUTE_WIDTH 1 /* HPOUTL_MUTE */ +#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */ +#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */ +#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */ +#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */ +#define WM8904_HPOUTLZC 0x0040 /* HPOUTLZC */ +#define WM8904_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */ +#define WM8904_HPOUTLZC_SHIFT 6 /* HPOUTLZC */ +#define WM8904_HPOUTLZC_WIDTH 1 /* HPOUTLZC */ +#define WM8904_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */ +#define WM8904_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */ +#define WM8904_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */ + +/* + * R58 (0x3A) - Analogue OUT1 Right + */ +#define WM8904_HPOUTR_MUTE 0x0100 /* HPOUTR_MUTE */ +#define WM8904_HPOUTR_MUTE_MASK 0x0100 /* HPOUTR_MUTE */ +#define WM8904_HPOUTR_MUTE_SHIFT 8 /* HPOUTR_MUTE */ +#define WM8904_HPOUTR_MUTE_WIDTH 1 /* HPOUTR_MUTE */ +#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */ +#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */ +#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */ +#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */ +#define WM8904_HPOUTRZC 0x0040 /* HPOUTRZC */ +#define WM8904_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */ +#define WM8904_HPOUTRZC_SHIFT 6 /* HPOUTRZC */ +#define WM8904_HPOUTRZC_WIDTH 1 /* HPOUTRZC */ +#define WM8904_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */ +#define WM8904_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */ +#define WM8904_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */ + +/* + * R59 (0x3B) - Analogue OUT2 Left + */ +#define WM8904_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */ +#define WM8904_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */ +#define WM8904_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */ +#define WM8904_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */ +#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */ +#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */ +#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */ +#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */ +#define WM8904_LINEOUTLZC 0x0040 /* LINEOUTLZC */ +#define WM8904_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */ +#define WM8904_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */ +#define WM8904_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */ +#define WM8904_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */ +#define WM8904_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */ +#define WM8904_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */ + +/* + * R60 (0x3C) - Analogue OUT2 Right + */ +#define WM8904_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */ +#define WM8904_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */ +#define WM8904_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */ +#define WM8904_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */ +#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */ +#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */ +#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */ +#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */ +#define WM8904_LINEOUTRZC 0x0040 /* LINEOUTRZC */ +#define WM8904_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */ +#define WM8904_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */ +#define WM8904_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */ +#define WM8904_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */ +#define WM8904_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */ +#define WM8904_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */ + +/* + * R61 (0x3D) - Analogue OUT12 ZC + */ +#define WM8904_HPL_BYP_ENA 0x0008 /* HPL_BYP_ENA */ +#define WM8904_HPL_BYP_ENA_MASK 0x0008 /* HPL_BYP_ENA */ +#define WM8904_HPL_BYP_ENA_SHIFT 3 /* HPL_BYP_ENA */ +#define WM8904_HPL_BYP_ENA_WIDTH 1 /* HPL_BYP_ENA */ +#define WM8904_HPR_BYP_ENA 0x0004 /* HPR_BYP_ENA */ +#define WM8904_HPR_BYP_ENA_MASK 0x0004 /* HPR_BYP_ENA */ +#define WM8904_HPR_BYP_ENA_SHIFT 2 /* HPR_BYP_ENA */ +#define WM8904_HPR_BYP_ENA_WIDTH 1 /* HPR_BYP_ENA */ +#define WM8904_LINEOUTL_BYP_ENA 0x0002 /* LINEOUTL_BYP_ENA */ +#define WM8904_LINEOUTL_BYP_ENA_MASK 0x0002 /* LINEOUTL_BYP_ENA */ +#define WM8904_LINEOUTL_BYP_ENA_SHIFT 1 /* LINEOUTL_BYP_ENA */ +#define WM8904_LINEOUTL_BYP_ENA_WIDTH 1 /* LINEOUTL_BYP_ENA */ +#define WM8904_LINEOUTR_BYP_ENA 0x0001 /* LINEOUTR_BYP_ENA */ +#define WM8904_LINEOUTR_BYP_ENA_MASK 0x0001 /* LINEOUTR_BYP_ENA */ +#define WM8904_LINEOUTR_BYP_ENA_SHIFT 0 /* LINEOUTR_BYP_ENA */ +#define WM8904_LINEOUTR_BYP_ENA_WIDTH 1 /* LINEOUTR_BYP_ENA */ + +/* + * R67 (0x43) - DC Servo 0 + */ +#define WM8904_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8904_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8904_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */ +#define WM8904_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */ +#define WM8904_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8904_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8904_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */ +#define WM8904_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */ +#define WM8904_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8904_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8904_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */ +#define WM8904_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */ +#define WM8904_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8904_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8904_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */ +#define WM8904_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */ + +/* + * R68 (0x44) - DC Servo 1 + */ +#define WM8904_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8904_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8904_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */ +#define WM8904_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */ +#define WM8904_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8904_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8904_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */ +#define WM8904_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */ +#define WM8904_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8904_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8904_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */ +#define WM8904_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */ +#define WM8904_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8904_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8904_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */ +#define WM8904_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */ +#define WM8904_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8904_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8904_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */ +#define WM8904_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */ +#define WM8904_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8904_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8904_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */ +#define WM8904_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */ +#define WM8904_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8904_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8904_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */ +#define WM8904_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */ +#define WM8904_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8904_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8904_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */ +#define WM8904_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */ +#define WM8904_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8904_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8904_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */ +#define WM8904_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */ +#define WM8904_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8904_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8904_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */ +#define WM8904_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */ +#define WM8904_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8904_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8904_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */ +#define WM8904_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */ +#define WM8904_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8904_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8904_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */ +#define WM8904_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */ +#define WM8904_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8904_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8904_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */ +#define WM8904_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */ +#define WM8904_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8904_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8904_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */ +#define WM8904_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */ +#define WM8904_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8904_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8904_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8904_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8904_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8904_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8904_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */ +#define WM8904_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */ + +/* + * R69 (0x45) - DC Servo 2 + */ +#define WM8904_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8904_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8904_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8904_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8904_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8904_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */ + +/* + * R71 (0x47) - DC Servo 4 + */ +#define WM8904_DCS_SERIES_NO_23_MASK 0x007F /* DCS_SERIES_NO_23 - [6:0] */ +#define WM8904_DCS_SERIES_NO_23_SHIFT 0 /* DCS_SERIES_NO_23 - [6:0] */ +#define WM8904_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [6:0] */ + +/* + * R72 (0x48) - DC Servo 5 + */ +#define WM8904_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8904_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8904_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */ + +/* + * R73 (0x49) - DC Servo 6 + */ +#define WM8904_DCS_DAC_WR_VAL_3_MASK 0x00FF /* DCS_DAC_WR_VAL_3 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_3_SHIFT 0 /* DCS_DAC_WR_VAL_3 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [7:0] */ + +/* + * R74 (0x4A) - DC Servo 7 + */ +#define WM8904_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */ + +/* + * R75 (0x4B) - DC Servo 8 + */ +#define WM8904_DCS_DAC_WR_VAL_1_MASK 0x00FF /* DCS_DAC_WR_VAL_1 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_1_SHIFT 0 /* DCS_DAC_WR_VAL_1 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [7:0] */ + +/* + * R76 (0x4C) - DC Servo 9 + */ +#define WM8904_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8904_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */ + +/* + * R77 (0x4D) - DC Servo Readback 0 + */ +#define WM8904_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8904_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8904_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8904_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8904_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8904_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8904_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8904_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8904_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */ + +/* + * R90 (0x5A) - Analogue HP 0 + */ +#define WM8904_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */ +#define WM8904_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */ +#define WM8904_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */ +#define WM8904_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */ +#define WM8904_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */ +#define WM8904_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */ +#define WM8904_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */ +#define WM8904_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */ +#define WM8904_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */ +#define WM8904_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */ +#define WM8904_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */ +#define WM8904_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */ +#define WM8904_HPL_ENA 0x0010 /* HPL_ENA */ +#define WM8904_HPL_ENA_MASK 0x0010 /* HPL_ENA */ +#define WM8904_HPL_ENA_SHIFT 4 /* HPL_ENA */ +#define WM8904_HPL_ENA_WIDTH 1 /* HPL_ENA */ +#define WM8904_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */ +#define WM8904_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */ +#define WM8904_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */ +#define WM8904_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */ +#define WM8904_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */ +#define WM8904_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */ +#define WM8904_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */ +#define WM8904_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */ +#define WM8904_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */ +#define WM8904_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */ +#define WM8904_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */ +#define WM8904_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */ +#define WM8904_HPR_ENA 0x0001 /* HPR_ENA */ +#define WM8904_HPR_ENA_MASK 0x0001 /* HPR_ENA */ +#define WM8904_HPR_ENA_SHIFT 0 /* HPR_ENA */ +#define WM8904_HPR_ENA_WIDTH 1 /* HPR_ENA */ + +/* + * R94 (0x5E) - Analogue Lineout 0 + */ +#define WM8904_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */ +#define WM8904_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */ +#define WM8904_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */ +#define WM8904_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */ +#define WM8904_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */ +#define WM8904_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */ +#define WM8904_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */ +#define WM8904_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */ +#define WM8904_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */ +#define WM8904_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */ +#define WM8904_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */ +#define WM8904_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */ +#define WM8904_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */ +#define WM8904_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */ +#define WM8904_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */ +#define WM8904_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */ +#define WM8904_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */ +#define WM8904_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */ +#define WM8904_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */ +#define WM8904_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */ +#define WM8904_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */ +#define WM8904_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */ +#define WM8904_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */ +#define WM8904_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */ +#define WM8904_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */ +#define WM8904_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */ +#define WM8904_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */ +#define WM8904_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */ +#define WM8904_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */ +#define WM8904_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */ +#define WM8904_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */ +#define WM8904_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */ + +/* + * R98 (0x62) - Charge Pump 0 + */ +#define WM8904_CP_ENA 0x0001 /* CP_ENA */ +#define WM8904_CP_ENA_MASK 0x0001 /* CP_ENA */ +#define WM8904_CP_ENA_SHIFT 0 /* CP_ENA */ +#define WM8904_CP_ENA_WIDTH 1 /* CP_ENA */ + +/* + * R104 (0x68) - Class W 0 + */ +#define WM8904_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */ +#define WM8904_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */ +#define WM8904_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */ +#define WM8904_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */ + +/* + * R108 (0x6C) - Write Sequencer 0 + */ +#define WM8904_WSEQ_ENA 0x0100 /* WSEQ_ENA */ +#define WM8904_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */ +#define WM8904_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */ +#define WM8904_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ +#define WM8904_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */ +#define WM8904_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */ +#define WM8904_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */ + +/* + * R109 (0x6D) - Write Sequencer 1 + */ +#define WM8904_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */ +#define WM8904_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */ +#define WM8904_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */ +#define WM8904_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */ +#define WM8904_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */ +#define WM8904_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */ +#define WM8904_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */ +#define WM8904_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */ +#define WM8904_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */ + +/* + * R110 (0x6E) - Write Sequencer 2 + */ +#define WM8904_WSEQ_EOS 0x4000 /* WSEQ_EOS */ +#define WM8904_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */ +#define WM8904_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */ +#define WM8904_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */ +#define WM8904_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */ +#define WM8904_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */ +#define WM8904_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */ +#define WM8904_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */ +#define WM8904_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */ +#define WM8904_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */ + +/* + * R111 (0x6F) - Write Sequencer 3 + */ +#define WM8904_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ +#define WM8904_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ +#define WM8904_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ +#define WM8904_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ +#define WM8904_WSEQ_START 0x0100 /* WSEQ_START */ +#define WM8904_WSEQ_START_MASK 0x0100 /* WSEQ_START */ +#define WM8904_WSEQ_START_SHIFT 8 /* WSEQ_START */ +#define WM8904_WSEQ_START_WIDTH 1 /* WSEQ_START */ +#define WM8904_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */ +#define WM8904_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */ +#define WM8904_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */ + +/* + * R112 (0x70) - Write Sequencer 4 + */ +#define WM8904_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */ +#define WM8904_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */ +#define WM8904_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */ +#define WM8904_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */ +#define WM8904_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */ +#define WM8904_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */ +#define WM8904_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ + +/* + * R116 (0x74) - FLL Control 1 + */ +#define WM8904_FLL_FRACN_ENA 0x0004 /* FLL_FRACN_ENA */ +#define WM8904_FLL_FRACN_ENA_MASK 0x0004 /* FLL_FRACN_ENA */ +#define WM8904_FLL_FRACN_ENA_SHIFT 2 /* FLL_FRACN_ENA */ +#define WM8904_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */ +#define WM8904_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */ +#define WM8904_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */ +#define WM8904_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */ +#define WM8904_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */ +#define WM8904_FLL_ENA 0x0001 /* FLL_ENA */ +#define WM8904_FLL_ENA_MASK 0x0001 /* FLL_ENA */ +#define WM8904_FLL_ENA_SHIFT 0 /* FLL_ENA */ +#define WM8904_FLL_ENA_WIDTH 1 /* FLL_ENA */ + +/* + * R117 (0x75) - FLL Control 2 + */ +#define WM8904_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */ +#define WM8904_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */ +#define WM8904_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */ +#define WM8904_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */ +#define WM8904_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */ +#define WM8904_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */ +#define WM8904_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ +#define WM8904_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ +#define WM8904_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ + +/* + * R118 (0x76) - FLL Control 3 + */ +#define WM8904_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */ +#define WM8904_FLL_K_SHIFT 0 /* FLL_K - [15:0] */ +#define WM8904_FLL_K_WIDTH 16 /* FLL_K - [15:0] */ + +/* + * R119 (0x77) - FLL Control 4 + */ +#define WM8904_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */ +#define WM8904_FLL_N_SHIFT 5 /* FLL_N - [14:5] */ +#define WM8904_FLL_N_WIDTH 10 /* FLL_N - [14:5] */ +#define WM8904_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */ +#define WM8904_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */ +#define WM8904_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */ + +/* + * R120 (0x78) - FLL Control 5 + */ +#define WM8904_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */ +#define WM8904_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */ +#define WM8904_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */ +#define WM8904_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */ +#define WM8904_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */ +#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */ + +/* + * R121 (0x79) - GPIO Control 1 + */ +#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */ +#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */ +#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */ +#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */ +#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */ +#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */ +#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */ +#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */ +#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */ +#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */ +#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */ + +/* + * R122 (0x7A) - GPIO Control 2 + */ +#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */ +#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */ +#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */ +#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */ +#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */ +#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */ +#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */ +#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */ +#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */ +#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */ +#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */ + +/* + * R123 (0x7B) - GPIO Control 3 + */ +#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */ +#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */ +#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */ +#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */ +#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */ +#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */ +#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */ +#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */ +#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */ +#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */ +#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */ + +/* + * R124 (0x7C) - GPIO Control 4 + */ +#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */ +#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */ +#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */ +#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */ +#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */ +#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */ +#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */ +#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */ +#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */ +#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */ +#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */ +#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */ +#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */ +#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */ +#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */ + +/* + * R126 (0x7E) - Digital Pulls + */ +#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */ +#define WM8904_MCLK_PU_MASK 0x0080 /* MCLK_PU */ +#define WM8904_MCLK_PU_SHIFT 7 /* MCLK_PU */ +#define WM8904_MCLK_PU_WIDTH 1 /* MCLK_PU */ +#define WM8904_MCLK_PD 0x0040 /* MCLK_PD */ +#define WM8904_MCLK_PD_MASK 0x0040 /* MCLK_PD */ +#define WM8904_MCLK_PD_SHIFT 6 /* MCLK_PD */ +#define WM8904_MCLK_PD_WIDTH 1 /* MCLK_PD */ +#define WM8904_DACDAT_PU 0x0020 /* DACDAT_PU */ +#define WM8904_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */ +#define WM8904_DACDAT_PU_SHIFT 5 /* DACDAT_PU */ +#define WM8904_DACDAT_PU_WIDTH 1 /* DACDAT_PU */ +#define WM8904_DACDAT_PD 0x0010 /* DACDAT_PD */ +#define WM8904_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */ +#define WM8904_DACDAT_PD_SHIFT 4 /* DACDAT_PD */ +#define WM8904_DACDAT_PD_WIDTH 1 /* DACDAT_PD */ +#define WM8904_LRCLK_PU 0x0008 /* LRCLK_PU */ +#define WM8904_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */ +#define WM8904_LRCLK_PU_SHIFT 3 /* LRCLK_PU */ +#define WM8904_LRCLK_PU_WIDTH 1 /* LRCLK_PU */ +#define WM8904_LRCLK_PD 0x0004 /* LRCLK_PD */ +#define WM8904_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */ +#define WM8904_LRCLK_PD_SHIFT 2 /* LRCLK_PD */ +#define WM8904_LRCLK_PD_WIDTH 1 /* LRCLK_PD */ +#define WM8904_BCLK_PU 0x0002 /* BCLK_PU */ +#define WM8904_BCLK_PU_MASK 0x0002 /* BCLK_PU */ +#define WM8904_BCLK_PU_SHIFT 1 /* BCLK_PU */ +#define WM8904_BCLK_PU_WIDTH 1 /* BCLK_PU */ +#define WM8904_BCLK_PD 0x0001 /* BCLK_PD */ +#define WM8904_BCLK_PD_MASK 0x0001 /* BCLK_PD */ +#define WM8904_BCLK_PD_SHIFT 0 /* BCLK_PD */ +#define WM8904_BCLK_PD_WIDTH 1 /* BCLK_PD */ + +/* + * R127 (0x7F) - Interrupt Status + */ +#define WM8904_IRQ 0x0400 /* IRQ */ +#define WM8904_IRQ_MASK 0x0400 /* IRQ */ +#define WM8904_IRQ_SHIFT 10 /* IRQ */ +#define WM8904_IRQ_WIDTH 1 /* IRQ */ +#define WM8904_GPIO_BCLK_EINT 0x0200 /* GPIO_BCLK_EINT */ +#define WM8904_GPIO_BCLK_EINT_MASK 0x0200 /* GPIO_BCLK_EINT */ +#define WM8904_GPIO_BCLK_EINT_SHIFT 9 /* GPIO_BCLK_EINT */ +#define WM8904_GPIO_BCLK_EINT_WIDTH 1 /* GPIO_BCLK_EINT */ +#define WM8904_WSEQ_EINT 0x0100 /* WSEQ_EINT */ +#define WM8904_WSEQ_EINT_MASK 0x0100 /* WSEQ_EINT */ +#define WM8904_WSEQ_EINT_SHIFT 8 /* WSEQ_EINT */ +#define WM8904_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */ +#define WM8904_GPIO3_EINT 0x0080 /* GPIO3_EINT */ +#define WM8904_GPIO3_EINT_MASK 0x0080 /* GPIO3_EINT */ +#define WM8904_GPIO3_EINT_SHIFT 7 /* GPIO3_EINT */ +#define WM8904_GPIO3_EINT_WIDTH 1 /* GPIO3_EINT */ +#define WM8904_GPIO2_EINT 0x0040 /* GPIO2_EINT */ +#define WM8904_GPIO2_EINT_MASK 0x0040 /* GPIO2_EINT */ +#define WM8904_GPIO2_EINT_SHIFT 6 /* GPIO2_EINT */ +#define WM8904_GPIO2_EINT_WIDTH 1 /* GPIO2_EINT */ +#define WM8904_GPIO1_EINT 0x0020 /* GPIO1_EINT */ +#define WM8904_GPIO1_EINT_MASK 0x0020 /* GPIO1_EINT */ +#define WM8904_GPIO1_EINT_SHIFT 5 /* GPIO1_EINT */ +#define WM8904_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */ +#define WM8904_GPI8_EINT 0x0010 /* GPI8_EINT */ +#define WM8904_GPI8_EINT_MASK 0x0010 /* GPI8_EINT */ +#define WM8904_GPI8_EINT_SHIFT 4 /* GPI8_EINT */ +#define WM8904_GPI8_EINT_WIDTH 1 /* GPI8_EINT */ +#define WM8904_GPI7_EINT 0x0008 /* GPI7_EINT */ +#define WM8904_GPI7_EINT_MASK 0x0008 /* GPI7_EINT */ +#define WM8904_GPI7_EINT_SHIFT 3 /* GPI7_EINT */ +#define WM8904_GPI7_EINT_WIDTH 1 /* GPI7_EINT */ +#define WM8904_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */ +#define WM8904_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */ +#define WM8904_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */ +#define WM8904_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */ +#define WM8904_MIC_SHRT_EINT 0x0002 /* MIC_SHRT_EINT */ +#define WM8904_MIC_SHRT_EINT_MASK 0x0002 /* MIC_SHRT_EINT */ +#define WM8904_MIC_SHRT_EINT_SHIFT 1 /* MIC_SHRT_EINT */ +#define WM8904_MIC_SHRT_EINT_WIDTH 1 /* MIC_SHRT_EINT */ +#define WM8904_MIC_DET_EINT 0x0001 /* MIC_DET_EINT */ +#define WM8904_MIC_DET_EINT_MASK 0x0001 /* MIC_DET_EINT */ +#define WM8904_MIC_DET_EINT_SHIFT 0 /* MIC_DET_EINT */ +#define WM8904_MIC_DET_EINT_WIDTH 1 /* MIC_DET_EINT */ + +/* + * R128 (0x80) - Interrupt Status Mask + */ +#define WM8904_IM_GPIO_BCLK_EINT 0x0200 /* IM_GPIO_BCLK_EINT */ +#define WM8904_IM_GPIO_BCLK_EINT_MASK 0x0200 /* IM_GPIO_BCLK_EINT */ +#define WM8904_IM_GPIO_BCLK_EINT_SHIFT 9 /* IM_GPIO_BCLK_EINT */ +#define WM8904_IM_GPIO_BCLK_EINT_WIDTH 1 /* IM_GPIO_BCLK_EINT */ +#define WM8904_IM_WSEQ_EINT 0x0100 /* IM_WSEQ_EINT */ +#define WM8904_IM_WSEQ_EINT_MASK 0x0100 /* IM_WSEQ_EINT */ +#define WM8904_IM_WSEQ_EINT_SHIFT 8 /* IM_WSEQ_EINT */ +#define WM8904_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */ +#define WM8904_IM_GPIO3_EINT 0x0080 /* IM_GPIO3_EINT */ +#define WM8904_IM_GPIO3_EINT_MASK 0x0080 /* IM_GPIO3_EINT */ +#define WM8904_IM_GPIO3_EINT_SHIFT 7 /* IM_GPIO3_EINT */ +#define WM8904_IM_GPIO3_EINT_WIDTH 1 /* IM_GPIO3_EINT */ +#define WM8904_IM_GPIO2_EINT 0x0040 /* IM_GPIO2_EINT */ +#define WM8904_IM_GPIO2_EINT_MASK 0x0040 /* IM_GPIO2_EINT */ +#define WM8904_IM_GPIO2_EINT_SHIFT 6 /* IM_GPIO2_EINT */ +#define WM8904_IM_GPIO2_EINT_WIDTH 1 /* IM_GPIO2_EINT */ +#define WM8904_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */ +#define WM8904_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */ +#define WM8904_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */ +#define WM8904_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */ +#define WM8904_IM_GPI8_EINT 0x0010 /* IM_GPI8_EINT */ +#define WM8904_IM_GPI8_EINT_MASK 0x0010 /* IM_GPI8_EINT */ +#define WM8904_IM_GPI8_EINT_SHIFT 4 /* IM_GPI8_EINT */ +#define WM8904_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */ +#define WM8904_IM_GPI7_EINT 0x0008 /* IM_GPI7_EINT */ +#define WM8904_IM_GPI7_EINT_MASK 0x0008 /* IM_GPI7_EINT */ +#define WM8904_IM_GPI7_EINT_SHIFT 3 /* IM_GPI7_EINT */ +#define WM8904_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */ +#define WM8904_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */ +#define WM8904_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */ +#define WM8904_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */ +#define WM8904_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */ +#define WM8904_IM_MIC_SHRT_EINT 0x0002 /* IM_MIC_SHRT_EINT */ +#define WM8904_IM_MIC_SHRT_EINT_MASK 0x0002 /* IM_MIC_SHRT_EINT */ +#define WM8904_IM_MIC_SHRT_EINT_SHIFT 1 /* IM_MIC_SHRT_EINT */ +#define WM8904_IM_MIC_SHRT_EINT_WIDTH 1 /* IM_MIC_SHRT_EINT */ +#define WM8904_IM_MIC_DET_EINT 0x0001 /* IM_MIC_DET_EINT */ +#define WM8904_IM_MIC_DET_EINT_MASK 0x0001 /* IM_MIC_DET_EINT */ +#define WM8904_IM_MIC_DET_EINT_SHIFT 0 /* IM_MIC_DET_EINT */ +#define WM8904_IM_MIC_DET_EINT_WIDTH 1 /* IM_MIC_DET_EINT */ + +/* + * R129 (0x81) - Interrupt Polarity + */ +#define WM8904_GPIO_BCLK_EINT_POL 0x0200 /* GPIO_BCLK_EINT_POL */ +#define WM8904_GPIO_BCLK_EINT_POL_MASK 0x0200 /* GPIO_BCLK_EINT_POL */ +#define WM8904_GPIO_BCLK_EINT_POL_SHIFT 9 /* GPIO_BCLK_EINT_POL */ +#define WM8904_GPIO_BCLK_EINT_POL_WIDTH 1 /* GPIO_BCLK_EINT_POL */ +#define WM8904_WSEQ_EINT_POL 0x0100 /* WSEQ_EINT_POL */ +#define WM8904_WSEQ_EINT_POL_MASK 0x0100 /* WSEQ_EINT_POL */ +#define WM8904_WSEQ_EINT_POL_SHIFT 8 /* WSEQ_EINT_POL */ +#define WM8904_WSEQ_EINT_POL_WIDTH 1 /* WSEQ_EINT_POL */ +#define WM8904_GPIO3_EINT_POL 0x0080 /* GPIO3_EINT_POL */ +#define WM8904_GPIO3_EINT_POL_MASK 0x0080 /* GPIO3_EINT_POL */ +#define WM8904_GPIO3_EINT_POL_SHIFT 7 /* GPIO3_EINT_POL */ +#define WM8904_GPIO3_EINT_POL_WIDTH 1 /* GPIO3_EINT_POL */ +#define WM8904_GPIO2_EINT_POL 0x0040 /* GPIO2_EINT_POL */ +#define WM8904_GPIO2_EINT_POL_MASK 0x0040 /* GPIO2_EINT_POL */ +#define WM8904_GPIO2_EINT_POL_SHIFT 6 /* GPIO2_EINT_POL */ +#define WM8904_GPIO2_EINT_POL_WIDTH 1 /* GPIO2_EINT_POL */ +#define WM8904_GPIO1_EINT_POL 0x0020 /* GPIO1_EINT_POL */ +#define WM8904_GPIO1_EINT_POL_MASK 0x0020 /* GPIO1_EINT_POL */ +#define WM8904_GPIO1_EINT_POL_SHIFT 5 /* GPIO1_EINT_POL */ +#define WM8904_GPIO1_EINT_POL_WIDTH 1 /* GPIO1_EINT_POL */ +#define WM8904_GPI8_EINT_POL 0x0010 /* GPI8_EINT_POL */ +#define WM8904_GPI8_EINT_POL_MASK 0x0010 /* GPI8_EINT_POL */ +#define WM8904_GPI8_EINT_POL_SHIFT 4 /* GPI8_EINT_POL */ +#define WM8904_GPI8_EINT_POL_WIDTH 1 /* GPI8_EINT_POL */ +#define WM8904_GPI7_EINT_POL 0x0008 /* GPI7_EINT_POL */ +#define WM8904_GPI7_EINT_POL_MASK 0x0008 /* GPI7_EINT_POL */ +#define WM8904_GPI7_EINT_POL_SHIFT 3 /* GPI7_EINT_POL */ +#define WM8904_GPI7_EINT_POL_WIDTH 1 /* GPI7_EINT_POL */ +#define WM8904_FLL_LOCK_EINT_POL 0x0004 /* FLL_LOCK_EINT_POL */ +#define WM8904_FLL_LOCK_EINT_POL_MASK 0x0004 /* FLL_LOCK_EINT_POL */ +#define WM8904_FLL_LOCK_EINT_POL_SHIFT 2 /* FLL_LOCK_EINT_POL */ +#define WM8904_FLL_LOCK_EINT_POL_WIDTH 1 /* FLL_LOCK_EINT_POL */ +#define WM8904_MIC_SHRT_EINT_POL 0x0002 /* MIC_SHRT_EINT_POL */ +#define WM8904_MIC_SHRT_EINT_POL_MASK 0x0002 /* MIC_SHRT_EINT_POL */ +#define WM8904_MIC_SHRT_EINT_POL_SHIFT 1 /* MIC_SHRT_EINT_POL */ +#define WM8904_MIC_SHRT_EINT_POL_WIDTH 1 /* MIC_SHRT_EINT_POL */ +#define WM8904_MIC_DET_EINT_POL 0x0001 /* MIC_DET_EINT_POL */ +#define WM8904_MIC_DET_EINT_POL_MASK 0x0001 /* MIC_DET_EINT_POL */ +#define WM8904_MIC_DET_EINT_POL_SHIFT 0 /* MIC_DET_EINT_POL */ +#define WM8904_MIC_DET_EINT_POL_WIDTH 1 /* MIC_DET_EINT_POL */ + +/* + * R130 (0x82) - Interrupt Debounce + */ +#define WM8904_GPIO_BCLK_EINT_DB 0x0200 /* GPIO_BCLK_EINT_DB */ +#define WM8904_GPIO_BCLK_EINT_DB_MASK 0x0200 /* GPIO_BCLK_EINT_DB */ +#define WM8904_GPIO_BCLK_EINT_DB_SHIFT 9 /* GPIO_BCLK_EINT_DB */ +#define WM8904_GPIO_BCLK_EINT_DB_WIDTH 1 /* GPIO_BCLK_EINT_DB */ +#define WM8904_WSEQ_EINT_DB 0x0100 /* WSEQ_EINT_DB */ +#define WM8904_WSEQ_EINT_DB_MASK 0x0100 /* WSEQ_EINT_DB */ +#define WM8904_WSEQ_EINT_DB_SHIFT 8 /* WSEQ_EINT_DB */ +#define WM8904_WSEQ_EINT_DB_WIDTH 1 /* WSEQ_EINT_DB */ +#define WM8904_GPIO3_EINT_DB 0x0080 /* GPIO3_EINT_DB */ +#define WM8904_GPIO3_EINT_DB_MASK 0x0080 /* GPIO3_EINT_DB */ +#define WM8904_GPIO3_EINT_DB_SHIFT 7 /* GPIO3_EINT_DB */ +#define WM8904_GPIO3_EINT_DB_WIDTH 1 /* GPIO3_EINT_DB */ +#define WM8904_GPIO2_EINT_DB 0x0040 /* GPIO2_EINT_DB */ +#define WM8904_GPIO2_EINT_DB_MASK 0x0040 /* GPIO2_EINT_DB */ +#define WM8904_GPIO2_EINT_DB_SHIFT 6 /* GPIO2_EINT_DB */ +#define WM8904_GPIO2_EINT_DB_WIDTH 1 /* GPIO2_EINT_DB */ +#define WM8904_GPIO1_EINT_DB 0x0020 /* GPIO1_EINT_DB */ +#define WM8904_GPIO1_EINT_DB_MASK 0x0020 /* GPIO1_EINT_DB */ +#define WM8904_GPIO1_EINT_DB_SHIFT 5 /* GPIO1_EINT_DB */ +#define WM8904_GPIO1_EINT_DB_WIDTH 1 /* GPIO1_EINT_DB */ +#define WM8904_GPI8_EINT_DB 0x0010 /* GPI8_EINT_DB */ +#define WM8904_GPI8_EINT_DB_MASK 0x0010 /* GPI8_EINT_DB */ +#define WM8904_GPI8_EINT_DB_SHIFT 4 /* GPI8_EINT_DB */ +#define WM8904_GPI8_EINT_DB_WIDTH 1 /* GPI8_EINT_DB */ +#define WM8904_GPI7_EINT_DB 0x0008 /* GPI7_EINT_DB */ +#define WM8904_GPI7_EINT_DB_MASK 0x0008 /* GPI7_EINT_DB */ +#define WM8904_GPI7_EINT_DB_SHIFT 3 /* GPI7_EINT_DB */ +#define WM8904_GPI7_EINT_DB_WIDTH 1 /* GPI7_EINT_DB */ +#define WM8904_FLL_LOCK_EINT_DB 0x0004 /* FLL_LOCK_EINT_DB */ +#define WM8904_FLL_LOCK_EINT_DB_MASK 0x0004 /* FLL_LOCK_EINT_DB */ +#define WM8904_FLL_LOCK_EINT_DB_SHIFT 2 /* FLL_LOCK_EINT_DB */ +#define WM8904_FLL_LOCK_EINT_DB_WIDTH 1 /* FLL_LOCK_EINT_DB */ +#define WM8904_MIC_SHRT_EINT_DB 0x0002 /* MIC_SHRT_EINT_DB */ +#define WM8904_MIC_SHRT_EINT_DB_MASK 0x0002 /* MIC_SHRT_EINT_DB */ +#define WM8904_MIC_SHRT_EINT_DB_SHIFT 1 /* MIC_SHRT_EINT_DB */ +#define WM8904_MIC_SHRT_EINT_DB_WIDTH 1 /* MIC_SHRT_EINT_DB */ +#define WM8904_MIC_DET_EINT_DB 0x0001 /* MIC_DET_EINT_DB */ +#define WM8904_MIC_DET_EINT_DB_MASK 0x0001 /* MIC_DET_EINT_DB */ +#define WM8904_MIC_DET_EINT_DB_SHIFT 0 /* MIC_DET_EINT_DB */ +#define WM8904_MIC_DET_EINT_DB_WIDTH 1 /* MIC_DET_EINT_DB */ + +/* + * R134 (0x86) - EQ1 + */ +#define WM8904_EQ_ENA 0x0001 /* EQ_ENA */ +#define WM8904_EQ_ENA_MASK 0x0001 /* EQ_ENA */ +#define WM8904_EQ_ENA_SHIFT 0 /* EQ_ENA */ +#define WM8904_EQ_ENA_WIDTH 1 /* EQ_ENA */ + +/* + * R135 (0x87) - EQ2 + */ +#define WM8904_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */ +#define WM8904_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */ +#define WM8904_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */ + +/* + * R136 (0x88) - EQ3 + */ +#define WM8904_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */ +#define WM8904_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */ +#define WM8904_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */ + +/* + * R137 (0x89) - EQ4 + */ +#define WM8904_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */ +#define WM8904_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */ +#define WM8904_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */ + +/* + * R138 (0x8A) - EQ5 + */ +#define WM8904_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */ +#define WM8904_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */ +#define WM8904_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */ + +/* + * R139 (0x8B) - EQ6 + */ +#define WM8904_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */ +#define WM8904_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */ +#define WM8904_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */ + +/* + * R140 (0x8C) - EQ7 + */ +#define WM8904_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */ +#define WM8904_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */ +#define WM8904_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */ + +/* + * R141 (0x8D) - EQ8 + */ +#define WM8904_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */ +#define WM8904_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */ +#define WM8904_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */ + +/* + * R142 (0x8E) - EQ9 + */ +#define WM8904_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */ +#define WM8904_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */ +#define WM8904_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */ + +/* + * R143 (0x8F) - EQ10 + */ +#define WM8904_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */ +#define WM8904_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */ +#define WM8904_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */ + +/* + * R144 (0x90) - EQ11 + */ +#define WM8904_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */ +#define WM8904_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */ +#define WM8904_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */ + +/* + * R145 (0x91) - EQ12 + */ +#define WM8904_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */ +#define WM8904_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */ +#define WM8904_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */ + +/* + * R146 (0x92) - EQ13 + */ +#define WM8904_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */ +#define WM8904_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */ +#define WM8904_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */ + +/* + * R147 (0x93) - EQ14 + */ +#define WM8904_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */ +#define WM8904_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */ +#define WM8904_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */ + +/* + * R148 (0x94) - EQ15 + */ +#define WM8904_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */ +#define WM8904_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */ +#define WM8904_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */ + +/* + * R149 (0x95) - EQ16 + */ +#define WM8904_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */ +#define WM8904_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */ +#define WM8904_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */ + +/* + * R150 (0x96) - EQ17 + */ +#define WM8904_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */ +#define WM8904_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */ +#define WM8904_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */ + +/* + * R151 (0x97) - EQ18 + */ +#define WM8904_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */ +#define WM8904_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */ +#define WM8904_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */ + +/* + * R152 (0x98) - EQ19 + */ +#define WM8904_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */ +#define WM8904_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */ +#define WM8904_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */ + +/* + * R153 (0x99) - EQ20 + */ +#define WM8904_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */ +#define WM8904_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */ +#define WM8904_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */ + +/* + * R154 (0x9A) - EQ21 + */ +#define WM8904_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */ +#define WM8904_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */ +#define WM8904_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */ + +/* + * R155 (0x9B) - EQ22 + */ +#define WM8904_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */ +#define WM8904_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */ +#define WM8904_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */ + +/* + * R156 (0x9C) - EQ23 + */ +#define WM8904_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */ +#define WM8904_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */ +#define WM8904_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */ + +/* + * R157 (0x9D) - EQ24 + */ +#define WM8904_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */ +#define WM8904_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */ +#define WM8904_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */ + +/* + * R161 (0xA1) - Control Interface Test 1 + */ +#define WM8904_USER_KEY 0x0002 /* USER_KEY */ +#define WM8904_USER_KEY_MASK 0x0002 /* USER_KEY */ +#define WM8904_USER_KEY_SHIFT 1 /* USER_KEY */ +#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */ + +/* + * R204 (0xCC) - Analogue Output Bias 0 + */ +#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */ +#define WM8904_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */ +#define WM8904_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */ + +/* + * R247 (0xF7) - FLL NCO Test 0 + */ +#define WM8904_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */ +#define WM8904_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */ +#define WM8904_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */ +#define WM8904_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */ + +/* + * R248 (0xF8) - FLL NCO Test 1 + */ +#define WM8904_FLL_FRC_NCO_VAL_MASK 0x003F /* FLL_FRC_NCO_VAL - [5:0] */ +#define WM8904_FLL_FRC_NCO_VAL_SHIFT 0 /* FLL_FRC_NCO_VAL - [5:0] */ +#define WM8904_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [5:0] */ + +#endif -- cgit v1.2.3 From 926a01ce1ef5e27281af0270e4476979c0522954 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 16 Dec 2009 16:15:00 +0100 Subject: ALSA: Release v1.0.22 Signed-off-by: Jaroslav Kysela --- include/sound/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/version.h b/include/sound/version.h index 22939142dd23..1f5d4872d623 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.21" +#define CONFIG_SND_VERSION "1.0.22" #define CONFIG_SND_DATE "" -- cgit v1.2.3 From 6c941c8556dd9269be621cd8159fc60e955a91b3 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 16 Dec 2009 16:15:00 +0100 Subject: ALSA: Release v1.0.22 Signed-off-by: Jaroslav Kysela Signed-off-by: Takashi Iwai --- include/sound/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/version.h b/include/sound/version.h index 22939142dd23..1f5d4872d623 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.21" +#define CONFIG_SND_VERSION "1.0.22" #define CONFIG_SND_DATE "" -- cgit v1.2.3 From 681b84e17747e1c208e8e1acc54cc5e612da84d1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 18 Dec 2009 09:29:00 +0100 Subject: sound: pcm: add vmalloc buffer helper functions There are now five copies of the code to allocate a PCM buffer using vmalloc(). Add a sixth in the core so that the others can be removed. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 38 ++++++++++++++++++++++++++++++++++ sound/core/pcm_memory.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index c83a4a79f16b..0ad2d28f2360 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -905,6 +905,44 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size); int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream); +int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, + size_t size, gfp_t gfp_flags); +int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream); +struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, + unsigned long offset); +#if 0 /* for kernel-doc */ +/** + * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer + * @substream: the substream to allocate the buffer to + * @size: the requested buffer size, in bytes + * + * Allocates the PCM substream buffer using vmalloc(), i.e., the memory is + * contiguous in kernel virtual space, but not in physical memory. Use this + * if the buffer is accessed by kernel code but not by device DMA. + * + * Returns 1 if the buffer was changed, 0 if not changed, or a negative error + * code. + */ +static int snd_pcm_lib_alloc_vmalloc_buffer + (struct snd_pcm_substream *substream, size_t size); +/** + * snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer + * @substream: the substream to allocate the buffer to + * @size: the requested buffer size, in bytes + * + * This function works like snd_pcm_lib_alloc_vmalloc_buffer(), but uses + * vmalloc_32(), i.e., the pages are allocated from 32-bit-addressable memory. + */ +static int snd_pcm_lib_alloc_vmalloc_32_buffer + (struct snd_pcm_substream *substream, size_t size); +#endif +#define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \ + _snd_pcm_lib_alloc_vmalloc_buffer \ + (subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO) +#define snd_pcm_lib_alloc_vmalloc_32_buffer(subs, size) \ + _snd_pcm_lib_alloc_vmalloc_buffer \ + (subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO) + #ifdef CONFIG_SND_DMA_SGBUF /* * SG-buffer handling diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index caa7796bc2f5..d9727c74b2e1 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -434,3 +434,57 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) } EXPORT_SYMBOL(snd_pcm_lib_free_pages); + +int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, + size_t size, gfp_t gfp_flags) +{ + struct snd_pcm_runtime *runtime; + + if (PCM_RUNTIME_CHECK(substream)) + return -EINVAL; + runtime = substream->runtime; + if (runtime->dma_area) { + if (runtime->dma_bytes >= size) + return 0; /* already large enough */ + vfree(runtime->dma_area); + } + runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL); + if (!runtime->dma_area) + return -ENOMEM; + runtime->dma_bytes = size; + return 1; +} +EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer); + +/** + * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer + * @substream: the substream with a buffer allocated by + * snd_pcm_lib_alloc_vmalloc_buffer() + */ +int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + + if (PCM_RUNTIME_CHECK(substream)) + return -EINVAL; + runtime = substream->runtime; + vfree(runtime->dma_area); + runtime->dma_area = NULL; + return 0; +} +EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer); + +/** + * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct + * @substream: the substream with a buffer allocated by + * snd_pcm_lib_alloc_vmalloc_buffer() + * @offset: offset in the buffer + * + * This function is to be used as the page callback in the PCM ops. + */ +struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, + unsigned long offset) +{ + return vmalloc_to_page(substream->runtime->dma_area + offset); +} +EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page); -- cgit v1.2.3 From b35a28af0a64a1e8e389bc009b76253256d8fe7b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 18 Dec 2009 12:00:22 +0000 Subject: ASoC: Add initial WM8955 CODEC driver The WM8955 is a low power, high quality stereo DAC with integrated headphone and loudspeaker amplifiers, designed to reduce external component requirements in portable digital audio applications. This is an initial driver implementing support for the majority of the functionality in the device, currently OUT3 is not supported. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/wm8955.h | 26 + sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8955.c | 1151 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8955.h | 489 +++++++++++++++++++ 5 files changed, 1672 insertions(+) create mode 100644 include/sound/wm8955.h create mode 100644 sound/soc/codecs/wm8955.c create mode 100644 sound/soc/codecs/wm8955.h (limited to 'include') diff --git a/include/sound/wm8955.h b/include/sound/wm8955.h new file mode 100644 index 000000000000..5074ef499f40 --- /dev/null +++ b/include/sound/wm8955.h @@ -0,0 +1,26 @@ +/* + * Platform data for WM8955 + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __WM8955_PDATA_H__ +#define __WM8955_PDATA_H__ + +struct wm8955_pdata { + /* Configure LOUT2/ROUT2 to drive a speaker */ + unsigned int out2_speaker:1; + + /* Configure MONOIN+/- in differential mode */ + unsigned int monoin_diff:1; +}; + +#endif diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 691abe7df087..62ff26a08a2f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -52,6 +52,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8903 if I2C select SND_SOC_WM8904 if I2C select SND_SOC_WM8940 if I2C + select SND_SOC_WM8955 if I2C select SND_SOC_WM8960 if I2C select SND_SOC_WM8961 if I2C select SND_SOC_WM8971 if I2C @@ -214,6 +215,9 @@ config SND_SOC_WM8904 config SND_SOC_WM8940 tristate +config SND_SOC_WM8955 + tristate + config SND_SOC_WM8960 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index c0fd3c86edad..ea9835412e6a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -39,6 +39,7 @@ snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8904-objs := wm8904.o snd-soc-wm8940-objs := wm8940.o +snd-soc-wm8955-objs := wm8955.o snd-soc-wm8960-objs := wm8960.o snd-soc-wm8961-objs := wm8961.o snd-soc-wm8971-objs := wm8971.o @@ -97,6 +98,7 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o +obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c new file mode 100644 index 000000000000..615dab2b62ef --- /dev/null +++ b/sound/soc/codecs/wm8955.c @@ -0,0 +1,1151 @@ +/* + * wm8955.c -- WM8955 ALSA SoC Audio driver + * + * Copyright 2009 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8955.h" + +static struct snd_soc_codec *wm8955_codec; +struct snd_soc_codec_device soc_codec_dev_wm8955; + +#define WM8955_NUM_SUPPLIES 4 +static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { + "DCVDD", + "DBVDD", + "HPVDD", + "AVDD", +}; + +/* codec private data */ +struct wm8955_priv { + struct snd_soc_codec codec; + u16 reg_cache[WM8955_MAX_REGISTER + 1]; + + unsigned int mclk_rate; + + int deemph; + int fs; + + struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; + + struct wm8955_pdata *pdata; +}; + +static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = { + 0x0000, /* R0 */ + 0x0000, /* R1 */ + 0x0079, /* R2 - LOUT1 volume */ + 0x0079, /* R3 - ROUT1 volume */ + 0x0000, /* R4 */ + 0x0008, /* R5 - DAC Control */ + 0x0000, /* R6 */ + 0x000A, /* R7 - Audio Interface */ + 0x0000, /* R8 - Sample Rate */ + 0x0000, /* R9 */ + 0x00FF, /* R10 - Left DAC volume */ + 0x00FF, /* R11 - Right DAC volume */ + 0x000F, /* R12 - Bass control */ + 0x000F, /* R13 - Treble control */ + 0x0000, /* R14 */ + 0x0000, /* R15 - Reset */ + 0x0000, /* R16 */ + 0x0000, /* R17 */ + 0x0000, /* R18 */ + 0x0000, /* R19 */ + 0x0000, /* R20 */ + 0x0000, /* R21 */ + 0x0000, /* R22 */ + 0x00C1, /* R23 - Additional control (1) */ + 0x0000, /* R24 - Additional control (2) */ + 0x0000, /* R25 - Power Management (1) */ + 0x0000, /* R26 - Power Management (2) */ + 0x0000, /* R27 - Additional Control (3) */ + 0x0000, /* R28 */ + 0x0000, /* R29 */ + 0x0000, /* R30 */ + 0x0000, /* R31 */ + 0x0000, /* R32 */ + 0x0000, /* R33 */ + 0x0050, /* R34 - Left out Mix (1) */ + 0x0050, /* R35 - Left out Mix (2) */ + 0x0050, /* R36 - Right out Mix (1) */ + 0x0050, /* R37 - Right Out Mix (2) */ + 0x0050, /* R38 - Mono out Mix (1) */ + 0x0050, /* R39 - Mono out Mix (2) */ + 0x0079, /* R40 - LOUT2 volume */ + 0x0079, /* R41 - ROUT2 volume */ + 0x0079, /* R42 - MONOOUT volume */ + 0x0000, /* R43 - Clocking / PLL */ + 0x0103, /* R44 - PLL Control 1 */ + 0x0024, /* R45 - PLL Control 2 */ + 0x01BA, /* R46 - PLL Control 3 */ + 0x0000, /* R47 */ + 0x0000, /* R48 */ + 0x0000, /* R49 */ + 0x0000, /* R50 */ + 0x0000, /* R51 */ + 0x0000, /* R52 */ + 0x0000, /* R53 */ + 0x0000, /* R54 */ + 0x0000, /* R55 */ + 0x0000, /* R56 */ + 0x0000, /* R57 */ + 0x0000, /* R58 */ + 0x0000, /* R59 - PLL Control 4 */ +}; + +static int wm8955_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8955_RESET, 0); +} + +struct pll_factors { + int n; + int k; + int outdiv; +}; + +/* The size in bits of the FLL divide multiplied by 10 + * to allow rounding later */ +#define FIXED_FLL_SIZE ((1 << 22) * 10) + +static int wm8995_pll_factors(struct device *dev, + int Fref, int Fout, struct pll_factors *pll) +{ + u64 Kpart; + unsigned int K, Ndiv, Nmod, target; + + dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout); + + /* The oscilator should run at should be 90-100MHz, and + * there's a divide by 4 plus an optional divide by 2 in the + * output path to generate the system clock. The clock table + * is sortd so we should always generate a suitable target. */ + target = Fout * 4; + if (target < 90000000) { + pll->outdiv = 1; + target *= 2; + } else { + pll->outdiv = 0; + } + + WARN_ON(target < 90000000 || target > 100000000); + + dev_dbg(dev, "Fvco=%dHz\n", target); + + /* Now, calculate N.K */ + Ndiv = target / Fref; + + pll->n = Ndiv; + Nmod = target % Fref; + dev_dbg(dev, "Nmod=%d\n", Nmod); + + /* Calculate fractional part - scale up so we can round. */ + Kpart = FIXED_FLL_SIZE * (long long)Nmod; + + do_div(Kpart, Fref); + + K = Kpart & 0xFFFFFFFF; + + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + pll->k = K / 10; + + dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv); + + return 0; +} + +/* Lookup table specifiying SRATE (table 25 in datasheet); some of the + * output frequencies have been rounded to the standard frequencies + * they are intended to match where the error is slight. */ +static struct { + int mclk; + int fs; + int usb; + int sr; +} clock_cfgs[] = { + { 18432000, 8000, 0, 3, }, + { 18432000, 12000, 0, 9, }, + { 18432000, 16000, 0, 11, }, + { 18432000, 24000, 0, 29, }, + { 18432000, 32000, 0, 13, }, + { 18432000, 48000, 0, 1, }, + { 18432000, 96000, 0, 15, }, + + { 16934400, 8018, 0, 19, }, + { 16934400, 11025, 0, 25, }, + { 16934400, 22050, 0, 27, }, + { 16934400, 44100, 0, 17, }, + { 16934400, 88200, 0, 31, }, + + { 12000000, 8000, 1, 2, }, + { 12000000, 11025, 1, 25, }, + { 12000000, 12000, 1, 8, }, + { 12000000, 16000, 1, 10, }, + { 12000000, 22050, 1, 27, }, + { 12000000, 24000, 1, 28, }, + { 12000000, 32000, 1, 12, }, + { 12000000, 44100, 1, 17, }, + { 12000000, 48000, 1, 0, }, + { 12000000, 88200, 1, 31, }, + { 12000000, 96000, 1, 14, }, + + { 12288000, 8000, 0, 2, }, + { 12288000, 12000, 0, 8, }, + { 12288000, 16000, 0, 10, }, + { 12288000, 24000, 0, 28, }, + { 12288000, 32000, 0, 12, }, + { 12288000, 48000, 0, 0, }, + { 12288000, 96000, 0, 14, }, + + { 12289600, 8018, 0, 18, }, + { 12289600, 11025, 0, 24, }, + { 12289600, 22050, 0, 26, }, + { 11289600, 44100, 0, 16, }, + { 11289600, 88200, 0, 31, }, +}; + +static int wm8955_configure_clocking(struct snd_soc_codec *codec) +{ + struct wm8955_priv *wm8955 = codec->private_data; + int i, ret, val; + int clocking = 0; + int srate = 0; + int sr = -1; + struct pll_factors pll; + + /* If we're not running a sample rate currently just pick one */ + if (wm8955->fs == 0) + wm8955->fs = 8000; + + /* Can we generate an exact output? */ + for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) { + if (wm8955->fs != clock_cfgs[i].fs) + continue; + sr = i; + + if (wm8955->mclk_rate == clock_cfgs[i].mclk) + break; + } + + /* We should never get here with an unsupported sample rate */ + if (sr == -1) { + dev_err(codec->dev, "Sample rate %dHz unsupported\n", + wm8955->fs); + WARN_ON(sr == -1); + return -EINVAL; + } + + if (i == ARRAY_SIZE(clock_cfgs)) { + /* If we can't generate the right clock from MCLK then + * we should configure the PLL to supply us with an + * appropriate clock. + */ + clocking |= WM8955_MCLKSEL; + + /* Use the last divider configuration we saw for the + * sample rate. */ + ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate, + clock_cfgs[sr].mclk, &pll); + if (ret != 0) { + dev_err(codec->dev, + "Unable to generate %dHz from %dHz MCLK\n", + wm8955->fs, wm8955->mclk_rate); + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1, + WM8955_N_MASK | WM8955_K_21_18_MASK, + (pll.n << WM8955_N_SHIFT) | + pll.k >> 18); + snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2, + WM8955_K_17_9_MASK, + (pll.k >> 9) & WM8955_K_17_9_MASK); + snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2, + WM8955_K_8_0_MASK, + pll.k & WM8955_K_8_0_MASK); + if (pll.k) + snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4, + WM8955_KEN, WM8955_KEN); + else + snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4, + WM8955_KEN, 0); + + if (pll.outdiv) + val = WM8955_PLL_RB | WM8955_PLLOUTDIV2; + else + val = WM8955_PLL_RB; + + /* Now start the PLL running */ + snd_soc_update_bits(codec, WM8955_CLOCKING_PLL, + WM8955_PLL_RB | WM8955_PLLOUTDIV2, val); + snd_soc_update_bits(codec, WM8955_CLOCKING_PLL, + WM8955_PLLEN, WM8955_PLLEN); + } + + srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT); + + snd_soc_update_bits(codec, WM8955_SAMPLE_RATE, + WM8955_USB | WM8955_SR_MASK, srate); + snd_soc_update_bits(codec, WM8955_CLOCKING_PLL, + WM8955_MCLKSEL, clocking); + + return 0; +} + +static int wm8955_sysclk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + int ret = 0; + + /* Always disable the clocks - if we're doing reconfiguration this + * avoids misclocking. + */ + snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, + WM8955_DIGENB, 0); + snd_soc_update_bits(codec, WM8955_CLOCKING_PLL, + WM8955_PLL_RB | WM8955_PLLEN, 0); + + switch (event) { + case SND_SOC_DAPM_POST_PMD: + break; + case SND_SOC_DAPM_PRE_PMU: + ret = wm8955_configure_clocking(codec); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int deemph_settings[] = { 0, 32000, 44100, 48000 }; + +static int wm8955_set_deemph(struct snd_soc_codec *codec) +{ + struct wm8955_priv *wm8955 = codec->private_data; + int val, i, best; + + /* If we're using deemphasis select the nearest available sample + * rate. + */ + if (wm8955->deemph) { + best = 1; + for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) { + if (abs(deemph_settings[i] - wm8955->fs) < + abs(deemph_settings[best] - wm8955->fs)) + best = i; + } + + val = best << WM8955_DEEMPH_SHIFT; + } else { + val = 0; + } + + dev_dbg(codec->dev, "Set deemphasis %d\n", val); + + return snd_soc_update_bits(codec, WM8955_DAC_CONTROL, + WM8955_DEEMPH_MASK, val); +} + +static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8955_priv *wm8955 = codec->private_data; + + return wm8955->deemph; +} + +static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8955_priv *wm8955 = codec->private_data; + int deemph = ucontrol->value.enumerated.item[0]; + + if (deemph > 1) + return -EINVAL; + + wm8955->deemph = deemph; + + return wm8955_set_deemph(codec); +} + +static const char *bass_mode_text[] = { + "Linear", "Adaptive", +}; + +static const struct soc_enum bass_mode = + SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text); + +static const char *bass_cutoff_text[] = { + "Low", "High" +}; + +static const struct soc_enum bass_cutoff = + SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text); + +static const char *treble_cutoff_text[] = { + "High", "Low" +}; + +static const struct soc_enum treble_cutoff = + SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text); + +static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0); +static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); +static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0); +static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); +static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1); + +static const struct snd_kcontrol_new wm8955_snd_controls[] = { +SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME, + WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv), +SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1, + atten_tlv), +SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, + wm8955_get_deemph, wm8955_put_deemph), + +SOC_ENUM("Bass Mode", bass_mode), +SOC_ENUM("Bass Cutoff", bass_cutoff), +SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1), + +SOC_ENUM("Treble Cutoff", treble_cutoff), +SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv), + +SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1, + bypass_tlv), +SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1, + bypass_tlv), + +SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1, + bypass_tlv), +SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1, + bypass_tlv), + +/* Not a stereo pair so they line up with the DAPM switches */ +SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1, + mono_tlv), +SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1, + mono_tlv), + +SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME, + WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv), +SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME, + WM8955_ROUT1_VOLUME, 7, 1, 0), + +SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME, + WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv), +SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME, + WM8955_ROUT2_VOLUME, 7, 1, 0), + +SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv), +SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0), +}; + +static const struct snd_kcontrol_new lmixer[] = { +SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0), +SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0), +SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0), +SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0), +}; + +static const struct snd_kcontrol_new rmixer[] = { +SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0), +SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0), +SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0), +SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0), +}; + +static const struct snd_kcontrol_new mmixer[] = { +SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0), +SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0), +SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0), +SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0), +}; + +static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("MONOIN-"), +SND_SOC_DAPM_INPUT("MONOIN+"), +SND_SOC_DAPM_INPUT("LINEINR"), +SND_SOC_DAPM_INPUT("LINEINL"), + +SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0), + +SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0), + +SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0), +SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0), + +SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0), +SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0), + +/* The names are chosen to make the control names nice */ +SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0, + lmixer, ARRAY_SIZE(lmixer)), +SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0, + rmixer, ARRAY_SIZE(rmixer)), +SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0, + mmixer, ARRAY_SIZE(mmixer)), + +SND_SOC_DAPM_OUTPUT("LOUT1"), +SND_SOC_DAPM_OUTPUT("ROUT1"), +SND_SOC_DAPM_OUTPUT("LOUT2"), +SND_SOC_DAPM_OUTPUT("ROUT2"), +SND_SOC_DAPM_OUTPUT("MONOOUT"), +SND_SOC_DAPM_OUTPUT("OUT3"), +}; + +static const struct snd_soc_dapm_route wm8955_intercon[] = { + { "DACL", NULL, "SYSCLK" }, + { "DACR", NULL, "SYSCLK" }, + + { "Mono Input", NULL, "MONOIN-" }, + { "Mono Input", NULL, "MONOIN+" }, + + { "Left", "Playback Switch", "DACL" }, + { "Left", "Right Playback Switch", "DACR" }, + { "Left", "Bypass Switch", "LINEINL" }, + { "Left", "Mono Switch", "Mono Input" }, + + { "Right", "Playback Switch", "DACR" }, + { "Right", "Left Playback Switch", "DACL" }, + { "Right", "Bypass Switch", "LINEINR" }, + { "Right", "Mono Switch", "Mono Input" }, + + { "Mono", "Left Playback Switch", "DACL" }, + { "Mono", "Right Playback Switch", "DACR" }, + { "Mono", "Left Bypass Switch", "LINEINL" }, + { "Mono", "Right Bypass Switch", "LINEINR" }, + + { "LOUT1 PGA", NULL, "Left" }, + { "LOUT1", NULL, "TSDEN" }, + { "LOUT1", NULL, "LOUT1 PGA" }, + + { "ROUT1 PGA", NULL, "Right" }, + { "ROUT1", NULL, "TSDEN" }, + { "ROUT1", NULL, "ROUT1 PGA" }, + + { "LOUT2 PGA", NULL, "Left" }, + { "LOUT2", NULL, "TSDEN" }, + { "LOUT2", NULL, "LOUT2 PGA" }, + + { "ROUT2 PGA", NULL, "Right" }, + { "ROUT2", NULL, "TSDEN" }, + { "ROUT2", NULL, "ROUT2 PGA" }, + + { "MOUT PGA", NULL, "Mono" }, + { "MONOOUT", NULL, "MOUT PGA" }, + + /* OUT3 not currently implemented */ + { "OUT3", NULL, "OUT3 PGA" }, +}; + +static int wm8955_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_add_controls(codec, wm8955_snd_controls, + ARRAY_SIZE(wm8955_snd_controls)); + + snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets, + ARRAY_SIZE(wm8955_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, wm8955_intercon, + ARRAY_SIZE(wm8955_intercon)); + + return 0; +} + +static int wm8955_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8955_priv *wm8955 = codec->private_data; + int ret; + int wl; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + wl = 0; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + wl = 0x4; + break; + case SNDRV_PCM_FORMAT_S24_LE: + wl = 0x8; + break; + case SNDRV_PCM_FORMAT_S32_LE: + wl = 0xc; + break; + default: + return -EINVAL; + } + snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE, + WM8955_WL_MASK, wl); + + wm8955->fs = params_rate(params); + wm8955_set_deemph(codec); + + /* If the chip is clocked then disable the clocks and force a + * reconfiguration, otherwise DAPM will power up the + * clocks for us later. */ + ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1); + if (ret < 0) + return ret; + if (ret & WM8955_DIGENB) { + snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, + WM8955_DIGENB, 0); + snd_soc_update_bits(codec, WM8955_CLOCKING_PLL, + WM8955_PLL_RB | WM8955_PLLEN, 0); + + wm8955_configure_clocking(codec); + } + + return 0; +} + + +static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8955_priv *priv = codec->private_data; + int div; + + switch (clk_id) { + case WM8955_CLK_MCLK: + if (freq > 15000000) { + priv->mclk_rate = freq /= 2; + div = WM8955_MCLKDIV2; + } else { + priv->mclk_rate = freq; + div = 0; + } + + snd_soc_update_bits(codec, WM8955_SAMPLE_RATE, + WM8955_MCLKDIV2, div); + break; + + default: + return -EINVAL; + } + + dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq); + + return 0; +} + +static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + u16 aif = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + aif |= WM8955_MS; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: + aif |= WM8955_LRP; + case SND_SOC_DAIFMT_DSP_A: + aif |= 0x3; + break; + case SND_SOC_DAIFMT_I2S: + aif |= 0x2; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + aif |= 0x1; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + aif |= WM8955_BCLKINV; + break; + default: + return -EINVAL; + } + break; + + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + aif |= WM8955_BCLKINV | WM8955_LRP; + break; + case SND_SOC_DAIFMT_IB_NF: + aif |= WM8955_BCLKINV; + break; + case SND_SOC_DAIFMT_NB_IF: + aif |= WM8955_LRP; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE, + WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV | + WM8955_LRP, aif); + + return 0; +} + + +static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute) +{ + struct snd_soc_codec *codec = codec_dai->codec; + int val; + + if (mute) + val = WM8955_DACMU; + else + val = 0; + + snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val); + + return 0; +} + +static int wm8955_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8955_priv *wm8955 = codec->private_data; + int ret, i; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VMID resistance 2*50k */ + snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, + WM8955_VMIDSEL_MASK, + 0x1 << WM8955_VMIDSEL_SHIFT); + + /* Default bias current */ + snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1, + WM8955_VSEL_MASK, + 0x2 << WM8955_VSEL_SHIFT); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), + wm8955->supplies); + if (ret != 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + + /* Sync back cached values if they're + * different from the hardware default. + */ + for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) { + if (i == WM8955_RESET) + continue; + + if (wm8955->reg_cache[i] == wm8955_reg[i]) + continue; + + snd_soc_write(codec, i, wm8955->reg_cache[i]); + } + + /* Enable VREF and VMID */ + snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, + WM8955_VREF | + WM8955_VMIDSEL_MASK, + WM8955_VREF | + 0x3 << WM8955_VREF_SHIFT); + + /* Let VMID ramp */ + msleep(500); + + /* High resistance VROI to maintain outputs */ + snd_soc_update_bits(codec, + WM8955_ADDITIONAL_CONTROL_3, + WM8955_VROI, WM8955_VROI); + } + + /* Maintain VMID with 2*250k */ + snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, + WM8955_VMIDSEL_MASK, + 0x2 << WM8955_VMIDSEL_SHIFT); + + /* Minimum bias current */ + snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1, + WM8955_VSEL_MASK, 0); + break; + + case SND_SOC_BIAS_OFF: + /* Low resistance VROI to help discharge */ + snd_soc_update_bits(codec, + WM8955_ADDITIONAL_CONTROL_3, + WM8955_VROI, 0); + + /* Turn off VMID and VREF */ + snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, + WM8955_VREF | + WM8955_VMIDSEL_MASK, 0); + + regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), + wm8955->supplies); + break; + } + codec->bias_level = level; + return 0; +} + +#define WM8955_RATES SNDRV_PCM_RATE_8000_96000 + +#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8955_dai_ops = { + .set_sysclk = wm8955_set_sysclk, + .set_fmt = wm8955_set_fmt, + .hw_params = wm8955_hw_params, + .digital_mute = wm8955_digital_mute, +}; + +struct snd_soc_dai wm8955_dai = { + .name = "WM8955", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8955_RATES, + .formats = WM8955_FORMATS, + }, + .ops = &wm8955_dai_ops, +}; +EXPORT_SYMBOL_GPL(wm8955_dai); + +#ifdef CONFIG_PM +static int wm8955_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int wm8955_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + return 0; +} +#else +#define wm8955_suspend NULL +#define wm8955_resume NULL +#endif + +static int wm8955_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + int ret = 0; + + if (wm8955_codec == NULL) { + dev_err(&pdev->dev, "Codec device not registered\n"); + return -ENODEV; + } + + socdev->card->codec = wm8955_codec; + codec = wm8955_codec; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(codec->dev, "failed to create pcms: %d\n", ret); + goto pcm_err; + } + + wm8955_add_widgets(codec); + + return ret; + +pcm_err: + return ret; +} + +static int wm8955_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8955 = { + .probe = wm8955_probe, + .remove = wm8955_remove, + .suspend = wm8955_suspend, + .resume = wm8955_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955); + +static int wm8955_register(struct wm8955_priv *wm8955, + enum snd_soc_control_type control) +{ + int ret; + struct snd_soc_codec *codec = &wm8955->codec; + int i; + + if (wm8955_codec) { + dev_err(codec->dev, "Another WM8955 is registered\n"); + return -EINVAL; + } + + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + codec->private_data = wm8955; + codec->name = "WM8955"; + codec->owner = THIS_MODULE; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = wm8955_set_bias_level; + codec->dai = &wm8955_dai; + codec->num_dai = 1; + codec->reg_cache_size = WM8955_MAX_REGISTER; + codec->reg_cache = &wm8955->reg_cache; + + memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg)); + + ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + goto err; + } + + for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) + wm8955->supplies[i].supply = wm8955_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies), + wm8955->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + goto err; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), + wm8955->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + ret = wm8955_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); + goto err_enable; + } + + wm8955_dai.dev = codec->dev; + + /* Change some default settings - latch VU and enable ZC */ + wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; + wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; + wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; + wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; + wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; + wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; + wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; + + /* Also enable adaptive bass boost by default */ + wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; + + /* Set platform data values */ + if (wm8955->pdata) { + if (wm8955->pdata->out2_speaker) + wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2] + |= WM8955_ROUT2INV; + + if (wm8955->pdata->monoin_diff) + wm8955->reg_cache[WM8955_MONO_OUT_MIX_1] + |= WM8955_DMEN; + } + + wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* Bias level configuration will have done an extra enable */ + regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); + + wm8955_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret != 0) { + dev_err(codec->dev, "Failed to register codec: %d\n", ret); + return ret; + } + + ret = snd_soc_register_dai(&wm8955_dai); + if (ret != 0) { + dev_err(codec->dev, "Failed to register DAI: %d\n", ret); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); +err: + kfree(wm8955); + return ret; +} + +static void wm8955_unregister(struct wm8955_priv *wm8955) +{ + wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF); + regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); + snd_soc_unregister_dai(&wm8955_dai); + snd_soc_unregister_codec(&wm8955->codec); + kfree(wm8955); + wm8955_codec = NULL; +} + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8955_priv *wm8955; + struct snd_soc_codec *codec; + + wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL); + if (wm8955 == NULL) + return -ENOMEM; + + codec = &wm8955->codec; + codec->hw_write = (hw_write_t)i2c_master_send; + + i2c_set_clientdata(i2c, wm8955); + codec->control_data = i2c; + wm8955->pdata = i2c->dev.platform_data; + + codec->dev = &i2c->dev; + + return wm8955_register(wm8955, SND_SOC_I2C); +} + +static __devexit int wm8955_i2c_remove(struct i2c_client *client) +{ + struct wm8955_priv *wm8955 = i2c_get_clientdata(client); + wm8955_unregister(wm8955); + return 0; +} + +static const struct i2c_device_id wm8955_i2c_id[] = { + { "wm8955", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id); + +static struct i2c_driver wm8955_i2c_driver = { + .driver = { + .name = "wm8955", + .owner = THIS_MODULE, + }, + .probe = wm8955_i2c_probe, + .remove = __devexit_p(wm8955_i2c_remove), + .id_table = wm8955_i2c_id, +}; +#endif + +static int __init wm8955_modinit(void) +{ + int ret; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + ret = i2c_add_driver(&wm8955_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", + ret); + } +#endif + return 0; +} +module_init(wm8955_modinit); + +static void __exit wm8955_exit(void) +{ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&wm8955_i2c_driver); +#endif +} +module_exit(wm8955_exit); + +MODULE_DESCRIPTION("ASoC WM8955 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h new file mode 100644 index 000000000000..ae349c8531f6 --- /dev/null +++ b/sound/soc/codecs/wm8955.h @@ -0,0 +1,489 @@ +/* + * wm8955.h -- WM8904 ASoC driver + * + * Copyright 2009 Wolfson Microelectronics, plc + * + * Author: Mark Brown + * + * 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 _WM8955_H +#define _WM8955_H + +#define WM8955_CLK_MCLK 1 + +extern struct snd_soc_dai wm8955_dai; +extern struct snd_soc_codec_device soc_codec_dev_wm8955; + +/* + * Register values. + */ +#define WM8955_LOUT1_VOLUME 0x02 +#define WM8955_ROUT1_VOLUME 0x03 +#define WM8955_DAC_CONTROL 0x05 +#define WM8955_AUDIO_INTERFACE 0x07 +#define WM8955_SAMPLE_RATE 0x08 +#define WM8955_LEFT_DAC_VOLUME 0x0A +#define WM8955_RIGHT_DAC_VOLUME 0x0B +#define WM8955_BASS_CONTROL 0x0C +#define WM8955_TREBLE_CONTROL 0x0D +#define WM8955_RESET 0x0F +#define WM8955_ADDITIONAL_CONTROL_1 0x17 +#define WM8955_ADDITIONAL_CONTROL_2 0x18 +#define WM8955_POWER_MANAGEMENT_1 0x19 +#define WM8955_POWER_MANAGEMENT_2 0x1A +#define WM8955_ADDITIONAL_CONTROL_3 0x1B +#define WM8955_LEFT_OUT_MIX_1 0x22 +#define WM8955_LEFT_OUT_MIX_2 0x23 +#define WM8955_RIGHT_OUT_MIX_1 0x24 +#define WM8955_RIGHT_OUT_MIX_2 0x25 +#define WM8955_MONO_OUT_MIX_1 0x26 +#define WM8955_MONO_OUT_MIX_2 0x27 +#define WM8955_LOUT2_VOLUME 0x28 +#define WM8955_ROUT2_VOLUME 0x29 +#define WM8955_MONOOUT_VOLUME 0x2A +#define WM8955_CLOCKING_PLL 0x2B +#define WM8955_PLL_CONTROL_1 0x2C +#define WM8955_PLL_CONTROL_2 0x2D +#define WM8955_PLL_CONTROL_3 0x2E +#define WM8955_PLL_CONTROL_4 0x3B + +#define WM8955_REGISTER_COUNT 29 +#define WM8955_MAX_REGISTER 0x3B + +/* + * Field Definitions. + */ + +/* + * R2 (0x02) - LOUT1 volume + */ +#define WM8955_LO1VU 0x0100 /* LO1VU */ +#define WM8955_LO1VU_MASK 0x0100 /* LO1VU */ +#define WM8955_LO1VU_SHIFT 8 /* LO1VU */ +#define WM8955_LO1VU_WIDTH 1 /* LO1VU */ +#define WM8955_LO1ZC 0x0080 /* LO1ZC */ +#define WM8955_LO1ZC_MASK 0x0080 /* LO1ZC */ +#define WM8955_LO1ZC_SHIFT 7 /* LO1ZC */ +#define WM8955_LO1ZC_WIDTH 1 /* LO1ZC */ +#define WM8955_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */ +#define WM8955_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */ +#define WM8955_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */ + +/* + * R3 (0x03) - ROUT1 volume + */ +#define WM8955_RO1VU 0x0100 /* RO1VU */ +#define WM8955_RO1VU_MASK 0x0100 /* RO1VU */ +#define WM8955_RO1VU_SHIFT 8 /* RO1VU */ +#define WM8955_RO1VU_WIDTH 1 /* RO1VU */ +#define WM8955_RO1ZC 0x0080 /* RO1ZC */ +#define WM8955_RO1ZC_MASK 0x0080 /* RO1ZC */ +#define WM8955_RO1ZC_SHIFT 7 /* RO1ZC */ +#define WM8955_RO1ZC_WIDTH 1 /* RO1ZC */ +#define WM8955_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */ +#define WM8955_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */ +#define WM8955_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */ + +/* + * R5 (0x05) - DAC Control + */ +#define WM8955_DAT 0x0080 /* DAT */ +#define WM8955_DAT_MASK 0x0080 /* DAT */ +#define WM8955_DAT_SHIFT 7 /* DAT */ +#define WM8955_DAT_WIDTH 1 /* DAT */ +#define WM8955_DACMU 0x0008 /* DACMU */ +#define WM8955_DACMU_MASK 0x0008 /* DACMU */ +#define WM8955_DACMU_SHIFT 3 /* DACMU */ +#define WM8955_DACMU_WIDTH 1 /* DACMU */ +#define WM8955_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */ +#define WM8955_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */ +#define WM8955_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */ + +/* + * R7 (0x07) - Audio Interface + */ +#define WM8955_BCLKINV 0x0080 /* BCLKINV */ +#define WM8955_BCLKINV_MASK 0x0080 /* BCLKINV */ +#define WM8955_BCLKINV_SHIFT 7 /* BCLKINV */ +#define WM8955_BCLKINV_WIDTH 1 /* BCLKINV */ +#define WM8955_MS 0x0040 /* MS */ +#define WM8955_MS_MASK 0x0040 /* MS */ +#define WM8955_MS_SHIFT 6 /* MS */ +#define WM8955_MS_WIDTH 1 /* MS */ +#define WM8955_LRSWAP 0x0020 /* LRSWAP */ +#define WM8955_LRSWAP_MASK 0x0020 /* LRSWAP */ +#define WM8955_LRSWAP_SHIFT 5 /* LRSWAP */ +#define WM8955_LRSWAP_WIDTH 1 /* LRSWAP */ +#define WM8955_LRP 0x0010 /* LRP */ +#define WM8955_LRP_MASK 0x0010 /* LRP */ +#define WM8955_LRP_SHIFT 4 /* LRP */ +#define WM8955_LRP_WIDTH 1 /* LRP */ +#define WM8955_WL_MASK 0x000C /* WL - [3:2] */ +#define WM8955_WL_SHIFT 2 /* WL - [3:2] */ +#define WM8955_WL_WIDTH 2 /* WL - [3:2] */ +#define WM8955_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */ +#define WM8955_FORMAT_SHIFT 0 /* FORMAT - [1:0] */ +#define WM8955_FORMAT_WIDTH 2 /* FORMAT - [1:0] */ + +/* + * R8 (0x08) - Sample Rate + */ +#define WM8955_BCLKDIV2 0x0080 /* BCLKDIV2 */ +#define WM8955_BCLKDIV2_MASK 0x0080 /* BCLKDIV2 */ +#define WM8955_BCLKDIV2_SHIFT 7 /* BCLKDIV2 */ +#define WM8955_BCLKDIV2_WIDTH 1 /* BCLKDIV2 */ +#define WM8955_MCLKDIV2 0x0040 /* MCLKDIV2 */ +#define WM8955_MCLKDIV2_MASK 0x0040 /* MCLKDIV2 */ +#define WM8955_MCLKDIV2_SHIFT 6 /* MCLKDIV2 */ +#define WM8955_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */ +#define WM8955_SR_MASK 0x003E /* SR - [5:1] */ +#define WM8955_SR_SHIFT 1 /* SR - [5:1] */ +#define WM8955_SR_WIDTH 5 /* SR - [5:1] */ +#define WM8955_USB 0x0001 /* USB */ +#define WM8955_USB_MASK 0x0001 /* USB */ +#define WM8955_USB_SHIFT 0 /* USB */ +#define WM8955_USB_WIDTH 1 /* USB */ + +/* + * R10 (0x0A) - Left DAC volume + */ +#define WM8955_LDVU 0x0100 /* LDVU */ +#define WM8955_LDVU_MASK 0x0100 /* LDVU */ +#define WM8955_LDVU_SHIFT 8 /* LDVU */ +#define WM8955_LDVU_WIDTH 1 /* LDVU */ +#define WM8955_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */ +#define WM8955_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */ +#define WM8955_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */ + +/* + * R11 (0x0B) - Right DAC volume + */ +#define WM8955_RDVU 0x0100 /* RDVU */ +#define WM8955_RDVU_MASK 0x0100 /* RDVU */ +#define WM8955_RDVU_SHIFT 8 /* RDVU */ +#define WM8955_RDVU_WIDTH 1 /* RDVU */ +#define WM8955_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */ +#define WM8955_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */ +#define WM8955_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */ + +/* + * R12 (0x0C) - Bass control + */ +#define WM8955_BB 0x0080 /* BB */ +#define WM8955_BB_MASK 0x0080 /* BB */ +#define WM8955_BB_SHIFT 7 /* BB */ +#define WM8955_BB_WIDTH 1 /* BB */ +#define WM8955_BC 0x0040 /* BC */ +#define WM8955_BC_MASK 0x0040 /* BC */ +#define WM8955_BC_SHIFT 6 /* BC */ +#define WM8955_BC_WIDTH 1 /* BC */ +#define WM8955_BASS_MASK 0x000F /* BASS - [3:0] */ +#define WM8955_BASS_SHIFT 0 /* BASS - [3:0] */ +#define WM8955_BASS_WIDTH 4 /* BASS - [3:0] */ + +/* + * R13 (0x0D) - Treble control + */ +#define WM8955_TC 0x0040 /* TC */ +#define WM8955_TC_MASK 0x0040 /* TC */ +#define WM8955_TC_SHIFT 6 /* TC */ +#define WM8955_TC_WIDTH 1 /* TC */ +#define WM8955_TRBL_MASK 0x000F /* TRBL - [3:0] */ +#define WM8955_TRBL_SHIFT 0 /* TRBL - [3:0] */ +#define WM8955_TRBL_WIDTH 4 /* TRBL - [3:0] */ + +/* + * R15 (0x0F) - Reset + */ +#define WM8955_RESET_MASK 0x01FF /* RESET - [8:0] */ +#define WM8955_RESET_SHIFT 0 /* RESET - [8:0] */ +#define WM8955_RESET_WIDTH 9 /* RESET - [8:0] */ + +/* + * R23 (0x17) - Additional control (1) + */ +#define WM8955_TSDEN 0x0100 /* TSDEN */ +#define WM8955_TSDEN_MASK 0x0100 /* TSDEN */ +#define WM8955_TSDEN_SHIFT 8 /* TSDEN */ +#define WM8955_TSDEN_WIDTH 1 /* TSDEN */ +#define WM8955_VSEL_MASK 0x00C0 /* VSEL - [7:6] */ +#define WM8955_VSEL_SHIFT 6 /* VSEL - [7:6] */ +#define WM8955_VSEL_WIDTH 2 /* VSEL - [7:6] */ +#define WM8955_DMONOMIX_MASK 0x0030 /* DMONOMIX - [5:4] */ +#define WM8955_DMONOMIX_SHIFT 4 /* DMONOMIX - [5:4] */ +#define WM8955_DMONOMIX_WIDTH 2 /* DMONOMIX - [5:4] */ +#define WM8955_DACINV 0x0002 /* DACINV */ +#define WM8955_DACINV_MASK 0x0002 /* DACINV */ +#define WM8955_DACINV_SHIFT 1 /* DACINV */ +#define WM8955_DACINV_WIDTH 1 /* DACINV */ +#define WM8955_TOEN 0x0001 /* TOEN */ +#define WM8955_TOEN_MASK 0x0001 /* TOEN */ +#define WM8955_TOEN_SHIFT 0 /* TOEN */ +#define WM8955_TOEN_WIDTH 1 /* TOEN */ + +/* + * R24 (0x18) - Additional control (2) + */ +#define WM8955_OUT3SW_MASK 0x0180 /* OUT3SW - [8:7] */ +#define WM8955_OUT3SW_SHIFT 7 /* OUT3SW - [8:7] */ +#define WM8955_OUT3SW_WIDTH 2 /* OUT3SW - [8:7] */ +#define WM8955_ROUT2INV 0x0010 /* ROUT2INV */ +#define WM8955_ROUT2INV_MASK 0x0010 /* ROUT2INV */ +#define WM8955_ROUT2INV_SHIFT 4 /* ROUT2INV */ +#define WM8955_ROUT2INV_WIDTH 1 /* ROUT2INV */ +#define WM8955_DACOSR 0x0001 /* DACOSR */ +#define WM8955_DACOSR_MASK 0x0001 /* DACOSR */ +#define WM8955_DACOSR_SHIFT 0 /* DACOSR */ +#define WM8955_DACOSR_WIDTH 1 /* DACOSR */ + +/* + * R25 (0x19) - Power Management (1) + */ +#define WM8955_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */ +#define WM8955_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */ +#define WM8955_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */ +#define WM8955_VREF 0x0040 /* VREF */ +#define WM8955_VREF_MASK 0x0040 /* VREF */ +#define WM8955_VREF_SHIFT 6 /* VREF */ +#define WM8955_VREF_WIDTH 1 /* VREF */ +#define WM8955_DIGENB 0x0001 /* DIGENB */ +#define WM8955_DIGENB_MASK 0x0001 /* DIGENB */ +#define WM8955_DIGENB_SHIFT 0 /* DIGENB */ +#define WM8955_DIGENB_WIDTH 1 /* DIGENB */ + +/* + * R26 (0x1A) - Power Management (2) + */ +#define WM8955_DACL 0x0100 /* DACL */ +#define WM8955_DACL_MASK 0x0100 /* DACL */ +#define WM8955_DACL_SHIFT 8 /* DACL */ +#define WM8955_DACL_WIDTH 1 /* DACL */ +#define WM8955_DACR 0x0080 /* DACR */ +#define WM8955_DACR_MASK 0x0080 /* DACR */ +#define WM8955_DACR_SHIFT 7 /* DACR */ +#define WM8955_DACR_WIDTH 1 /* DACR */ +#define WM8955_LOUT1 0x0040 /* LOUT1 */ +#define WM8955_LOUT1_MASK 0x0040 /* LOUT1 */ +#define WM8955_LOUT1_SHIFT 6 /* LOUT1 */ +#define WM8955_LOUT1_WIDTH 1 /* LOUT1 */ +#define WM8955_ROUT1 0x0020 /* ROUT1 */ +#define WM8955_ROUT1_MASK 0x0020 /* ROUT1 */ +#define WM8955_ROUT1_SHIFT 5 /* ROUT1 */ +#define WM8955_ROUT1_WIDTH 1 /* ROUT1 */ +#define WM8955_LOUT2 0x0010 /* LOUT2 */ +#define WM8955_LOUT2_MASK 0x0010 /* LOUT2 */ +#define WM8955_LOUT2_SHIFT 4 /* LOUT2 */ +#define WM8955_LOUT2_WIDTH 1 /* LOUT2 */ +#define WM8955_ROUT2 0x0008 /* ROUT2 */ +#define WM8955_ROUT2_MASK 0x0008 /* ROUT2 */ +#define WM8955_ROUT2_SHIFT 3 /* ROUT2 */ +#define WM8955_ROUT2_WIDTH 1 /* ROUT2 */ +#define WM8955_MONO 0x0004 /* MONO */ +#define WM8955_MONO_MASK 0x0004 /* MONO */ +#define WM8955_MONO_SHIFT 2 /* MONO */ +#define WM8955_MONO_WIDTH 1 /* MONO */ +#define WM8955_OUT3 0x0002 /* OUT3 */ +#define WM8955_OUT3_MASK 0x0002 /* OUT3 */ +#define WM8955_OUT3_SHIFT 1 /* OUT3 */ +#define WM8955_OUT3_WIDTH 1 /* OUT3 */ + +/* + * R27 (0x1B) - Additional Control (3) + */ +#define WM8955_VROI 0x0040 /* VROI */ +#define WM8955_VROI_MASK 0x0040 /* VROI */ +#define WM8955_VROI_SHIFT 6 /* VROI */ +#define WM8955_VROI_WIDTH 1 /* VROI */ + +/* + * R34 (0x22) - Left out Mix (1) + */ +#define WM8955_LD2LO 0x0100 /* LD2LO */ +#define WM8955_LD2LO_MASK 0x0100 /* LD2LO */ +#define WM8955_LD2LO_SHIFT 8 /* LD2LO */ +#define WM8955_LD2LO_WIDTH 1 /* LD2LO */ +#define WM8955_LI2LO 0x0080 /* LI2LO */ +#define WM8955_LI2LO_MASK 0x0080 /* LI2LO */ +#define WM8955_LI2LO_SHIFT 7 /* LI2LO */ +#define WM8955_LI2LO_WIDTH 1 /* LI2LO */ +#define WM8955_LI2LOVOL_MASK 0x0070 /* LI2LOVOL - [6:4] */ +#define WM8955_LI2LOVOL_SHIFT 4 /* LI2LOVOL - [6:4] */ +#define WM8955_LI2LOVOL_WIDTH 3 /* LI2LOVOL - [6:4] */ + +/* + * R35 (0x23) - Left out Mix (2) + */ +#define WM8955_RD2LO 0x0100 /* RD2LO */ +#define WM8955_RD2LO_MASK 0x0100 /* RD2LO */ +#define WM8955_RD2LO_SHIFT 8 /* RD2LO */ +#define WM8955_RD2LO_WIDTH 1 /* RD2LO */ +#define WM8955_RI2LO 0x0080 /* RI2LO */ +#define WM8955_RI2LO_MASK 0x0080 /* RI2LO */ +#define WM8955_RI2LO_SHIFT 7 /* RI2LO */ +#define WM8955_RI2LO_WIDTH 1 /* RI2LO */ +#define WM8955_RI2LOVOL_MASK 0x0070 /* RI2LOVOL - [6:4] */ +#define WM8955_RI2LOVOL_SHIFT 4 /* RI2LOVOL - [6:4] */ +#define WM8955_RI2LOVOL_WIDTH 3 /* RI2LOVOL - [6:4] */ + +/* + * R36 (0x24) - Right out Mix (1) + */ +#define WM8955_LD2RO 0x0100 /* LD2RO */ +#define WM8955_LD2RO_MASK 0x0100 /* LD2RO */ +#define WM8955_LD2RO_SHIFT 8 /* LD2RO */ +#define WM8955_LD2RO_WIDTH 1 /* LD2RO */ +#define WM8955_LI2RO 0x0080 /* LI2RO */ +#define WM8955_LI2RO_MASK 0x0080 /* LI2RO */ +#define WM8955_LI2RO_SHIFT 7 /* LI2RO */ +#define WM8955_LI2RO_WIDTH 1 /* LI2RO */ +#define WM8955_LI2ROVOL_MASK 0x0070 /* LI2ROVOL - [6:4] */ +#define WM8955_LI2ROVOL_SHIFT 4 /* LI2ROVOL - [6:4] */ +#define WM8955_LI2ROVOL_WIDTH 3 /* LI2ROVOL - [6:4] */ + +/* + * R37 (0x25) - Right Out Mix (2) + */ +#define WM8955_RD2RO 0x0100 /* RD2RO */ +#define WM8955_RD2RO_MASK 0x0100 /* RD2RO */ +#define WM8955_RD2RO_SHIFT 8 /* RD2RO */ +#define WM8955_RD2RO_WIDTH 1 /* RD2RO */ +#define WM8955_RI2RO 0x0080 /* RI2RO */ +#define WM8955_RI2RO_MASK 0x0080 /* RI2RO */ +#define WM8955_RI2RO_SHIFT 7 /* RI2RO */ +#define WM8955_RI2RO_WIDTH 1 /* RI2RO */ +#define WM8955_RI2ROVOL_MASK 0x0070 /* RI2ROVOL - [6:4] */ +#define WM8955_RI2ROVOL_SHIFT 4 /* RI2ROVOL - [6:4] */ +#define WM8955_RI2ROVOL_WIDTH 3 /* RI2ROVOL - [6:4] */ + +/* + * R38 (0x26) - Mono out Mix (1) + */ +#define WM8955_LD2MO 0x0100 /* LD2MO */ +#define WM8955_LD2MO_MASK 0x0100 /* LD2MO */ +#define WM8955_LD2MO_SHIFT 8 /* LD2MO */ +#define WM8955_LD2MO_WIDTH 1 /* LD2MO */ +#define WM8955_LI2MO 0x0080 /* LI2MO */ +#define WM8955_LI2MO_MASK 0x0080 /* LI2MO */ +#define WM8955_LI2MO_SHIFT 7 /* LI2MO */ +#define WM8955_LI2MO_WIDTH 1 /* LI2MO */ +#define WM8955_LI2MOVOL_MASK 0x0070 /* LI2MOVOL - [6:4] */ +#define WM8955_LI2MOVOL_SHIFT 4 /* LI2MOVOL - [6:4] */ +#define WM8955_LI2MOVOL_WIDTH 3 /* LI2MOVOL - [6:4] */ +#define WM8955_DMEN 0x0001 /* DMEN */ +#define WM8955_DMEN_MASK 0x0001 /* DMEN */ +#define WM8955_DMEN_SHIFT 0 /* DMEN */ +#define WM8955_DMEN_WIDTH 1 /* DMEN */ + +/* + * R39 (0x27) - Mono out Mix (2) + */ +#define WM8955_RD2MO 0x0100 /* RD2MO */ +#define WM8955_RD2MO_MASK 0x0100 /* RD2MO */ +#define WM8955_RD2MO_SHIFT 8 /* RD2MO */ +#define WM8955_RD2MO_WIDTH 1 /* RD2MO */ +#define WM8955_RI2MO 0x0080 /* RI2MO */ +#define WM8955_RI2MO_MASK 0x0080 /* RI2MO */ +#define WM8955_RI2MO_SHIFT 7 /* RI2MO */ +#define WM8955_RI2MO_WIDTH 1 /* RI2MO */ +#define WM8955_RI2MOVOL_MASK 0x0070 /* RI2MOVOL - [6:4] */ +#define WM8955_RI2MOVOL_SHIFT 4 /* RI2MOVOL - [6:4] */ +#define WM8955_RI2MOVOL_WIDTH 3 /* RI2MOVOL - [6:4] */ + +/* + * R40 (0x28) - LOUT2 volume + */ +#define WM8955_LO2VU 0x0100 /* LO2VU */ +#define WM8955_LO2VU_MASK 0x0100 /* LO2VU */ +#define WM8955_LO2VU_SHIFT 8 /* LO2VU */ +#define WM8955_LO2VU_WIDTH 1 /* LO2VU */ +#define WM8955_LO2ZC 0x0080 /* LO2ZC */ +#define WM8955_LO2ZC_MASK 0x0080 /* LO2ZC */ +#define WM8955_LO2ZC_SHIFT 7 /* LO2ZC */ +#define WM8955_LO2ZC_WIDTH 1 /* LO2ZC */ +#define WM8955_LOUT2VOL_MASK 0x007F /* LOUT2VOL - [6:0] */ +#define WM8955_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [6:0] */ +#define WM8955_LOUT2VOL_WIDTH 7 /* LOUT2VOL - [6:0] */ + +/* + * R41 (0x29) - ROUT2 volume + */ +#define WM8955_RO2VU 0x0100 /* RO2VU */ +#define WM8955_RO2VU_MASK 0x0100 /* RO2VU */ +#define WM8955_RO2VU_SHIFT 8 /* RO2VU */ +#define WM8955_RO2VU_WIDTH 1 /* RO2VU */ +#define WM8955_RO2ZC 0x0080 /* RO2ZC */ +#define WM8955_RO2ZC_MASK 0x0080 /* RO2ZC */ +#define WM8955_RO2ZC_SHIFT 7 /* RO2ZC */ +#define WM8955_RO2ZC_WIDTH 1 /* RO2ZC */ +#define WM8955_ROUT2VOL_MASK 0x007F /* ROUT2VOL - [6:0] */ +#define WM8955_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [6:0] */ +#define WM8955_ROUT2VOL_WIDTH 7 /* ROUT2VOL - [6:0] */ + +/* + * R42 (0x2A) - MONOOUT volume + */ +#define WM8955_MOZC 0x0080 /* MOZC */ +#define WM8955_MOZC_MASK 0x0080 /* MOZC */ +#define WM8955_MOZC_SHIFT 7 /* MOZC */ +#define WM8955_MOZC_WIDTH 1 /* MOZC */ +#define WM8955_MOUTVOL_MASK 0x007F /* MOUTVOL - [6:0] */ +#define WM8955_MOUTVOL_SHIFT 0 /* MOUTVOL - [6:0] */ +#define WM8955_MOUTVOL_WIDTH 7 /* MOUTVOL - [6:0] */ + +/* + * R43 (0x2B) - Clocking / PLL + */ +#define WM8955_MCLKSEL 0x0100 /* MCLKSEL */ +#define WM8955_MCLKSEL_MASK 0x0100 /* MCLKSEL */ +#define WM8955_MCLKSEL_SHIFT 8 /* MCLKSEL */ +#define WM8955_MCLKSEL_WIDTH 1 /* MCLKSEL */ +#define WM8955_PLLOUTDIV2 0x0020 /* PLLOUTDIV2 */ +#define WM8955_PLLOUTDIV2_MASK 0x0020 /* PLLOUTDIV2 */ +#define WM8955_PLLOUTDIV2_SHIFT 5 /* PLLOUTDIV2 */ +#define WM8955_PLLOUTDIV2_WIDTH 1 /* PLLOUTDIV2 */ +#define WM8955_PLL_RB 0x0010 /* PLL_RB */ +#define WM8955_PLL_RB_MASK 0x0010 /* PLL_RB */ +#define WM8955_PLL_RB_SHIFT 4 /* PLL_RB */ +#define WM8955_PLL_RB_WIDTH 1 /* PLL_RB */ +#define WM8955_PLLEN 0x0008 /* PLLEN */ +#define WM8955_PLLEN_MASK 0x0008 /* PLLEN */ +#define WM8955_PLLEN_SHIFT 3 /* PLLEN */ +#define WM8955_PLLEN_WIDTH 1 /* PLLEN */ + +/* + * R44 (0x2C) - PLL Control 1 + */ +#define WM8955_N_MASK 0x01E0 /* N - [8:5] */ +#define WM8955_N_SHIFT 5 /* N - [8:5] */ +#define WM8955_N_WIDTH 4 /* N - [8:5] */ +#define WM8955_K_21_18_MASK 0x000F /* K(21:18) - [3:0] */ +#define WM8955_K_21_18_SHIFT 0 /* K(21:18) - [3:0] */ +#define WM8955_K_21_18_WIDTH 4 /* K(21:18) - [3:0] */ + +/* + * R45 (0x2D) - PLL Control 2 + */ +#define WM8955_K_17_9_MASK 0x01FF /* K(17:9) - [8:0] */ +#define WM8955_K_17_9_SHIFT 0 /* K(17:9) - [8:0] */ +#define WM8955_K_17_9_WIDTH 9 /* K(17:9) - [8:0] */ + +/* + * R46 (0x2E) - PLL Control 3 + */ +#define WM8955_K_8_0_MASK 0x01FF /* K(8:0) - [8:0] */ +#define WM8955_K_8_0_SHIFT 0 /* K(8:0) - [8:0] */ +#define WM8955_K_8_0_WIDTH 9 /* K(8:0) - [8:0] */ + +/* + * R59 (0x3B) - PLL Control 4 + */ +#define WM8955_KEN 0x0080 /* KEN */ +#define WM8955_KEN_MASK 0x0080 /* KEN */ +#define WM8955_KEN_SHIFT 7 /* KEN */ +#define WM8955_KEN_WIDTH 1 /* KEN */ + +#endif -- cgit v1.2.3 From ad8decb7f5dfd556e4a8400e37b127cd20d8e4c5 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 20 Dec 2009 19:01:50 +0100 Subject: ALSA: jazz16: Add support for Media Vision Jazz16 chipset This is one of Sound Blaster Pro compatible chipsets which is supported by Linux OSS driver and was missing native supoort for ALSA. The Jazz16 audio codec is Crystal CS4216 which is capable of playback and recording up to 48 kHz stereo. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- include/sound/sb.h | 1 + sound/isa/Kconfig | 16 ++ sound/isa/sb/Makefile | 2 + sound/isa/sb/jazz16.c | 385 +++++++++++++++++++++++++++++++++++++++++++++++ sound/isa/sb/sb8_main.c | 117 ++++++++++++-- sound/isa/sb/sb_common.c | 3 + sound/isa/sb/sb_mixer.c | 3 + 7 files changed, 511 insertions(+), 16 deletions(-) create mode 100644 sound/isa/sb/jazz16.c (limited to 'include') diff --git a/include/sound/sb.h b/include/sound/sb.h index 4e62ee1e4115..95353542256a 100644 --- a/include/sound/sb.h +++ b/include/sound/sb.h @@ -33,6 +33,7 @@ enum sb_hw_type { SB_HW_20, SB_HW_201, SB_HW_PRO, + SB_HW_JAZZ16, /* Media Vision Jazz16 */ SB_HW_16, SB_HW_16CSP, /* SB16 with CSP chip */ SB_HW_ALS100, /* Avance Logic ALS100 chip */ diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 194af3b01e13..755a0a5f0e3f 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -239,6 +239,22 @@ config SND_INTERWAVE_STB To compile this driver as a module, choose M here: the module will be called snd-interwave-stb. +config SND_JAZZ16 + tristate "Media Vision Jazz16 card and compatibles" + select SND_OPL3_LIB + select SND_MPU401_UART + select SND_SB8_DSP + help + Say Y here to include support for soundcards based on the + Media Vision Jazz16 chipset: digital chip MVD1216 (Jazz16), + codec MVA416 (CS4216) and mixer MVA514 (ICS2514). + Media Vision's Jazz16 cards were sold under names Pro Sonic 16, + Premium 3-D and Pro 3-D. There were also OEMs cards with the + Jazz16 chipset. + + To compile this driver as a module, choose M here: the module + will be called snd-jazz16. + config SND_OPL3SA2 tristate "Yamaha OPL3-SA2/SA3" select SND_OPL3_LIB diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index faeffceb01b7..af3669681788 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -12,6 +12,7 @@ snd-sb16-objs := sb16.o snd-sbawe-objs := sbawe.o emu8000.o snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o snd-es968-objs := es968.o +snd-jazz16-objs := jazz16.o # Toplevel Module Dependency obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o @@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SB8) += snd-sb8.o obj-$(CONFIG_SND_SB16) += snd-sb16.o obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o obj-$(CONFIG_SND_ES968) += snd-es968.o +obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c new file mode 100644 index 000000000000..d52966b75846 --- /dev/null +++ b/sound/isa/sb/jazz16.c @@ -0,0 +1,385 @@ + +/* + * jazz16.c - driver for Media Vision Jazz16 based soundcards. + * Copyright (C) 2009 Krzysztof Helt + * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman. + * Based on OSS Sound Blaster driver. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SNDRV_LEGACY_FIND_FREE_IRQ +#define SNDRV_LEGACY_FIND_FREE_DMA +#include + +#define PFX "jazz16: " + +MODULE_DESCRIPTION("Media Vision Jazz16"); +MODULE_SUPPORTED_DEVICE("{{Media Vision ??? }," + "{RTL,RTL3000}}"); + +MODULE_AUTHOR("Krzysztof Helt "); +MODULE_LICENSE("GPL"); + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; +static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; +static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; +static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; +static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; +static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard."); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard."); +module_param_array(port, long, NULL, 0444); +MODULE_PARM_DESC(port, "Port # for jazz16 driver."); +module_param_array(mpu_port, long, NULL, 0444); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver."); +module_param_array(irq, int, NULL, 0444); +MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver."); +module_param_array(mpu_irq, int, NULL, 0444); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver."); +module_param_array(dma8, int, NULL, 0444); +MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver."); +module_param_array(dma16, int, NULL, 0444); +MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver."); + +#define SB_JAZZ16_WAKEUP 0xaf +#define SB_JAZZ16_SET_PORTS 0x50 +#define SB_DSP_GET_JAZZ_BRD_REV 0xfa +#define SB_JAZZ16_SET_DMAINTR 0xfb +#define SB_DSP_GET_JAZZ_MODEL 0xfe + +struct snd_card_jazz16 { + struct snd_sb *chip; +}; + +static irqreturn_t jazz16_interrupt(int irq, void *chip) +{ + return snd_sb8dsp_interrupt(chip); +} + +static int __devinit jazz16_configure_ports(unsigned long port, + unsigned long mpu_port, int idx) +{ + unsigned char val; + + if (!request_region(0x201, 1, "jazz16 config")) { + snd_printk(KERN_ERR "config port region is already in use.\n"); + return -EBUSY; + } + outb(SB_JAZZ16_WAKEUP - idx, 0x201); + udelay(100); + outb(SB_JAZZ16_SET_PORTS + idx, 0x201); + udelay(100); + val = port & 0x70; + val |= (mpu_port & 0x30) >> 4; + outb(val, 0x201); + + release_region(0x201, 1); + return 0; +} + +static int __devinit jazz16_detect_board(unsigned long port, + unsigned long mpu_port) +{ + int err; + int val; + struct snd_sb chip; + + if (!request_region(port, 0x10, "jazz16")) { + snd_printk(KERN_ERR "I/O port region is already in use.\n"); + return -EBUSY; + } + /* just to call snd_sbdsp_command/reset/get_byte() */ + chip.port = port; + + err = snd_sbdsp_reset(&chip); + if (err < 0) + for (val = 0; val < 4; val++) { + err = jazz16_configure_ports(port, mpu_port, val); + if (err < 0) + break; + + err = snd_sbdsp_reset(&chip); + if (!err) + break; + } + if (err < 0) { + err = -ENODEV; + goto err_unmap; + } + if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) { + err = -EBUSY; + goto err_unmap; + } + val = snd_sbdsp_get_byte(&chip); + if (val >= 0x30) + snd_sbdsp_get_byte(&chip); + + if ((val & 0xf0) != 0x10) { + err = -ENODEV; + goto err_unmap; + } + if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) { + err = -EBUSY; + goto err_unmap; + } + snd_sbdsp_get_byte(&chip); + err = snd_sbdsp_get_byte(&chip); + snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n", + val, err); + + err = 0; + +err_unmap: + release_region(port, 0x10); + return err; +} + +static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq) +{ + static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4, + 0, 2, 5, 0, 0, 0, 0, 6 }; + static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 }; + + if (jazz_dma_bits[chip->dma8] == 0 || + jazz_dma_bits[chip->dma16] == 0 || + jazz_irq_bits[chip->irq] == 0) + return -EINVAL; + + if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR)) + return -EBUSY; + + if (!snd_sbdsp_command(chip, + jazz_dma_bits[chip->dma8] | + (jazz_dma_bits[chip->dma16] << 4))) + return -EBUSY; + + if (!snd_sbdsp_command(chip, + jazz_irq_bits[chip->irq] | + (jazz_irq_bits[mpu_irq] << 4))) + return -EBUSY; + + return 0; +} + +static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev) +{ + if (!enable[dev]) + return 0; + if (port[dev] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "please specify port\n"); + return 0; + } + if (dma16[dev] != SNDRV_AUTO_DMA && + dma16[dev] != 5 && dma16[dev] != 7) { + snd_printk(KERN_ERR "dma16 must be 5 or 7"); + return 0; + } + return 1; +} + +static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev) +{ + struct snd_card *card; + struct snd_card_jazz16 *jazz16; + struct snd_sb *chip; + struct snd_opl3 *opl3; + static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1}; + static int possible_dmas8[] = {1, 3, -1}; + static int possible_dmas16[] = {5, 7, -1}; + int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq; + + err = snd_card_create(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_jazz16), &card); + if (err < 0) + return err; + + jazz16 = card->private_data; + + xirq = irq[dev]; + if (xirq == SNDRV_AUTO_IRQ) { + xirq = snd_legacy_find_free_irq(possible_irqs); + if (xirq < 0) { + snd_printk(KERN_ERR "unable to find a free IRQ\n"); + err = -EBUSY; + goto err_free; + } + } + xdma8 = dma8[dev]; + if (xdma8 == SNDRV_AUTO_DMA) { + xdma8 = snd_legacy_find_free_dma(possible_dmas8); + if (xdma8 < 0) { + snd_printk(KERN_ERR "unable to find a free DMA8\n"); + err = -EBUSY; + goto err_free; + } + } + xdma16 = dma16[dev]; + if (xdma16 == SNDRV_AUTO_DMA) { + xdma16 = snd_legacy_find_free_dma(possible_dmas16); + if (xdma16 < 0) { + snd_printk(KERN_ERR "unable to find a free DMA16\n"); + err = -EBUSY; + goto err_free; + } + } + + xmpu_port = mpu_port[dev]; + if (xmpu_port == SNDRV_AUTO_PORT) + xmpu_port = 0; + err = jazz16_detect_board(port[dev], xmpu_port); + if (err < 0) { + printk(KERN_ERR "Media Vision Jazz16 board not detected\n"); + goto err_free; + } + err = snd_sbdsp_create(card, port[dev], irq[dev], + jazz16_interrupt, + dma8[dev], dma16[dev], + SB_HW_JAZZ16, + &chip); + if (err < 0) + goto err_free; + + xmpu_irq = mpu_irq[dev]; + if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT) + xmpu_irq = 0; + err = jazz16_configure_board(chip, xmpu_irq); + if (err < 0) { + printk(KERN_ERR "Media Vision Jazz16 configuration failed\n"); + goto err_free; + } + + jazz16->chip = chip; + + strcpy(card->driver, "jazz16"); + strcpy(card->shortname, "Media Vision Jazz16"); + sprintf(card->longname, + "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d", + port[dev], xirq, xdma8, xdma16); + + err = snd_sb8dsp_pcm(chip, 0, NULL); + if (err < 0) + goto err_free; + err = snd_sbmixer_new(chip); + if (err < 0) + goto err_free; + + err = snd_opl3_create(card, chip->port, chip->port + 2, + OPL3_HW_AUTO, 1, &opl3); + if (err < 0) + snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", + chip->port, chip->port + 2); + else { + err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (err < 0) + goto err_free; + } + if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { + if (mpu_irq[dev] == SNDRV_AUTO_IRQ) + mpu_irq[dev] = -1; + + if (snd_mpu401_uart_new(card, 0, + MPU401_HW_MPU401, + mpu_port[dev], 0, + mpu_irq[dev], + mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, + NULL) < 0) + snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", + mpu_port[dev]); + } + + snd_card_set_dev(card, devptr); + + err = snd_card_register(card); + if (err < 0) + goto err_free; + + dev_set_drvdata(devptr, card); + return 0; + +err_free: + snd_card_free(card); + return err; +} + +static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev) +{ + struct snd_card *card = dev_get_drvdata(devptr); + + dev_set_drvdata(devptr, NULL); + snd_card_free(card); + return 0; +} + +#ifdef CONFIG_PM +static int snd_jazz16_suspend(struct device *pdev, unsigned int n, + pm_message_t state) +{ + struct snd_card *card = dev_get_drvdata(pdev); + struct snd_card_jazz16 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); + snd_sbmixer_suspend(chip); + return 0; +} + +static int snd_jazz16_resume(struct device *pdev, unsigned int n) +{ + struct snd_card *card = dev_get_drvdata(pdev); + struct snd_card_jazz16 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_sbdsp_reset(chip); + snd_sbmixer_resume(chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + +static struct isa_driver snd_jazz16_driver = { + .match = snd_jazz16_match, + .probe = snd_jazz16_probe, + .remove = __devexit_p(snd_jazz16_remove), +#ifdef CONFIG_PM + .suspend = snd_jazz16_suspend, + .resume = snd_jazz16_resume, +#endif + .driver = { + .name = "jazz16" + }, +}; + +static int __init alsa_card_jazz16_init(void) +{ + return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS); +} + +static void __exit alsa_card_jazz16_exit(void) +{ + isa_unregister_driver(&snd_jazz16_driver); +} + +module_init(alsa_card_jazz16_init) +module_exit(alsa_card_jazz16_exit) diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 658d55769c9c..3222aed5fac6 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -106,9 +106,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) struct snd_sb *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned int mixreg, rate, size, count; + unsigned char format; + unsigned char stereo = runtime->channels > 1; + int dma; rate = runtime->rate; switch (chip->hardware) { + case SB_HW_JAZZ16: + if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { + if (chip->mode & SB_MODE_CAPTURE_16) + return -EBUSY; + else + chip->mode |= SB_MODE_PLAYBACK_16; + } + chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; + break; case SB_HW_PRO: if (runtime->channels > 1) { if (snd_BUG_ON(rate != SB8_RATE(11025) && @@ -133,11 +145,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) default: return -EINVAL; } + if (chip->mode & SB_MODE_PLAYBACK_16) { + format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; + dma = chip->dma16; + } else { + format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; + chip->mode |= SB_MODE_PLAYBACK_8; + dma = chip->dma8; + } size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); spin_lock_irqsave(&chip->reg_lock, flags); snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); - if (runtime->channels > 1) { + if (chip->hardware == SB_HW_JAZZ16) + snd_sbdsp_command(chip, format); + else if (stereo) { /* set playback stereo mode */ spin_lock(&chip->mixer_lock); mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); @@ -147,15 +169,14 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) /* Soundblaster hardware programming reference guide, 3-23 */ snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); runtime->dma_area[0] = 0x80; - snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); + snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); /* force interrupt */ - chip->mode = SB_MODE_HALT; snd_sbdsp_command(chip, SB_DSP_OUTPUT); snd_sbdsp_command(chip, 0); snd_sbdsp_command(chip, 0); } snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); - if (runtime->channels > 1) { + if (stereo) { snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); spin_lock(&chip->mixer_lock); /* save output filter status and turn it off */ @@ -168,13 +189,15 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) snd_sbdsp_command(chip, 256 - runtime->rate_den); } if (chip->playback_format != SB_DSP_OUTPUT) { + if (chip->mode & SB_MODE_PLAYBACK_16) + count /= 2; count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); snd_sbdsp_command(chip, count >> 8); } spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_dma_program(chip->dma8, runtime->dma_addr, + snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); return 0; } @@ -212,7 +235,6 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); } spin_unlock_irqrestore(&chip->reg_lock, flags); - chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT; return 0; } @@ -234,9 +256,21 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) struct snd_sb *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned int mixreg, rate, size, count; + unsigned char format; + unsigned char stereo = runtime->channels > 1; + int dma; rate = runtime->rate; switch (chip->hardware) { + case SB_HW_JAZZ16: + if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { + if (chip->mode & SB_MODE_PLAYBACK_16) + return -EBUSY; + else + chip->mode |= SB_MODE_CAPTURE_16; + } + chip->capture_format = SB_DSP_LO_INPUT_AUTO; + break; case SB_HW_PRO: if (runtime->channels > 1) { if (snd_BUG_ON(rate != SB8_RATE(11025) && @@ -262,14 +296,24 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) default: return -EINVAL; } + if (chip->mode & SB_MODE_CAPTURE_16) { + format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; + dma = chip->dma16; + } else { + format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; + chip->mode |= SB_MODE_CAPTURE_8; + dma = chip->dma8; + } size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); spin_lock_irqsave(&chip->reg_lock, flags); snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); - if (runtime->channels > 1) + if (chip->hardware == SB_HW_JAZZ16) + snd_sbdsp_command(chip, format); + else if (stereo) snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); - if (runtime->channels > 1) { + if (stereo) { snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); spin_lock(&chip->mixer_lock); /* save input filter status and turn it off */ @@ -282,13 +326,15 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) snd_sbdsp_command(chip, 256 - runtime->rate_den); } if (chip->capture_format != SB_DSP_INPUT) { + if (chip->mode & SB_MODE_PLAYBACK_16) + count /= 2; count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); snd_sbdsp_command(chip, count >> 8); } spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_dma_program(chip->dma8, runtime->dma_addr, + snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); return 0; } @@ -328,7 +374,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); } spin_unlock_irqrestore(&chip->reg_lock, flags); - chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT; return 0; } @@ -339,13 +384,21 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) snd_sb_ack_8bit(chip); switch (chip->mode) { - case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ + case SB_MODE_PLAYBACK_16: /* ok.. playback is active */ + if (chip->hardware != SB_HW_JAZZ16) + break; + /* fallthru */ + case SB_MODE_PLAYBACK_8: substream = chip->playback_substream; runtime = substream->runtime; if (chip->playback_format == SB_DSP_OUTPUT) snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); snd_pcm_period_elapsed(substream); break; + case SB_MODE_CAPTURE_16: + if (chip->hardware != SB_HW_JAZZ16) + break; + /* fallthru */ case SB_MODE_CAPTURE_8: substream = chip->capture_substream; runtime = substream->runtime; @@ -361,10 +414,15 @@ static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *subs { struct snd_sb *chip = snd_pcm_substream_chip(substream); size_t ptr; + int dma; - if (chip->mode != SB_MODE_PLAYBACK_8) + if (chip->mode & SB_MODE_PLAYBACK_8) + dma = chip->dma8; + else if (chip->mode & SB_MODE_PLAYBACK_16) + dma = chip->dma16; + else return 0; - ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); + ptr = snd_dma_pointer(dma, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -372,10 +430,15 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst { struct snd_sb *chip = snd_pcm_substream_chip(substream); size_t ptr; + int dma; - if (chip->mode != SB_MODE_CAPTURE_8) + if (chip->mode & SB_MODE_CAPTURE_8) + dma = chip->dma8; + else if (chip->mode & SB_MODE_CAPTURE_16) + dma = chip->dma16; + else return 0; - ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); + ptr = snd_dma_pointer(dma, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -446,6 +509,13 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) runtime->hw = snd_sb8_capture; } switch (chip->hardware) { + case SB_HW_JAZZ16: + runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE; + runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000; + runtime->hw.rate_min = 4000; + runtime->hw.rate_max = 50000; + runtime->hw.channels_max = 2; + break; case SB_HW_PRO: runtime->hw.rate_max = 44100; runtime->hw.channels_max = 2; @@ -468,6 +538,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) } snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_clock); + if (chip->dma8 > 3 || chip->dma16 >= 0) { + snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2); + snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2); + runtime->hw.buffer_bytes_max = 128 * 1024 * 1024; + runtime->hw.period_bytes_max = 128 * 1024 * 1024; + } return 0; } @@ -480,6 +558,10 @@ static int snd_sb8_close(struct snd_pcm_substream *substream) chip->capture_substream = NULL; spin_lock_irqsave(&chip->open_lock, flags); chip->open &= ~SB_OPEN_PCM; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + chip->mode &= ~SB_MODE_PLAYBACK; + else + chip->mode &= ~SB_MODE_CAPTURE; spin_unlock_irqrestore(&chip->open_lock, flags); return 0; } @@ -515,6 +597,7 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) struct snd_card *card = chip->card; struct snd_pcm *pcm; int err; + size_t max_prealloc = 64 * 1024; if (rpcm) *rpcm = NULL; @@ -527,9 +610,11 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); + if (chip->dma8 > 3 || chip->dma16 >= 0) + max_prealloc = 128 * 1024; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(), - 64*1024, 64*1024); + 64*1024, max_prealloc); if (rpcm) *rpcm = pcm; diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 27a651502251..eae6c1c0eff9 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c @@ -170,6 +170,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip) case SB_HW_CS5530: str = "16 (CS5530)"; break; + case SB_HW_JAZZ16: + str = "Pro (Jazz16)"; + break; default: return -ENODEV; } diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 8cfc41fbe368..6496822c1808 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c @@ -779,6 +779,7 @@ int snd_sbmixer_new(struct snd_sb *chip) return err; break; case SB_HW_PRO: + case SB_HW_JAZZ16: if ((err = snd_sbmixer_init(chip, snd_sbpro_controls, ARRAY_SIZE(snd_sbpro_controls), @@ -929,6 +930,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip) save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); break; case SB_HW_PRO: + case SB_HW_JAZZ16: save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); break; case SB_HW_16: @@ -955,6 +957,7 @@ void snd_sbmixer_resume(struct snd_sb *chip) restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); break; case SB_HW_PRO: + case SB_HW_JAZZ16: restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); break; case SB_HW_16: -- cgit v1.2.3 From 41116e926cb92292fa4fcbe888ae8133fa0038e6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Dec 2009 09:00:14 +0100 Subject: ALSA: cs46xx - Fix suspend/resume with new DSP Fix the basic suspend/resume of snd-cs46xx drivers with new DSP. References: https://bugzilla.redhat.com/show_bug.cgi?id=498287 https://bugzilla.redhat.com/show_bug.cgi?id=160751 Tested-by: Florian Zumbiehl Signed-off-by: Takashi Iwai --- include/sound/cs46xx_dsp_spos.h | 6 ++++-- sound/pci/cs46xx/cs46xx_lib.c | 2 +- sound/pci/cs46xx/dsp_spos.c | 42 +++++++++++++++++++++++++++++++++---- sound/pci/cs46xx/dsp_spos.h | 4 ++++ sound/pci/cs46xx/dsp_spos_scb_lib.c | 33 +++++++++++++---------------- 5 files changed, 62 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h index 7c44667e79a6..49b03c9e5e55 100644 --- a/include/sound/cs46xx_dsp_spos.h +++ b/include/sound/cs46xx_dsp_spos.h @@ -118,9 +118,11 @@ struct dsp_scb_descriptor { struct snd_info_entry *proc_info; int ref_count; - spinlock_t lock; - int deleted; + u16 volume[2]; + unsigned int deleted :1; + unsigned int updated :1; + unsigned int volume_set :1; }; struct dsp_task_descriptor { diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 1be96ead4244..e6b4a879ae2e 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -3597,7 +3597,7 @@ static struct cs_card_type __devinitdata cards[] = { #ifdef CONFIG_PM static unsigned int saved_regs[] = { BA0_ACOSV, - BA0_ASER_FADDR, + /*BA0_ASER_FADDR,*/ BA0_ASER_MASTER, BA1_PVOL, BA1_CVOL, diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index f4f0c8f5dad7..3e5ca8fb519f 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -298,6 +298,9 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) if (ins->scbs[i].deleted) continue; cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); +#ifdef CONFIG_PM + kfree(ins->scbs[i].data); +#endif } kfree(ins->code.data); @@ -974,13 +977,11 @@ static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * nam index = find_free_scb_index (ins); + memset(&ins->scbs[index], 0, sizeof(ins->scbs[index])); strcpy(ins->scbs[index].scb_name, name); ins->scbs[index].address = dest; ins->scbs[index].index = index; - ins->scbs[index].proc_info = NULL; ins->scbs[index].ref_count = 1; - ins->scbs[index].deleted = 0; - spin_lock_init(&ins->scbs[index].lock); desc = (ins->scbs + index); ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER); @@ -1022,17 +1023,29 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) return desc; } +#define SCB_BYTES (0x10 * 4) + struct dsp_scb_descriptor * cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest) { struct dsp_scb_descriptor * desc; +#ifdef CONFIG_PM + /* copy the data for resume */ + scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL); + if (!scb_data) + return NULL; +#endif + desc = _map_scb (chip,name,dest); if (desc) { desc->data = scb_data; _dsp_create_scb(chip,scb_data,dest); } else { snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); +#ifdef CONFIG_PM + kfree(scb_data); +#endif } return desc; @@ -1988,7 +2001,28 @@ int cs46xx_dsp_resume(struct snd_cs46xx * chip) continue; _dsp_create_scb(chip, s->data, s->address); } - + for (i = 0; i < ins->nscb; i++) { + struct dsp_scb_descriptor *s = &ins->scbs[i]; + if (s->deleted) + continue; + if (s->updated) + cs46xx_dsp_spos_update_scb(chip, s); + if (s->volume_set) + cs46xx_dsp_scb_set_volume(chip, s, + s->volume[0], s->volume[1]); + } + if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) { + cs46xx_dsp_enable_spdif_hw(chip); + snd_cs46xx_poke(chip, (ins->ref_snoop_scb->address + 2) << 2, + (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10); + if (ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) + cs46xx_poke_via_dsp(chip, SP_SPDOUT_CSUV, + ins->spdif_csuv_stream); + } + if (chip->dsp_spos_instance->spdif_status_in) { + cs46xx_poke_via_dsp(chip, SP_ASER_COUNTDOWN, 0x80000005); + cs46xx_poke_via_dsp(chip, SP_SPDIN_CONTROL, 0x800003ff); + } return 0; } #endif diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h index f9e169d33c03..ca47a8114c7f 100644 --- a/sound/pci/cs46xx/dsp_spos.h +++ b/sound/pci/cs46xx/dsp_spos.h @@ -212,6 +212,7 @@ static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip, (scb->address + SCBsubListPtr) << 2, (scb->sub_list_ptr->address << 0x10) | (scb->next_scb_ptr->address)); + scb->updated = 1; } static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, @@ -222,6 +223,9 @@ static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); + scb->volume_set = 1; + scb->volume[0] = left; + scb->volume[1] = right; } #endif /* __DSP_SPOS_H__ */ #endif /* CONFIG_SND_CS46XX_NEW_DSP */ diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index dd7c41b037b4..00b148a10239 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -115,7 +115,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - unsigned long flags; if ( scb->parent_scb_ptr ) { /* unlink parent SCB */ @@ -153,8 +152,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor scb->next_scb_ptr = ins->the_null_scb; } - spin_lock_irqsave(&chip->reg_lock, flags); - /* update parent first entry in DSP RAM */ cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); @@ -162,7 +159,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor cs46xx_dsp_spos_update_scb(chip,scb); scb->parent_scb_ptr = NULL; - spin_unlock_irqrestore(&chip->reg_lock, flags); } } @@ -197,9 +193,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * goto _end; #endif - spin_lock_irqsave(&scb->lock, flags); + spin_lock_irqsave(&chip->reg_lock, flags); _dsp_unlink_scb (chip,scb); - spin_unlock_irqrestore(&scb->lock, flags); + spin_unlock_irqrestore(&chip->reg_lock, flags); cs46xx_dsp_proc_free_scb_desc(scb); if (snd_BUG_ON(!scb->scb_symbol)) @@ -207,6 +203,10 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * remove_symbol (chip,scb->scb_symbol); ins->scbs[scb->index].deleted = 1; +#ifdef CONFIG_PM + kfree(ins->scbs[scb->index].data); + ins->scbs[scb->index].data = NULL; +#endif if (scb->index < ins->scb_highest_frag_index) ins->scb_highest_frag_index = scb->index; @@ -1508,20 +1508,17 @@ int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip, chip->dsp_spos_instance->npcm_channels <= 0)) return -EIO; - spin_lock(&pcm_channel->src_scb->lock); - + spin_lock_irqsave(&chip->reg_lock, flags); if (pcm_channel->unlinked) { - spin_unlock(&pcm_channel->src_scb->lock); + spin_unlock_irqrestore(&chip->reg_lock, flags); return -EIO; } - spin_lock_irqsave(&chip->reg_lock, flags); pcm_channel->unlinked = 1; - spin_unlock_irqrestore(&chip->reg_lock, flags); _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); + spin_unlock_irqrestore(&chip->reg_lock, flags); - spin_unlock(&pcm_channel->src_scb->lock); return 0; } @@ -1533,10 +1530,10 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; unsigned long flags; - spin_lock(&pcm_channel->src_scb->lock); + spin_lock_irqsave(&chip->reg_lock, flags); if (pcm_channel->unlinked == 0) { - spin_unlock(&pcm_channel->src_scb->lock); + spin_unlock_irqrestore(&chip->reg_lock, flags); return -EIO; } @@ -1552,8 +1549,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; - spin_lock_irqsave(&chip->reg_lock, flags); - /* update SCB entry in DSP RAM */ cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); @@ -1562,8 +1557,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, pcm_channel->unlinked = 0; spin_unlock_irqrestore(&chip->reg_lock, flags); - - spin_unlock(&pcm_channel->src_scb->lock); return 0; } @@ -1596,13 +1589,17 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) { + unsigned long flags; + if (snd_BUG_ON(!src->parent_scb_ptr)) return -EINVAL; /* mute SCB */ cs46xx_dsp_scb_set_volume (chip,src,0,0); + spin_lock_irqsave(&chip->reg_lock, flags); _dsp_unlink_scb (chip,src); + spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } -- cgit v1.2.3 From 4757968dbff3d43f373f08de973014a9bd41ef0a Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 28 Dec 2009 16:15:03 +0100 Subject: ALSA: Release v1.0.22.1 Signed-off-by: Jaroslav Kysela --- include/sound/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/version.h b/include/sound/version.h index 1f5d4872d623..7fed23442db8 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.22" +#define CONFIG_SND_VERSION "1.0.22.1" #define CONFIG_SND_DATE "" -- cgit v1.2.3 From ddf1ffbd40c92ff1e58c45fa96d309788f7beb60 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:04 -0800 Subject: Input: serio - let device core tell us if device was registered No need to keep track of it by ourselves. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 8 ++------ include/linux/serio.h | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 0a278f9f1d3a..d89880450f77 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -577,8 +577,6 @@ static void serio_add_port(struct serio *serio) printk(KERN_ERR "serio: device_add() failed for %s (%s), error: %d\n", serio->phys, serio->name, error); - else - serio->registered = true; } /* @@ -605,10 +603,8 @@ static void serio_destroy_port(struct serio *serio) serio->parent = NULL; } - if (serio->registered) { + if (device_is_registered(&serio->dev)) device_del(&serio->dev); - serio->registered = false; - } list_del_init(&serio->node); serio_remove_pending_events(serio); @@ -995,7 +991,7 @@ irqreturn_t serio_interrupt(struct serio *serio, if (likely(serio->drv)) { ret = serio->drv->interrupt(serio, data, dfl); - } else if (!dfl && serio->registered) { + } else if (!dfl && device_is_registered(&serio->dev)) { serio_rescan(serio); ret = IRQ_HANDLED; } diff --git a/include/linux/serio.h b/include/linux/serio.h index e2f3044d4a4a..d0fb702059cd 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -30,7 +30,6 @@ struct serio { char phys[32]; bool manual_bind; - bool registered; /* port has been fully registered with driver core */ struct serio_device_id id; -- cgit v1.2.3 From 361b7b5b032338361ea88412f1fc45479fdd5859 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:03 -0800 Subject: Input: gameport - let device core tell us if device was registered No need to keep track of it by ourselves. Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/gameport.c | 6 +----- include/linux/gameport.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index ac11be08585e..f9e5f8e1690b 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -561,8 +561,6 @@ static void gameport_add_port(struct gameport *gameport) printk(KERN_ERR "gameport: device_add() failed for %s (%s), error: %d\n", gameport->phys, gameport->name, error); - else - gameport->registered = 1; } /* @@ -584,10 +582,8 @@ static void gameport_destroy_port(struct gameport *gameport) gameport->parent = NULL; } - if (gameport->registered) { + if (device_is_registered(&gameport->dev)) device_del(&gameport->dev); - gameport->registered = 0; - } list_del_init(&gameport->node); diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 1bc08541c2b9..48e68da097f6 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -46,7 +46,6 @@ struct gameport { struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ struct device dev; - unsigned int registered; /* port has been fully registered with driver core */ struct list_head node; }; -- cgit v1.2.3 From 4d96eb255c53ab5e39b37fd4d484ea3dc39ab456 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 20 Dec 2009 11:47:57 +0100 Subject: ALSA: pcm_lib - add possibility to log last 10 DMA ring buffer positions In some debug cases, it might be usefull to see previous ring buffer positions to determine position problems from the lowlevel drivers. Signed-off-by: Jaroslav Kysela --- include/sound/pcm.h | 6 +++ sound/core/pcm.c | 4 ++ sound/core/pcm_lib.c | 140 ++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 127 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index c83a4a79f16b..4e18a6dbe690 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -262,6 +262,8 @@ struct snd_pcm_hw_constraint_list { unsigned int mask; }; +struct snd_pcm_hwptr_log; + struct snd_pcm_runtime { /* -- Status -- */ struct snd_pcm_substream *trigger_master; @@ -340,6 +342,10 @@ struct snd_pcm_runtime { /* -- OSS things -- */ struct snd_pcm_oss_runtime oss; #endif + +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + struct snd_pcm_hwptr_log *hwptr_log; +#endif }; struct snd_pcm_group { /* keep linked substreams */ diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 6884ae031f6f..df57a0e30bf2 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -921,6 +921,10 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) snd_free_pages((void*)runtime->control, PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); kfree(runtime->hw_constraints.rules); +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + if (runtime->hwptr_log) + kfree(runtime->hwptr_log); +#endif kfree(runtime); substream->runtime = NULL; put_pid(substream->pid); diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 9621236b2fef..1990afb8a735 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -126,34 +126,34 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram } } +static void pcm_debug_name(struct snd_pcm_substream *substream, + char *name, size_t len) +{ + snprintf(name, len, "pcmC%dD%d%c:%d", + substream->pcm->card->number, + substream->pcm->device, + substream->stream ? 'c' : 'p', + substream->number); +} + #define XRUN_DEBUG_BASIC (1<<0) #define XRUN_DEBUG_STACK (1<<1) /* dump also stack */ #define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */ #define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */ #define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */ +#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */ +#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */ #ifdef CONFIG_SND_PCM_XRUN_DEBUG + #define xrun_debug(substream, mask) \ ((substream)->pstr->xrun_debug & (mask)) -#else -#define xrun_debug(substream, mask) 0 -#endif #define dump_stack_on_xrun(substream) do { \ if (xrun_debug(substream, XRUN_DEBUG_STACK)) \ dump_stack(); \ } while (0) -static void pcm_debug_name(struct snd_pcm_substream *substream, - char *name, size_t len) -{ - snprintf(name, len, "pcmC%dD%d%c:%d", - substream->pcm->card->number, - substream->pcm->device, - substream->stream ? 'c' : 'p', - substream->number); -} - static void xrun(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -169,6 +169,102 @@ static void xrun(struct snd_pcm_substream *substream) } } +#define hw_ptr_error(substream, fmt, args...) \ + do { \ + if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ + if (printk_ratelimit()) { \ + snd_printd("PCM: " fmt, ##args); \ + } \ + dump_stack_on_xrun(substream); \ + } \ + } while (0) + +#define XRUN_LOG_CNT 10 + +struct hwptr_log_entry { + unsigned long jiffies; + snd_pcm_uframes_t pos; + snd_pcm_uframes_t period_size; + snd_pcm_uframes_t buffer_size; + snd_pcm_uframes_t old_hw_ptr; + snd_pcm_uframes_t hw_ptr_base; + snd_pcm_uframes_t hw_ptr_interrupt; +}; + +struct snd_pcm_hwptr_log { + unsigned int idx; + unsigned int hit: 1; + struct hwptr_log_entry entries[XRUN_LOG_CNT]; +}; + +static void xrun_log(struct snd_pcm_substream *substream, + snd_pcm_uframes_t pos) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_pcm_hwptr_log *log = runtime->hwptr_log; + struct hwptr_log_entry *entry; + + if (log == NULL) { + log = kzalloc(sizeof(*log), GFP_ATOMIC); + if (log == NULL) + return; + runtime->hwptr_log = log; + } else { + if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) + return; + } + entry = &log->entries[log->idx]; + entry->jiffies = jiffies; + entry->pos = pos; + entry->period_size = runtime->period_size; + entry->buffer_size = runtime->buffer_size;; + entry->old_hw_ptr = runtime->status->hw_ptr; + entry->hw_ptr_base = runtime->hw_ptr_base; + entry->hw_ptr_interrupt = runtime->hw_ptr_interrupt;; + log->idx = (log->idx + 1) % XRUN_LOG_CNT; +} + +static void xrun_log_show(struct snd_pcm_substream *substream) +{ + struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log; + struct hwptr_log_entry *entry; + char name[16]; + unsigned int idx; + int cnt; + + if (log == NULL) + return; + if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) + return; + pcm_debug_name(substream, name, sizeof(name)); + for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) { + entry = &log->entries[idx]; + if (entry->period_size == 0) + break; + snd_printd("hwptr log: %s: j=%lu, pos=0x%lx/0x%lx/0x%lx, " + "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", + name, entry->jiffies, (unsigned long)entry->pos, + (unsigned long)entry->period_size, + (unsigned long)entry->buffer_size, + (unsigned long)entry->old_hw_ptr, + (unsigned long)entry->hw_ptr_base, + (unsigned long)entry->hw_ptr_interrupt); + idx++; + idx %= XRUN_LOG_CNT; + } + log->hit = 1; +} + +#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ + +#define xrun_debug(substream, mask) 0 +#define xrun(substream) do { } while (0) +#define hw_ptr_error(substream, fmt, args...) do { } while (0) +#define xrun_log(substream, pos) do { } while (0) +#define xrun_log_show(substream) do { } while (0) + +#endif + static snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime) @@ -182,6 +278,7 @@ snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, if (printk_ratelimit()) { char name[16]; pcm_debug_name(substream, name, sizeof(name)); + xrun_log_show(substream); snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, " "buffer size = 0x%lx, period size = 0x%lx\n", name, pos, runtime->buffer_size, @@ -190,6 +287,8 @@ snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, pos = 0; } pos -= pos % runtime->min_align; + if (xrun_debug(substream, XRUN_DEBUG_LOG)) + xrun_log(substream, pos); return pos; } @@ -220,16 +319,6 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, return 0; } -#define hw_ptr_error(substream, fmt, args...) \ - do { \ - if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ - if (printk_ratelimit()) { \ - snd_printd("PCM: " fmt, ##args); \ - } \ - dump_stack_on_xrun(substream); \ - } \ - } while (0) - static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -270,6 +359,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr) delta += runtime->buffer_size; if (delta < 0) { + xrun_log_show(substream); hw_ptr_error(substream, "Unexpected hw_pointer value " "(stream=%i, pos=%ld, intr_ptr=%ld)\n", @@ -315,6 +405,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) delta = jdelta / (((runtime->period_size * HZ) / runtime->rate) + HZ/100); + xrun_log_show(substream); hw_ptr_error(substream, "hw_ptr skipping! [Q] " "(pos=%ld, delta=%ld, period=%ld, " @@ -334,6 +425,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) } no_jiffies_check: if (delta > runtime->period_size + runtime->period_size / 2) { + xrun_log_show(substream); hw_ptr_error(substream, "Lost interrupts? " "(stream=%i, delta=%ld, intr_ptr=%ld)\n", @@ -397,6 +489,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) if (delta < 0) { delta += runtime->buffer_size; if (delta < 0) { + xrun_log_show(substream); hw_ptr_error(substream, "Unexpected hw_pointer value [2] " "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n", @@ -416,6 +509,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) goto no_jiffies_check; delta -= runtime->delay; if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) { + xrun_log_show(substream); hw_ptr_error(substream, "hw_ptr skipping! " "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n", -- cgit v1.2.3 From f240406babfe1526998e10583ea5eccc2676a433 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 5 Jan 2010 17:19:34 +0100 Subject: ALSA: pcm_lib - cleanup & merge hw_ptr update functions Do general cleanup in snd_pcm_update_hw_ptr*() routines and merge them. The main change is hw_ptr_interrupt variable removal to simplify code logic. This variable can be computed directly from hw_ptr. Ensure that updated hw_ptr is not lower than previous one (it was possible with old code in some obscure situations when interrupt was delayed or the lowlevel driver returns wrong ring buffer position value). Signed-off-by: Jaroslav Kysela --- include/sound/pcm.h | 1 - include/sound/pcm_oss.h | 2 +- sound/core/oss/pcm_oss.c | 32 ++++-- sound/core/pcm_lib.c | 279 ++++++++++++++++------------------------------- sound/core/pcm_native.c | 2 - 5 files changed, 121 insertions(+), 195 deletions(-) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 4e18a6dbe690..fe1b131842be 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -271,7 +271,6 @@ struct snd_pcm_runtime { int overrange; snd_pcm_uframes_t avail_max; snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ - snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h index cc4e226f35fd..760c969d885d 100644 --- a/include/sound/pcm_oss.h +++ b/include/sound/pcm_oss.h @@ -61,7 +61,7 @@ struct snd_pcm_oss_runtime { struct snd_pcm_plugin *plugin_first; struct snd_pcm_plugin *plugin_last; #endif - unsigned int prev_hw_ptr_interrupt; + unsigned int prev_hw_ptr_period; }; struct snd_pcm_oss_file { diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index d9c96353121a..255ad910077a 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -632,6 +632,13 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes) return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); } +static inline +snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime) +{ + snd_pcm_uframes_t ptr = runtime->status->hw_ptr; + return ptr - (ptr % runtime->period_size); +} + /* define extended formats in the recent OSS versions (if any) */ /* linear formats */ #define AFMT_S32_LE 0x00001000 @@ -1102,7 +1109,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) return err; } runtime->oss.prepare = 0; - runtime->oss.prev_hw_ptr_interrupt = 0; + runtime->oss.prev_hw_ptr_period = 0; runtime->oss.period_ptr = 0; runtime->oss.buffer_used = 0; @@ -1950,7 +1957,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file) return result; } -static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) +static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, + snd_pcm_uframes_t hw_ptr) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t appl_ptr; @@ -1986,7 +1994,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr if (runtime->oss.trigger) goto _skip1; if (atomic_read(&psubstream->mmap_count)) - snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); + snd_pcm_oss_simulate_fill(psubstream, + get_hw_ptr_period(runtime)); runtime->oss.trigger = 1; runtime->start_threshold = 1; cmd = SNDRV_PCM_IOCTL_START; @@ -2105,11 +2114,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); if (atomic_read(&substream->mmap_count)) { snd_pcm_sframes_t n; - n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; + delay = get_hw_ptr_period(runtime); + n = delay - runtime->oss.prev_hw_ptr_period; if (n < 0) n += runtime->boundary; info.blocks = n / runtime->period_size; - runtime->oss.prev_hw_ptr_interrupt = delay; + runtime->oss.prev_hw_ptr_period = delay; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) snd_pcm_oss_simulate_fill(substream, delay); info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; @@ -2673,18 +2683,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; if (atomic_read(&substream->mmap_count)) - return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; + return runtime->oss.prev_hw_ptr_period != + get_hw_ptr_period(runtime); else - return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; + return snd_pcm_playback_avail(runtime) >= + runtime->oss.period_frames; } static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; if (atomic_read(&substream->mmap_count)) - return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; + return runtime->oss.prev_hw_ptr_period != + get_hw_ptr_period(runtime); else - return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; + return snd_pcm_capture_avail(runtime) >= + runtime->oss.period_frames; } static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1990afb8a735..70a4f7428d78 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -172,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream) #define hw_ptr_error(substream, fmt, args...) \ do { \ if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ + xrun_log_show(substream); \ if (printk_ratelimit()) { \ snd_printd("PCM: " fmt, ##args); \ } \ @@ -188,7 +189,6 @@ struct hwptr_log_entry { snd_pcm_uframes_t buffer_size; snd_pcm_uframes_t old_hw_ptr; snd_pcm_uframes_t hw_ptr_base; - snd_pcm_uframes_t hw_ptr_interrupt; }; struct snd_pcm_hwptr_log { @@ -220,7 +220,6 @@ static void xrun_log(struct snd_pcm_substream *substream, entry->buffer_size = runtime->buffer_size;; entry->old_hw_ptr = runtime->status->hw_ptr; entry->hw_ptr_base = runtime->hw_ptr_base; - entry->hw_ptr_interrupt = runtime->hw_ptr_interrupt;; log->idx = (log->idx + 1) % XRUN_LOG_CNT; } @@ -241,14 +240,13 @@ static void xrun_log_show(struct snd_pcm_substream *substream) entry = &log->entries[idx]; if (entry->period_size == 0) break; - snd_printd("hwptr log: %s: j=%lu, pos=0x%lx/0x%lx/0x%lx, " - "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", + snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " + "hwptr=%ld/%ld\n", name, entry->jiffies, (unsigned long)entry->pos, (unsigned long)entry->period_size, (unsigned long)entry->buffer_size, (unsigned long)entry->old_hw_ptr, - (unsigned long)entry->hw_ptr_base, - (unsigned long)entry->hw_ptr_interrupt); + (unsigned long)entry->hw_ptr_base); idx++; idx %= XRUN_LOG_CNT; } @@ -265,33 +263,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream) #endif -static snd_pcm_uframes_t -snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, - struct snd_pcm_runtime *runtime) -{ - snd_pcm_uframes_t pos; - - pos = substream->ops->pointer(substream); - if (pos == SNDRV_PCM_POS_XRUN) - return pos; /* XRUN */ - if (pos >= runtime->buffer_size) { - if (printk_ratelimit()) { - char name[16]; - pcm_debug_name(substream, name, sizeof(name)); - xrun_log_show(substream); - snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, " - "buffer size = 0x%lx, period size = 0x%lx\n", - name, pos, runtime->buffer_size, - runtime->period_size); - } - pos = 0; - } - pos -= pos % runtime->min_align; - if (xrun_debug(substream, XRUN_DEBUG_LOG)) - xrun_log(substream, pos); - return pos; -} - static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime) { @@ -319,72 +290,88 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, return 0; } -static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) +static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, + unsigned int in_interrupt) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t pos; - snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_ptr_interrupt, hw_base; + snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base; snd_pcm_sframes_t hdelta, delta; unsigned long jdelta; old_hw_ptr = runtime->status->hw_ptr; - pos = snd_pcm_update_hw_ptr_pos(substream, runtime); + pos = substream->ops->pointer(substream); if (pos == SNDRV_PCM_POS_XRUN) { xrun(substream); return -EPIPE; } - if (xrun_debug(substream, XRUN_DEBUG_PERIODUPDATE)) { - char name[16]; - pcm_debug_name(substream, name, sizeof(name)); - snd_printd("period_update: %s: pos=0x%x/0x%x/0x%x, " - "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", - name, (unsigned int)pos, - (unsigned int)runtime->period_size, - (unsigned int)runtime->buffer_size, - (unsigned long)old_hw_ptr, - (unsigned long)runtime->hw_ptr_base, - (unsigned long)runtime->hw_ptr_interrupt); + if (pos >= runtime->buffer_size) { + if (printk_ratelimit()) { + char name[16]; + pcm_debug_name(substream, name, sizeof(name)); + xrun_log_show(substream); + snd_printd(KERN_ERR "BUG: %s, pos = %ld, " + "buffer size = %ld, period size = %ld\n", + name, pos, runtime->buffer_size, + runtime->period_size); + } + pos = 0; } + pos -= pos % runtime->min_align; + if (xrun_debug(substream, XRUN_DEBUG_LOG)) + xrun_log(substream, pos); hw_base = runtime->hw_ptr_base; new_hw_ptr = hw_base + pos; - hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; - delta = new_hw_ptr - hw_ptr_interrupt; - if (hw_ptr_interrupt >= runtime->boundary) { - hw_ptr_interrupt -= runtime->boundary; - if (hw_base < runtime->boundary / 2) - /* hw_base was already lapped; recalc delta */ - delta = new_hw_ptr - hw_ptr_interrupt; - } - if (delta < 0) { - if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr) - delta += runtime->buffer_size; - if (delta < 0) { - xrun_log_show(substream); - hw_ptr_error(substream, - "Unexpected hw_pointer value " - "(stream=%i, pos=%ld, intr_ptr=%ld)\n", - substream->stream, (long)pos, - (long)hw_ptr_interrupt); -#if 1 - /* simply skipping the hwptr update seems more - * robust in some cases, e.g. on VMware with - * inaccurate timer source - */ - return 0; /* skip this update */ -#else - /* rebase to interrupt position */ - hw_base = new_hw_ptr = hw_ptr_interrupt; - /* align hw_base to buffer_size */ - hw_base -= hw_base % runtime->buffer_size; - delta = 0; -#endif - } else { + if (in_interrupt) { + /* we know that one period was processed */ + /* delta = "expected next hw_ptr" for in_interrupt != 0 */ + delta = old_hw_ptr - (old_hw_ptr % runtime->period_size) + + runtime->period_size; + if (delta > new_hw_ptr) { hw_base += runtime->buffer_size; if (hw_base >= runtime->boundary) hw_base = 0; new_hw_ptr = hw_base + pos; + goto __delta; } } + /* new_hw_ptr might be lower than old_hw_ptr in case when */ + /* pointer crosses the end of the ring buffer */ + if (new_hw_ptr < old_hw_ptr) { + hw_base += runtime->buffer_size; + if (hw_base >= runtime->boundary) + hw_base = 0; + new_hw_ptr = hw_base + pos; + } + __delta: + delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary; + if (xrun_debug(substream, in_interrupt ? + XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { + char name[16]; + pcm_debug_name(substream, name, sizeof(name)); + snd_printd("%s_update: %s: pos=%u/%u/%u, " + "hwptr=%ld/%ld/%ld/%ld\n", + in_interrupt ? "period" : "hwptr", + name, + (unsigned int)pos, + (unsigned int)runtime->period_size, + (unsigned int)runtime->buffer_size, + (unsigned long)delta, + (unsigned long)old_hw_ptr, + (unsigned long)new_hw_ptr, + (unsigned long)runtime->hw_ptr_base); + } + /* something must be really wrong */ + if (delta >= runtime->buffer_size) { + hw_ptr_error(substream, + "Unexpected hw_pointer value %s" + "(stream=%i, pos=%ld, new_hw_ptr=%ld, " + "old_hw_ptr=%ld)\n", + in_interrupt ? "[Q] " : "[P]", + substream->stream, (long)pos, + (long)new_hw_ptr, (long)old_hw_ptr); + return 0; + } /* Do jiffies check only in xrun_debug mode */ if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK)) @@ -396,7 +383,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) */ if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) goto no_jiffies_check; - hdelta = new_hw_ptr - old_hw_ptr; + hdelta = delta; if (hdelta < runtime->delay) goto no_jiffies_check; hdelta -= runtime->delay; @@ -405,45 +392,49 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) delta = jdelta / (((runtime->period_size * HZ) / runtime->rate) + HZ/100); - xrun_log_show(substream); + /* move new_hw_ptr according jiffies not pos variable */ + new_hw_ptr = old_hw_ptr; + /* use loop to avoid checks for delta overflows */ + /* the delta value is small or zero in most cases */ + while (delta > 0) { + new_hw_ptr += runtime->period_size; + if (new_hw_ptr >= runtime->boundary) + new_hw_ptr -= runtime->boundary; + delta--; + } + /* align hw_base to buffer_size */ + hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size); + delta = 0; hw_ptr_error(substream, - "hw_ptr skipping! [Q] " + "hw_ptr skipping! %s" "(pos=%ld, delta=%ld, period=%ld, " - "jdelta=%lu/%lu/%lu)\n", + "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n", + in_interrupt ? "[Q] " : "", (long)pos, (long)hdelta, (long)runtime->period_size, jdelta, - ((hdelta * HZ) / runtime->rate), delta); - hw_ptr_interrupt = runtime->hw_ptr_interrupt + - runtime->period_size * delta; - if (hw_ptr_interrupt >= runtime->boundary) - hw_ptr_interrupt -= runtime->boundary; - /* rebase to interrupt position */ - hw_base = new_hw_ptr = hw_ptr_interrupt; - /* align hw_base to buffer_size */ - hw_base -= hw_base % runtime->buffer_size; - delta = 0; + ((hdelta * HZ) / runtime->rate), delta, + (unsigned long)old_hw_ptr, + (unsigned long)new_hw_ptr); } no_jiffies_check: if (delta > runtime->period_size + runtime->period_size / 2) { - xrun_log_show(substream); hw_ptr_error(substream, - "Lost interrupts? " - "(stream=%i, delta=%ld, intr_ptr=%ld)\n", + "Lost interrupts? %s" + "(stream=%i, delta=%ld, new_hw_ptr=%ld, " + "old_hw_ptr=%ld)\n", + in_interrupt ? "[Q] " : "", substream->stream, (long)delta, - (long)hw_ptr_interrupt); - /* rebase hw_ptr_interrupt */ - hw_ptr_interrupt = - new_hw_ptr - new_hw_ptr % runtime->period_size; + (long)new_hw_ptr, + (long)old_hw_ptr); } - runtime->hw_ptr_interrupt = hw_ptr_interrupt; + + if (runtime->status->hw_ptr == new_hw_ptr) + return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); - if (runtime->status->hw_ptr == new_hw_ptr) - return 0; - runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; runtime->hw_ptr_jiffies = jiffies; @@ -456,83 +447,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) /* CAUTION: call it with irq disabled */ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_uframes_t pos; - snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base; - snd_pcm_sframes_t delta; - unsigned long jdelta; - - old_hw_ptr = runtime->status->hw_ptr; - pos = snd_pcm_update_hw_ptr_pos(substream, runtime); - if (pos == SNDRV_PCM_POS_XRUN) { - xrun(substream); - return -EPIPE; - } - if (xrun_debug(substream, XRUN_DEBUG_HWPTRUPDATE)) { - char name[16]; - pcm_debug_name(substream, name, sizeof(name)); - snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, " - "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", - name, (unsigned int)pos, - (unsigned int)runtime->period_size, - (unsigned int)runtime->buffer_size, - (unsigned long)old_hw_ptr, - (unsigned long)runtime->hw_ptr_base, - (unsigned long)runtime->hw_ptr_interrupt); - } - - hw_base = runtime->hw_ptr_base; - new_hw_ptr = hw_base + pos; - - delta = new_hw_ptr - old_hw_ptr; - jdelta = jiffies - runtime->hw_ptr_jiffies; - if (delta < 0) { - delta += runtime->buffer_size; - if (delta < 0) { - xrun_log_show(substream); - hw_ptr_error(substream, - "Unexpected hw_pointer value [2] " - "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n", - substream->stream, (long)pos, - (long)old_hw_ptr, jdelta); - return 0; - } - hw_base += runtime->buffer_size; - if (hw_base >= runtime->boundary) - hw_base = 0; - new_hw_ptr = hw_base + pos; - } - /* Do jiffies check only in xrun_debug mode */ - if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK)) - goto no_jiffies_check; - if (delta < runtime->delay) - goto no_jiffies_check; - delta -= runtime->delay; - if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) { - xrun_log_show(substream); - hw_ptr_error(substream, - "hw_ptr skipping! " - "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n", - (long)pos, (long)delta, - (long)runtime->period_size, jdelta, - ((delta * HZ) / runtime->rate)); - return 0; - } - no_jiffies_check: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - runtime->silence_size > 0) - snd_pcm_playback_silence(substream, new_hw_ptr); - - if (runtime->status->hw_ptr == new_hw_ptr) - return 0; - - runtime->hw_ptr_base = hw_base; - runtime->status->hw_ptr = new_hw_ptr; - runtime->hw_ptr_jiffies = jiffies; - if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) - snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); - - return snd_pcm_update_hw_ptr_post(substream, runtime); + return snd_pcm_update_hw_ptr0(substream, 0); } /** @@ -1744,7 +1659,7 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) snd_pcm_stream_lock_irqsave(substream, flags); if (!snd_pcm_running(substream) || - snd_pcm_update_hw_ptr_interrupt(substream) < 0) + snd_pcm_update_hw_ptr0(substream, 1) < 0) goto _end; if (substream->timer_running) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 29ab46a12e11..8e777f71717c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1247,8 +1247,6 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) if (err < 0) return err; runtime->hw_ptr_base = 0; - runtime->hw_ptr_interrupt = runtime->status->hw_ptr - - runtime->status->hw_ptr % runtime->period_size; runtime->silence_start = runtime->status->hw_ptr; runtime->silence_filled = 0; return 0; -- cgit v1.2.3 From 1250932e48d3b698415b1f04775433cf1da688d6 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 7 Jan 2010 15:36:31 +0100 Subject: ALSA: pcm_lib - optimize wake_up() calls for PCM I/O As noted by pl bossart , the PCM I/O routines (snd_pcm_lib_write1, snd_pcm_lib_read1) should block wake_up() calls until all samples are not processed. Signed-off-by: Jaroslav Kysela --- include/sound/pcm.h | 3 +++ sound/core/pcm_lib.c | 30 ++++++++++++++++++++---------- sound/core/pcm_native.c | 6 ++++-- 3 files changed, 27 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index fe1b131842be..e26fb3c58037 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -311,6 +311,7 @@ struct snd_pcm_runtime { struct snd_pcm_mmap_control *control; /* -- locking / scheduling -- */ + unsigned int nowake: 1; /* no wakeup (data-copy in progress) */ wait_queue_head_t sleep; struct fasync_struct *fasync; @@ -839,6 +840,8 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream); int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream); int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg); +int snd_pcm_update_state(struct snd_pcm_substream *substream, + struct snd_pcm_runtime *runtime); int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream); int snd_pcm_playback_xrun_check(struct snd_pcm_substream *substream); int snd_pcm_capture_xrun_check(struct snd_pcm_substream *substream); diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 70a4f7428d78..a63226232ef4 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -263,8 +263,8 @@ static void xrun_log_show(struct snd_pcm_substream *substream) #endif -static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, - struct snd_pcm_runtime *runtime) +int snd_pcm_update_state(struct snd_pcm_substream *substream, + struct snd_pcm_runtime *runtime) { snd_pcm_uframes_t avail; @@ -285,7 +285,7 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, return -EPIPE; } } - if (avail >= runtime->control->avail_min) + if (!runtime->nowake && avail >= runtime->control->avail_min) wake_up(&runtime->sleep); return 0; } @@ -441,7 +441,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); - return snd_pcm_update_hw_ptr_post(substream, runtime); + return snd_pcm_update_state(substream, runtime); } /* CAUTION: call it with irq disabled */ @@ -1792,6 +1792,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, goto _end_unlock; } + runtime->nowake = 1; while (size > 0) { snd_pcm_uframes_t frames, appl_ptr, appl_ofs; snd_pcm_uframes_t avail; @@ -1813,15 +1814,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, if (frames > cont) frames = cont; if (snd_BUG_ON(!frames)) { + runtime->nowake = 0; snd_pcm_stream_unlock_irq(substream); return -EINVAL; } appl_ptr = runtime->control->appl_ptr; appl_ofs = appl_ptr % runtime->buffer_size; snd_pcm_stream_unlock_irq(substream); - if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) - goto _end; + err = transfer(substream, appl_ofs, data, offset, frames); snd_pcm_stream_lock_irq(substream); + if (err < 0) + goto _end_unlock; switch (runtime->status->state) { case SNDRV_PCM_STATE_XRUN: err = -EPIPE; @@ -1850,8 +1853,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, } } _end_unlock: + runtime->nowake = 0; + if (xfer > 0 && err >= 0) + snd_pcm_update_state(substream, runtime); snd_pcm_stream_unlock_irq(substream); - _end: return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } @@ -2009,6 +2014,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, goto _end_unlock; } + runtime->nowake = 1; while (size > 0) { snd_pcm_uframes_t frames, appl_ptr, appl_ofs; snd_pcm_uframes_t avail; @@ -2037,15 +2043,17 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, if (frames > cont) frames = cont; if (snd_BUG_ON(!frames)) { + runtime->nowake = 0; snd_pcm_stream_unlock_irq(substream); return -EINVAL; } appl_ptr = runtime->control->appl_ptr; appl_ofs = appl_ptr % runtime->buffer_size; snd_pcm_stream_unlock_irq(substream); - if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) - goto _end; + err = transfer(substream, appl_ofs, data, offset, frames); snd_pcm_stream_lock_irq(substream); + if (err < 0) + goto _end_unlock; switch (runtime->status->state) { case SNDRV_PCM_STATE_XRUN: err = -EPIPE; @@ -2068,8 +2076,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, xfer += frames; } _end_unlock: + runtime->nowake = 0; + if (xfer > 0 && err >= 0) + snd_pcm_update_state(substream, runtime); snd_pcm_stream_unlock_irq(substream); - _end: return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 8e777f71717c..27284f628361 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -516,6 +516,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream, struct snd_pcm_sw_params *params) { struct snd_pcm_runtime *runtime; + int err; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; @@ -540,6 +541,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream, if (params->silence_threshold > runtime->buffer_size) return -EINVAL; } + err = 0; snd_pcm_stream_lock_irq(substream); runtime->tstamp_mode = params->tstamp_mode; runtime->period_step = params->period_step; @@ -553,10 +555,10 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, ULONG_MAX); - wake_up(&runtime->sleep); + err = snd_pcm_update_state(substream, runtime); } snd_pcm_stream_unlock_irq(substream); - return 0; + return err; } static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream, -- cgit v1.2.3 From e03a72e13648ac6277bf2bab6b8324d51f89c0fa Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Mon, 11 Jan 2010 03:21:51 -0500 Subject: block: Stop using byte offsets All callers of the stacking functions use 512-byte sector units rather than byte offsets. Simplify the code so the stacking functions take sectors when specifying data offsets. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- block/blk-settings.c | 26 +++++++++----------------- fs/partitions/check.c | 7 ++++--- include/linux/blkdev.h | 17 +++++------------ 3 files changed, 18 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/block/blk-settings.c b/block/blk-settings.c index 5eeb9e0d256e..78549c723783 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -507,7 +507,7 @@ static unsigned int lcm(unsigned int a, unsigned int b) * blk_stack_limits - adjust queue_limits for stacked devices * @t: the stacking driver limits (top device) * @b: the underlying queue limits (bottom, component device) - * @offset: offset to beginning of data within component device + * @start: first data sector within component device * * Description: * This function is used by stacking drivers like MD and DM to ensure @@ -525,10 +525,9 @@ static unsigned int lcm(unsigned int a, unsigned int b) * the alignment_offset is undefined. */ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, - sector_t offset) + sector_t start) { - sector_t alignment; - unsigned int top, bottom, ret = 0; + unsigned int top, bottom, alignment, ret = 0; t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); @@ -548,7 +547,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->misaligned |= b->misaligned; - alignment = queue_limit_alignment_offset(b, offset); + alignment = queue_limit_alignment_offset(b, start); /* Bottom device has different alignment. Check that it is * compatible with the current top alignment. @@ -611,11 +610,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, /* Discard alignment and granularity */ if (b->discard_granularity) { - unsigned int granularity = b->discard_granularity; - offset &= granularity - 1; - - alignment = (granularity + b->discard_alignment - offset) - & (granularity - 1); + alignment = queue_limit_discard_alignment(b, start); if (t->discard_granularity != 0 && t->discard_alignment != alignment) { @@ -657,7 +652,7 @@ int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev, start += get_start_sect(bdev); - return blk_stack_limits(t, &bq->limits, start << 9); + return blk_stack_limits(t, &bq->limits, start); } EXPORT_SYMBOL(bdev_stack_limits); @@ -668,9 +663,8 @@ EXPORT_SYMBOL(bdev_stack_limits); * @offset: offset to beginning of data within component device * * Description: - * Merges the limits for two queues. Returns 0 if alignment - * didn't change. Returns -1 if adding the bottom device caused - * misalignment. + * Merges the limits for a top level gendisk and a bottom level + * block_device. */ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, sector_t offset) @@ -678,9 +672,7 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, struct request_queue *t = disk->queue; struct request_queue *b = bdev_get_queue(bdev); - offset += get_start_sect(bdev) << 9; - - if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) { + if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; disk_name(disk, 0, top); diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 64bc8998ac9a..e8865c11777f 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -412,9 +412,10 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, pdev = part_to_dev(p); p->start_sect = start; - p->alignment_offset = queue_sector_alignment_offset(disk->queue, start); - p->discard_alignment = queue_sector_discard_alignment(disk->queue, - start); + p->alignment_offset = + queue_limit_alignment_offset(&disk->queue->limits, start); + p->discard_alignment = + queue_limit_discard_alignment(&disk->queue->limits, start); p->nr_sects = len; p->partno = partno; p->policy = get_disk_ro(disk); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 5c8018977efa..ffb13ad35716 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1112,18 +1112,13 @@ static inline int queue_alignment_offset(struct request_queue *q) return q->limits.alignment_offset; } -static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t offset) +static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t sector) { unsigned int granularity = max(lim->physical_block_size, lim->io_min); + unsigned int alignment = (sector << 9) & (granularity - 1); - offset &= granularity - 1; - return (granularity + lim->alignment_offset - offset) & (granularity - 1); -} - -static inline int queue_sector_alignment_offset(struct request_queue *q, - sector_t sector) -{ - return queue_limit_alignment_offset(&q->limits, sector << 9); + return (granularity + lim->alignment_offset - alignment) + & (granularity - 1); } static inline int bdev_alignment_offset(struct block_device *bdev) @@ -1147,10 +1142,8 @@ static inline int queue_discard_alignment(struct request_queue *q) return q->limits.discard_alignment; } -static inline int queue_sector_discard_alignment(struct request_queue *q, - sector_t sector) +static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector_t sector) { - struct queue_limits *lim = &q->limits; unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); return (lim->discard_granularity + lim->discard_alignment - alignment) -- cgit v1.2.3 From 2138301e1687bd4f22aa2b4df4829b6ffdae19bc Mon Sep 17 00:00:00 2001 From: Ilkka Koskinen Date: Fri, 8 Jan 2010 17:48:31 +0200 Subject: ASoC: tpa6130a2: Support for tpa6140's regulators tpa6140a2 uses different names for the regulators. Signed-off-by: Ilkka Koskinen Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- include/sound/tpa6130a2-plat.h | 6 ++++++ sound/soc/codecs/tpa6130a2.c | 22 ++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/sound/tpa6130a2-plat.h b/include/sound/tpa6130a2-plat.h index e8c901e749d8..e29fde6b5cbe 100644 --- a/include/sound/tpa6130a2-plat.h +++ b/include/sound/tpa6130a2-plat.h @@ -23,7 +23,13 @@ #ifndef TPA6130A2_PLAT_H #define TPA6130A2_PLAT_H +enum tpa_model { + TPA6130A2, + TPA6140A2, +}; + struct tpa6130a2_platform_data { + enum tpa_model id; int power_gpio; }; diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 8e98ccfab75c..8b27281e62a1 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -41,6 +41,11 @@ static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = { "Vdd", }; +static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = { + "HPVdd", + "AVdd", +}; + /* This struct is used to save the context */ struct tpa6130a2_data { struct mutex mutex; @@ -420,8 +425,21 @@ static int tpa6130a2_probe(struct i2c_client *client, gpio_direction_output(data->power_gpio, 0); } - for (i = 0; i < ARRAY_SIZE(data->supplies); i++) - data->supplies[i].supply = tpa6130a2_supply_names[i]; + switch (pdata->id) { + case TPA6130A2: + for (i = 0; i < ARRAY_SIZE(data->supplies); i++) + data->supplies[i].supply = tpa6130a2_supply_names[i]; + break; + case TPA6140A2: + for (i = 0; i < ARRAY_SIZE(data->supplies); i++) + data->supplies[i].supply = tpa6140a2_supply_names[i];; + break; + default: + dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", + pdata->id); + for (i = 0; i < ARRAY_SIZE(data->supplies); i++) + data->supplies[i].supply = tpa6130a2_supply_names[i]; + } ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), data->supplies); -- cgit v1.2.3 From 599faa0e264fe2e7f563f87b4aad8c83e9dc46d1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jan 2010 13:29:58 +0000 Subject: genirq: Fix documentation of default chip disable() The documentation says that by default disable() will be chip->mask but in fact default_disable() is a noop. Signed-off-by: Mark Brown LKML-Reference: <1262698198-30392-1-git-send-email-broonie@opensource.wolfsonmicro.com> Signed-off-by: Ingo Molnar --- include/linux/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index 451481c082b5..d13492df57a1 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -90,7 +90,7 @@ struct msi_desc; * @startup: start up the interrupt (defaults to ->enable if NULL) * @shutdown: shut down the interrupt (defaults to ->disable if NULL) * @enable: enable the interrupt (defaults to chip->unmask if NULL) - * @disable: disable the interrupt (defaults to chip->mask if NULL) + * @disable: disable the interrupt * @ack: start of a new interrupt * @mask: mask an interrupt source * @mask_ack: ack and mask an interrupt source -- cgit v1.2.3 From d1458279bf9c575a52fd22818ca19c463f380aba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2010 09:16:52 +0100 Subject: ALSA: Add snd_pci_quirk_lookup_id() Added a new function to look up a quirk entry with the given PCI SSID instead of a pci device pointer. This can be used when the searched ID is overridden for debugging or such a purpose. Signed-off-by: Takashi Iwai --- include/sound/core.h | 3 +++ sound/core/misc.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/sound/core.h b/include/sound/core.h index a61499c22b0b..89e0ac17f44a 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -458,5 +458,8 @@ struct snd_pci_quirk { const struct snd_pci_quirk * snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list); +const struct snd_pci_quirk * +snd_pci_quirk_lookup_id(u16 vendor, u16 device, + const struct snd_pci_quirk *list); #endif /* __SOUND_CORE_H */ diff --git a/sound/core/misc.c b/sound/core/misc.c index 23a032c6d487..3da4f92427d8 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c @@ -101,8 +101,9 @@ EXPORT_SYMBOL_GPL(__snd_printk); #ifdef CONFIG_PCI #include /** - * snd_pci_quirk_lookup - look up a PCI SSID quirk list - * @pci: pci_dev handle + * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list + * @vendor: PCI SSV id + * @device: PCI SSD id * @list: quirk list, terminated by a null entry * * Look through the given quirk list and finds a matching entry @@ -112,18 +113,39 @@ EXPORT_SYMBOL_GPL(__snd_printk); * Returns the matched entry pointer, or NULL if nothing matched. */ const struct snd_pci_quirk * -snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) +snd_pci_quirk_lookup_id(u16 vendor, u16 device, + const struct snd_pci_quirk *list) { const struct snd_pci_quirk *q; for (q = list; q->subvendor; q++) { - if (q->subvendor != pci->subsystem_vendor) + if (q->subvendor != vendor) continue; if (!q->subdevice || - (pci->subsystem_device & q->subdevice_mask) == q->subdevice) + (device & q->subdevice_mask) == q->subdevice) return q; } return NULL; } +EXPORT_SYMBOL(snd_pci_quirk_lookup_id); + +/** + * snd_pci_quirk_lookup - look up a PCI SSID quirk list + * @pci: pci_dev handle + * @list: quirk list, terminated by a null entry + * + * Look through the given quirk list and finds a matching entry + * with the same PCI SSID. When subdevice is 0, all subdevice + * values may match. + * + * Returns the matched entry pointer, or NULL if nothing matched. + */ +const struct snd_pci_quirk * +snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) +{ + return snd_pci_quirk_lookup_id(pci->subsystem_vendor, + pci->subsystem_device, + list); +} EXPORT_SYMBOL(snd_pci_quirk_lookup); #endif -- cgit v1.2.3 From c32d977b8157bf67cdf47729ce7dd054a26eb534 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Jan 2010 14:58:57 +0100 Subject: ALSA: pcm - Call pgprot_noncached() for vmalloc'ed buffers pgprot_noncached() can be set for vmalloc'ed buffers safely, and we'd need non-cached behavior more or less, even for the intermediate ring- buffers. Now snd_pcm_lib_mmap_vmalloc() is added as the common PCM mmap callback that is coupled with snd_pcm_lib_alloc_vmalloc_buffer() & co. Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 4 ++++ sound/core/pcm_native.c | 9 +++++++++ sound/drivers/vx/vx_pcm.c | 2 ++ sound/mips/sgio2audio.c | 3 +++ sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | 1 + sound/usb/ua101.c | 2 ++ sound/usb/usbaudio.c | 2 ++ 7 files changed, 23 insertions(+) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 1d4ca2aae50d..aabf48bb8ee6 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1021,6 +1021,10 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s #define snd_pcm_lib_mmap_iomem NULL #endif +int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, + struct vm_area_struct *area); +#define snd_pcm_lib_mmap_vmalloc snd_pcm_lib_mmap_noncached + static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) { *max = dma < 4 ? 64 * 1024 : 128 * 1024; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 5df0d21f18b3..88fff44702a4 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3176,6 +3176,15 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); #endif /* SNDRV_PCM_INFO_MMAP */ +/* mmap callback with pgprot_noncached */ +int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, + struct vm_area_struct *area) +{ + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); + return snd_pcm_default_mmap(substream, area); +} +EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached); + /* * mmap DMA buffer */ diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index c8385d26a16f..35a2f71a6af5 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -905,6 +905,7 @@ static struct snd_pcm_ops vx_pcm_playback_ops = { .trigger = vx_pcm_trigger, .pointer = vx_pcm_playback_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; @@ -1125,6 +1126,7 @@ static struct snd_pcm_ops vx_pcm_capture_ops = { .trigger = vx_pcm_trigger, .pointer = vx_pcm_capture_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 9b486beeb932..6aff217379d9 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -691,6 +691,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { .trigger = snd_sgio2audio_pcm_trigger, .pointer = snd_sgio2audio_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { @@ -703,6 +704,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { .trigger = snd_sgio2audio_pcm_trigger, .pointer = snd_sgio2audio_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; static struct snd_pcm_ops snd_sgio2audio_capture_ops = { @@ -715,6 +717,7 @@ static struct snd_pcm_ops snd_sgio2audio_capture_ops = { .trigger = snd_sgio2audio_pcm_trigger, .pointer = snd_sgio2audio_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; /* diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index 0afa683c900e..0d668f471620 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -277,6 +277,7 @@ static struct snd_pcm_ops pdacf_pcm_capture_ops = { .trigger = pdacf_pcm_trigger, .pointer = pdacf_pcm_capture_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; diff --git a/sound/usb/ua101.c b/sound/usb/ua101.c index 16dc7bd5e120..4f4ccdf70dd0 100644 --- a/sound/usb/ua101.c +++ b/sound/usb/ua101.c @@ -911,6 +911,7 @@ static struct snd_pcm_ops capture_pcm_ops = { .trigger = capture_pcm_trigger, .pointer = capture_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; static struct snd_pcm_ops playback_pcm_ops = { @@ -923,6 +924,7 @@ static struct snd_pcm_ops playback_pcm_ops = { .trigger = playback_pcm_trigger, .pointer = playback_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; static const struct uac_format_type_i_discrete_descriptor * diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 4ada98e16309..b8e0b8fda607 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1997,6 +1997,7 @@ static struct snd_pcm_ops snd_usb_playback_ops = { .trigger = snd_usb_pcm_playback_trigger, .pointer = snd_usb_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; static struct snd_pcm_ops snd_usb_capture_ops = { @@ -2009,6 +2010,7 @@ static struct snd_pcm_ops snd_usb_capture_ops = { .trigger = snd_usb_pcm_capture_trigger, .pointer = snd_usb_pcm_pointer, .page = snd_pcm_lib_get_vmalloc_page, + .mmap = snd_pcm_lib_mmap_vmalloc, }; -- cgit v1.2.3 From 84740ac19a0aeb87d1dc21e9d7d517f11bd49748 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 19 Jan 2010 08:39:05 +0100 Subject: ASoC: fix compile breakage - add a missing header include Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index ca24e7f7a3f5..061f16d4c878 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -16,6 +16,8 @@ #include +#include + struct snd_pcm_substream; /* -- cgit v1.2.3 From 6aceabb459c07a3fb4873c8306de8143c56241b2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Jan 2010 09:39:36 +0200 Subject: ASoC: tlv320dac33: Burst mode BCLK divider configuration Add possibility to configure the burst mode BCLK divider through platform data structure. The BCLK divider changes the actual speed of the serial bus in burst mode, which is faster than the sampling frequency of the running stream. In this way platforms can experiment with the optimal burst speed without the need to modify the codec driver itself. Signed-off-by: Peter Ujfalusi Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/tlv320dac33-plat.h | 1 + sound/soc/codecs/tlv320dac33.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/sound/tlv320dac33-plat.h b/include/sound/tlv320dac33-plat.h index 5858d06a7ffa..ac0665264bdf 100644 --- a/include/sound/tlv320dac33-plat.h +++ b/include/sound/tlv320dac33-plat.h @@ -15,6 +15,7 @@ struct tlv320dac33_platform_data { int power_gpio; + u8 burst_bclkdiv; }; #endif /* __TLV320DAC33_PLAT_H */ diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index e1aa66ff7f1c..1b35d0cf3364 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -91,6 +91,7 @@ struct tlv320dac33_priv { * this */ enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ unsigned int nsample; /* burst read amount from host */ + u8 burst_bclkdiv; /* BCLK divider value in burst mode */ enum dac33_state state; }; @@ -845,9 +846,18 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a); dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b); - /* BCLK divide ratio */ + /* + * BCLK divide ratio + * 0: 1.5 + * 1: 1 + * 2: 2 + * ... + * 254: 254 + * 255: 255 + */ if (dac33->fifo_mode) - dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3); + dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, + dac33->burst_bclkdiv); else dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); @@ -1239,6 +1249,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, i2c_set_clientdata(client, dac33); dac33->power_gpio = pdata->power_gpio; + dac33->burst_bclkdiv = pdata->burst_bclkdiv; dac33->irq = client->irq; dac33->nsample = NSAMPLE_MAX; /* Disable FIFO use by default */ -- cgit v1.2.3 From 3bf127637e22ddf95e67e10a23c339cee3d52429 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 21 Jan 2010 00:02:36 -0800 Subject: Input: sh_keysc - add mode 4 and mode 5 support Add Mode 4 and Mode 5 support to the SH_KEYSC driver. These modes allow slightly larger key pad matrixes. While at it, make use of resource_size(). Signed-off-by: Magnus Damm Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sh_keysc.c | 6 +++--- include/linux/input/sh_keysc.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 076111fc72d2..25706f802258 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -36,6 +36,8 @@ static const struct { [SH_KEYSC_MODE_1] = { 0, 6, 5 }, [SH_KEYSC_MODE_2] = { 1, 5, 6 }, [SH_KEYSC_MODE_3] = { 2, 4, 7 }, + [SH_KEYSC_MODE_4] = { 3, 6, 6 }, + [SH_KEYSC_MODE_5] = { 4, 6, 7 }, }; struct sh_keysc_priv { @@ -122,8 +124,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) return IRQ_HANDLED; } -#define res_size(res) ((res)->end - (res)->start + 1) - static int __devinit sh_keysc_probe(struct platform_device *pdev) { struct sh_keysc_priv *priv; @@ -164,7 +164,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); pdata = &priv->pdata; - priv->iomem_base = ioremap_nocache(res->start, res_size(res)); + priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); if (priv->iomem_base == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; diff --git a/include/linux/input/sh_keysc.h b/include/linux/input/sh_keysc.h index c211b5cf08e6..2aff38bcf2ba 100644 --- a/include/linux/input/sh_keysc.h +++ b/include/linux/input/sh_keysc.h @@ -1,10 +1,11 @@ #ifndef __SH_KEYSC_H__ #define __SH_KEYSC_H__ -#define SH_KEYSC_MAXKEYS 30 +#define SH_KEYSC_MAXKEYS 42 struct sh_keysc_info { - enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode; + enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3, + SH_KEYSC_MODE_4, SH_KEYSC_MODE_5 } mode; int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */ int delay; int kycr2_delay; -- cgit v1.2.3 From c91a988dc6551c66418690e36b2a23cdb0255da8 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 21 Jan 2010 10:32:15 +0100 Subject: ALSA: pcm_core: Fix wake_up() optimization This change fixes the "ALSA: pcm_lib - optimize wake_up() calls for PCM I/O" commit. New sleeping queue is introduced to separate user space and kernel space wake_ups. runtime->nowake is renamed to twake (transfer wake). Signed-off-by: Jaroslav Kysela --- include/sound/pcm.h | 5 +++-- sound/core/pcm.c | 1 + sound/core/pcm_lib.c | 20 ++++++++++---------- sound/core/pcm_native.c | 3 +++ 4 files changed, 17 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index e26fb3c58037..3bc9bca771ec 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -311,8 +311,9 @@ struct snd_pcm_runtime { struct snd_pcm_mmap_control *control; /* -- locking / scheduling -- */ - unsigned int nowake: 1; /* no wakeup (data-copy in progress) */ - wait_queue_head_t sleep; + unsigned int twake: 1; /* do transfer (!poll) wakeup */ + wait_queue_head_t sleep; /* poll sleep */ + wait_queue_head_t tsleep; /* transfer sleep */ struct fasync_struct *fasync; /* -- private section -- */ diff --git a/sound/core/pcm.c b/sound/core/pcm.c index df57a0e30bf2..0d428d0896db 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -894,6 +894,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, memset((void*)runtime->control, 0, size); init_waitqueue_head(&runtime->sleep); + init_waitqueue_head(&runtime->tsleep); runtime->status->state = SNDRV_PCM_STATE_OPEN; diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 5417f7dce834..e2a817eac2a9 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -285,8 +285,8 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, return -EPIPE; } } - if (!runtime->nowake && avail >= runtime->control->avail_min) - wake_up(&runtime->sleep); + if (avail >= runtime->control->avail_min) + wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); return 0; } @@ -1692,7 +1692,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, long tout; init_waitqueue_entry(&wait, current); - add_wait_queue(&runtime->sleep, &wait); + add_wait_queue(&runtime->tsleep, &wait); for (;;) { if (signal_pending(current)) { err = -ERESTARTSYS; @@ -1735,7 +1735,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, break; } _endloop: - remove_wait_queue(&runtime->sleep, &wait); + remove_wait_queue(&runtime->tsleep, &wait); *availp = avail; return err; } @@ -1794,7 +1794,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, goto _end_unlock; } - runtime->nowake = 1; + runtime->twake = 1; while (size > 0) { snd_pcm_uframes_t frames, appl_ptr, appl_ofs; snd_pcm_uframes_t avail; @@ -1816,7 +1816,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, if (frames > cont) frames = cont; if (snd_BUG_ON(!frames)) { - runtime->nowake = 0; + runtime->twake = 0; snd_pcm_stream_unlock_irq(substream); return -EINVAL; } @@ -1855,7 +1855,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, } } _end_unlock: - runtime->nowake = 0; + runtime->twake = 0; if (xfer > 0 && err >= 0) snd_pcm_update_state(substream, runtime); snd_pcm_stream_unlock_irq(substream); @@ -2016,7 +2016,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, goto _end_unlock; } - runtime->nowake = 1; + runtime->twake = 1; while (size > 0) { snd_pcm_uframes_t frames, appl_ptr, appl_ofs; snd_pcm_uframes_t avail; @@ -2045,7 +2045,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, if (frames > cont) frames = cont; if (snd_BUG_ON(!frames)) { - runtime->nowake = 0; + runtime->twake = 0; snd_pcm_stream_unlock_irq(substream); return -EINVAL; } @@ -2078,7 +2078,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, xfer += frames; } _end_unlock: - runtime->nowake = 0; + runtime->twake = 0; if (xfer > 0 && err >= 0) snd_pcm_update_state(substream, runtime); snd_pcm_stream_unlock_irq(substream); diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 27284f628361..56ec35e8510b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -919,6 +919,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state) runtime->status->state = state; } wake_up(&runtime->sleep); + wake_up(&runtime->tsleep); } static struct action_ops snd_pcm_action_stop = { @@ -1004,6 +1005,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push) SNDRV_TIMER_EVENT_MPAUSE, &runtime->trigger_tstamp); wake_up(&runtime->sleep); + wake_up(&runtime->tsleep); } else { runtime->status->state = SNDRV_PCM_STATE_RUNNING; if (substream->timer) @@ -1061,6 +1063,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state) runtime->status->suspended_state = runtime->status->state; runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; wake_up(&runtime->sleep); + wake_up(&runtime->tsleep); } static struct action_ops snd_pcm_action_suspend = { -- cgit v1.2.3 From a96ca3387382498ec8b501db5acef3ed9eb1bd36 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 19 Jan 2010 22:49:43 +0000 Subject: ASoC: Support turning off bias when the CODEC is idle Currently ASoC always maintains the bias of the CODEC while the system is active. With older mobile CODECs this is required since the outputs are referenced to a non-zero voltage and enabling or disabling this voltage without audible pops or clicks in the output takes too long to do when starting or stopping audio. As a result of features such as ground referenced outputs and class D speaker drivers current generation devices are able to power on and off much more quickly without these system level issues so provide a new flag idle_bias_off in snd_soc_codec which will cause the core to turn off the CODEC bias. The distinction between STANDBY and OFF is still maintained. This is partly for consistency but also allows for potential future extensions such as per-machine overrides or deferring the bias removal. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 2 ++ sound/soc/soc-dapm.c | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index 08909ccd235b..a8768ea7571a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -405,6 +405,8 @@ struct snd_soc_codec { short reg_cache_size; short reg_cache_step; + unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ + /* dapm */ u32 pop_time; struct list_head dapm_widgets; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d8e93749321e..6c3351095786 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1012,13 +1012,28 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) sys_power = 0; break; case SND_SOC_DAPM_STREAM_NOP: - sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; + switch (codec->bias_level) { + case SND_SOC_BIAS_STANDBY: + case SND_SOC_BIAS_OFF: + sys_power = 0; + break; + default: + sys_power = 1; + break; + } break; default: break; } } + if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { + ret = snd_soc_dapm_set_bias_level(socdev, + SND_SOC_BIAS_STANDBY); + if (ret != 0) + pr_err("Failed to turn on bias: %d\n", ret); + } + /* If we're changing to all on or all off then prepare */ if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { @@ -1042,6 +1057,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) pr_err("Failed to apply standby bias: %d\n", ret); } + /* If we're in standby and can support bias off then do that */ + if (codec->bias_level == SND_SOC_BIAS_STANDBY && + codec->idle_bias_off) { + ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); + if (ret != 0) + pr_err("Failed to turn off bias: %d\n", ret); + } + /* If we just powered up then move to active bias */ if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { ret = snd_soc_dapm_set_bias_level(socdev, -- cgit v1.2.3 From 2147d3f00f85c9e993786863d8138694672da01b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 09:08:31 +0800 Subject: ACPICA: Update for new gcc-4 warning options Added several new options for the gcc-4 generation, and updated the source accordingly. This includes some code restructuring to eliminate unreachable code, elimination of some gotos, elimination of unused return values, and some additional casting. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/exconfig.c | 13 +++++-------- drivers/acpi/acpica/hwgpe.c | 6 ++---- drivers/acpi/acpica/nspredef.c | 24 +++++++++++------------- drivers/acpi/acpica/nsrepair2.c | 24 +++++++++--------------- drivers/acpi/acpica/utmutex.c | 16 +++------------- include/acpi/platform/acenv.h | 4 ++-- 6 files changed, 32 insertions(+), 55 deletions(-) (limited to 'include') diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 46adfa541cbc..2ea8daccba1c 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -490,7 +490,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, status = acpi_tb_add_table(&table_desc, &table_index); if (ACPI_FAILURE(status)) { - goto cleanup; + + /* Delete allocated table buffer */ + + acpi_tb_delete_table(&table_desc); + return_ACPI_STATUS(status); } /* @@ -533,13 +537,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, acpi_gbl_table_handler_context); } - cleanup: - if (ACPI_FAILURE(status)) { - - /* Delete allocated table buffer */ - - acpi_tb_delete_table(&table_desc); - } return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index c28c41b3180b..55c4507957bb 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -224,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { - goto unlock_and_exit; + return (status); } if (register_bit & in_byte) { @@ -234,9 +234,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Set return value */ (*event_status) = local_event_status; - - unlock_and_exit: - return (status); + return (AE_OK); } /****************************************************************************** diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d34fa59548f7..309586f5809c 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -1000,27 +1000,25 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, /* Is the object one of the expected types? */ - if (!(return_btype & expected_btypes)) { + if (return_btype & expected_btypes) { - /* Type mismatch -- attempt repair of the returned object */ + /* For reference objects, check that the reference type is correct */ - status = acpi_ns_repair_object(data, expected_btypes, - package_index, - return_object_ptr); - if (ACPI_SUCCESS(status)) { - return (AE_OK); /* Repair was successful */ + if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { + status = acpi_ns_check_reference(data, return_object); } - goto type_error_exit; + + return (status); } - /* For reference objects, check that the reference type is correct */ + /* Type mismatch -- attempt repair of the returned object */ - if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { - status = acpi_ns_check_reference(data, return_object); + status = acpi_ns_repair_object(data, expected_btypes, + package_index, return_object_ptr); + if (ACPI_SUCCESS(status)) { + return (AE_OK); /* Repair was successful */ } - return (status); - type_error_exit: /* Create a string with all expected types for this predefined object */ diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index f13691c1cca5..6d6926466a08 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -93,7 +93,7 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, u32 sort_index, u8 sort_direction, char *sort_key_name); -static acpi_status +static void acpi_ns_sort_list(union acpi_operand_object **elements, u32 count, u32 index, u8 sort_direction); @@ -443,7 +443,6 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, union acpi_operand_object *obj_desc; u32 i; u32 previous_value; - acpi_status status; ACPI_FUNCTION_NAME(ns_check_sorted_list); @@ -494,19 +493,15 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, /* * The list must be sorted in the specified order. If we detect a - * discrepancy, issue a warning and sort the entire list + * discrepancy, sort the entire list. */ if (((sort_direction == ACPI_SORT_ASCENDING) && (obj_desc->integer.value < previous_value)) || ((sort_direction == ACPI_SORT_DESCENDING) && (obj_desc->integer.value > previous_value))) { - status = - acpi_ns_sort_list(return_object->package.elements, - outer_element_count, sort_index, - sort_direction); - if (ACPI_FAILURE(status)) { - return (status); - } + acpi_ns_sort_list(return_object->package.elements, + outer_element_count, sort_index, + sort_direction); data->flags |= ACPI_OBJECT_REPAIRED; @@ -615,15 +610,16 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, * Index - Sort by which package element * sort_direction - Ascending or Descending sort * - * RETURN: Status + * RETURN: None * * DESCRIPTION: Sort the objects that are in a package element list. * - * NOTE: Assumes that all NULL elements have been removed from the package. + * NOTE: Assumes that all NULL elements have been removed from the package, + * and that all elements have been verified to be of type Integer. * *****************************************************************************/ -static acpi_status +static void acpi_ns_sort_list(union acpi_operand_object **elements, u32 count, u32 index, u8 sort_direction) { @@ -652,6 +648,4 @@ acpi_ns_sort_list(union acpi_operand_object **elements, } } } - - return (AE_OK); } diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 80bb65154117..1f58a8824146 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utmutex") /* Local prototypes */ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id); -static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id); +static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id); /******************************************************************************* * @@ -114,7 +114,7 @@ void acpi_ut_mutex_terminate(void) /* Delete each predefined mutex object */ for (i = 0; i < ACPI_NUM_MUTEX; i++) { - (void)acpi_ut_delete_mutex(i); + acpi_ut_delete_mutex(i); } /* Delete the spinlocks */ @@ -146,10 +146,6 @@ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id) ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id); - if (mutex_id > ACPI_MAX_MUTEX) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - if (!acpi_gbl_mutex_info[mutex_id].mutex) { status = acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex); @@ -173,21 +169,15 @@ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id) * ******************************************************************************/ -static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) +static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) { ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id); - if (mutex_id > ACPI_MAX_MUTEX) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex); acpi_gbl_mutex_info[mutex_id].mutex = NULL; acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED; - - return_ACPI_STATUS(AE_OK); } /******************************************************************************* diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index e62f10d9a7d8..fa7689a6fc4b 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -311,8 +311,8 @@ typedef char *va_list; #define ACPI_MEMCMP(s1,s2,n) acpi_ut_memcmp((const char *)(s1), (const char *)(s2), (acpi_size)(n)) #define ACPI_MEMCPY(d,s,n) (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n)) #define ACPI_MEMSET(d,v,n) (void) acpi_ut_memset ((d), (v), (acpi_size)(n)) -#define ACPI_TOUPPER acpi_ut_to_upper -#define ACPI_TOLOWER acpi_ut_to_lower +#define ACPI_TOUPPER(c) acpi_ut_to_upper ((int) (c)) +#define ACPI_TOLOWER(c) acpi_ut_to_lower ((int) (c)) #endif /* ACPI_USE_SYSTEM_CLIBRARY */ -- cgit v1.2.3 From a8357b0c95484b46944728712f8810d3b37bf588 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 22 Jan 2010 19:07:36 +0800 Subject: ACPICA: Update all ACPICA copyrights and signons to 2010 Add 2010 copyright to all module headers and signons, including the Linux header. This affects virtually every file in the ACPICA core subsystem, iASL compiler, and all utilities. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/accommon.h | 2 +- drivers/acpi/acpica/acconfig.h | 2 +- drivers/acpi/acpica/acdebug.h | 2 +- drivers/acpi/acpica/acdispat.h | 2 +- drivers/acpi/acpica/acevents.h | 2 +- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/acpica/achware.h | 2 +- drivers/acpi/acpica/acinterp.h | 2 +- drivers/acpi/acpica/aclocal.h | 2 +- drivers/acpi/acpica/acmacros.h | 2 +- drivers/acpi/acpica/acnamesp.h | 2 +- drivers/acpi/acpica/acobject.h | 2 +- drivers/acpi/acpica/acopcode.h | 2 +- drivers/acpi/acpica/acparser.h | 2 +- drivers/acpi/acpica/acpredef.h | 2 +- drivers/acpi/acpica/acresrc.h | 2 +- drivers/acpi/acpica/acstruct.h | 2 +- drivers/acpi/acpica/actables.h | 2 +- drivers/acpi/acpica/acutils.h | 2 +- drivers/acpi/acpica/amlcode.h | 2 +- drivers/acpi/acpica/amlresrc.h | 2 +- drivers/acpi/acpica/dsfield.c | 2 +- drivers/acpi/acpica/dsinit.c | 2 +- drivers/acpi/acpica/dsmethod.c | 2 +- drivers/acpi/acpica/dsmthdat.c | 2 +- drivers/acpi/acpica/dsobject.c | 2 +- drivers/acpi/acpica/dsopcode.c | 2 +- drivers/acpi/acpica/dsutils.c | 2 +- drivers/acpi/acpica/dswexec.c | 2 +- drivers/acpi/acpica/dswload.c | 2 +- drivers/acpi/acpica/dswscope.c | 2 +- drivers/acpi/acpica/dswstate.c | 2 +- drivers/acpi/acpica/evevent.c | 2 +- drivers/acpi/acpica/evgpe.c | 2 +- drivers/acpi/acpica/evgpeblk.c | 2 +- drivers/acpi/acpica/evmisc.c | 2 +- drivers/acpi/acpica/evregion.c | 2 +- drivers/acpi/acpica/evrgnini.c | 2 +- drivers/acpi/acpica/evsci.c | 2 +- drivers/acpi/acpica/evxface.c | 2 +- drivers/acpi/acpica/evxfevnt.c | 2 +- drivers/acpi/acpica/evxfregn.c | 2 +- drivers/acpi/acpica/exconfig.c | 2 +- drivers/acpi/acpica/exconvrt.c | 2 +- drivers/acpi/acpica/excreate.c | 2 +- drivers/acpi/acpica/exdump.c | 2 +- drivers/acpi/acpica/exfield.c | 2 +- drivers/acpi/acpica/exfldio.c | 2 +- drivers/acpi/acpica/exmisc.c | 2 +- drivers/acpi/acpica/exmutex.c | 2 +- drivers/acpi/acpica/exnames.c | 2 +- drivers/acpi/acpica/exoparg1.c | 2 +- drivers/acpi/acpica/exoparg2.c | 2 +- drivers/acpi/acpica/exoparg3.c | 2 +- drivers/acpi/acpica/exoparg6.c | 2 +- drivers/acpi/acpica/exprep.c | 2 +- drivers/acpi/acpica/exregion.c | 2 +- drivers/acpi/acpica/exresnte.c | 2 +- drivers/acpi/acpica/exresolv.c | 2 +- drivers/acpi/acpica/exresop.c | 2 +- drivers/acpi/acpica/exstore.c | 2 +- drivers/acpi/acpica/exstoren.c | 2 +- drivers/acpi/acpica/exstorob.c | 2 +- drivers/acpi/acpica/exsystem.c | 2 +- drivers/acpi/acpica/exutils.c | 2 +- drivers/acpi/acpica/hwacpi.c | 2 +- drivers/acpi/acpica/hwgpe.c | 2 +- drivers/acpi/acpica/hwregs.c | 2 +- drivers/acpi/acpica/hwsleep.c | 2 +- drivers/acpi/acpica/hwtimer.c | 2 +- drivers/acpi/acpica/hwvalid.c | 2 +- drivers/acpi/acpica/hwxface.c | 2 +- drivers/acpi/acpica/nsaccess.c | 2 +- drivers/acpi/acpica/nsalloc.c | 2 +- drivers/acpi/acpica/nsdump.c | 2 +- drivers/acpi/acpica/nsdumpdv.c | 2 +- drivers/acpi/acpica/nseval.c | 2 +- drivers/acpi/acpica/nsinit.c | 2 +- drivers/acpi/acpica/nsload.c | 2 +- drivers/acpi/acpica/nsnames.c | 2 +- drivers/acpi/acpica/nsobject.c | 2 +- drivers/acpi/acpica/nsparse.c | 2 +- drivers/acpi/acpica/nspredef.c | 2 +- drivers/acpi/acpica/nsrepair.c | 2 +- drivers/acpi/acpica/nsrepair2.c | 2 +- drivers/acpi/acpica/nssearch.c | 2 +- drivers/acpi/acpica/nsutils.c | 2 +- drivers/acpi/acpica/nswalk.c | 2 +- drivers/acpi/acpica/nsxfeval.c | 2 +- drivers/acpi/acpica/nsxfname.c | 2 +- drivers/acpi/acpica/nsxfobj.c | 2 +- drivers/acpi/acpica/psargs.c | 2 +- drivers/acpi/acpica/psloop.c | 2 +- drivers/acpi/acpica/psopcode.c | 2 +- drivers/acpi/acpica/psparse.c | 2 +- drivers/acpi/acpica/psscope.c | 2 +- drivers/acpi/acpica/pstree.c | 2 +- drivers/acpi/acpica/psutils.c | 2 +- drivers/acpi/acpica/pswalk.c | 2 +- drivers/acpi/acpica/psxface.c | 2 +- drivers/acpi/acpica/rsaddr.c | 2 +- drivers/acpi/acpica/rscalc.c | 2 +- drivers/acpi/acpica/rscreate.c | 2 +- drivers/acpi/acpica/rsdump.c | 2 +- drivers/acpi/acpica/rsinfo.c | 2 +- drivers/acpi/acpica/rsio.c | 2 +- drivers/acpi/acpica/rsirq.c | 2 +- drivers/acpi/acpica/rslist.c | 2 +- drivers/acpi/acpica/rsmemory.c | 2 +- drivers/acpi/acpica/rsmisc.c | 2 +- drivers/acpi/acpica/rsutils.c | 2 +- drivers/acpi/acpica/rsxface.c | 2 +- drivers/acpi/acpica/tbfadt.c | 2 +- drivers/acpi/acpica/tbfind.c | 2 +- drivers/acpi/acpica/tbinstal.c | 2 +- drivers/acpi/acpica/tbutils.c | 2 +- drivers/acpi/acpica/tbxface.c | 2 +- drivers/acpi/acpica/tbxfroot.c | 2 +- drivers/acpi/acpica/utalloc.c | 2 +- drivers/acpi/acpica/utcopy.c | 2 +- drivers/acpi/acpica/utdebug.c | 2 +- drivers/acpi/acpica/utdelete.c | 2 +- drivers/acpi/acpica/uteval.c | 2 +- drivers/acpi/acpica/utglobal.c | 2 +- drivers/acpi/acpica/utids.c | 2 +- drivers/acpi/acpica/utinit.c | 2 +- drivers/acpi/acpica/utlock.c | 2 +- drivers/acpi/acpica/utmath.c | 2 +- drivers/acpi/acpica/utmisc.c | 2 +- drivers/acpi/acpica/utmutex.c | 2 +- drivers/acpi/acpica/utobject.c | 2 +- drivers/acpi/acpica/utresrc.c | 2 +- drivers/acpi/acpica/utstate.c | 2 +- drivers/acpi/acpica/utxface.c | 2 +- include/acpi/acexcep.h | 2 +- include/acpi/acnames.h | 2 +- include/acpi/acoutput.h | 2 +- include/acpi/acpi.h | 2 +- include/acpi/acpiosxf.h | 2 +- include/acpi/acpixf.h | 2 +- include/acpi/acrestyp.h | 2 +- include/acpi/actbl.h | 2 +- include/acpi/actbl1.h | 2 +- include/acpi/actbl2.h | 43 +++++++++++++++++++++++++++++++++++++++++ include/acpi/actypes.h | 2 +- include/acpi/platform/acenv.h | 2 +- include/acpi/platform/acgcc.h | 2 +- include/acpi/platform/aclinux.h | 2 +- 148 files changed, 190 insertions(+), 147 deletions(-) (limited to 'include') diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 3b20786cbb0d..3e50c74ed4a1 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index a4471e3d3853..33181ad350d5 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index a4fb001d96f1..48faf3eba9fb 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 6291904be01e..894a0ff2a946 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 0bba148a2c61..13d2b0bc2144 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 29ba66d5a790..f8dd8f250ac4 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 36192f142fbb..5900f135dc6d 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 5db9f2916f7c..c9d7802f9118 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 81e64f478679..2caf141076fc 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 7d9ba6e57554..a4a9519a1288 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 61edb156e8d0..73f9b0c88dd8 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 64062b1be3ee..6d0b4de68cf6 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index dfdf63327885..8c15ff43f42b 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 22881e8ce229..d0bb0fd3e57a 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 57bdaf6ffab1..97116082cb6c 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index eef5bd7a59fa..528bcbaf4ce7 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 7980a26bad35..161bc0e3d70a 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 01c76b8ea7ba..8ff3b741df28 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 3a451a21a3f9..d3ae626cf715 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 4940249f2524..1f484ba228fc 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 7b070e42b7c5..0e5798fcbb19 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 54a225e56a64..effbf1550b03 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index f23fa0be6fc2..abe140318a74 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index e786f9fd767f..721039233aa7 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 0ba19f84ad82..cc343b959540 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 9bc1ba076347..edd7aa238cf1 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index b79978f7bc71..bf980cadb1e8 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index dfa104102926..306c62ab2e88 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index f0280856dc0e..6b76c486d784 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index b40513dd6a6a..140a9d002959 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index 908645e72f03..d1e701709dac 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index e46c821cf572..050df8164165 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index cd55c774e882..c1e6f472d435 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index afacf4416c73..1685ce37dd12 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 247920900187..77670e04812d 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index ce224e1eaa89..e77374d92816 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 5336d911fbf0..654b2833598c 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index ff168052a332..86bd5a7f40d0 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 567b356c85af..8dfbaa96e422 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 2fe0809d4eb2..292c36375de8 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index eed7a38d25f2..8bbde6244908 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index c98aa7c2d67c..541cbc1544d5 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 2ea8daccba1c..cee2bceb2169 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index 51d5f224f9fa..adcaf3b89587 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 02b25d233d99..0aa57d938698 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index de3446372ddc..d39d438ba1e3 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 1588a2d660e7..c9190c784194 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index d7b3b418fb45..dc2f9e8bee6e 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 998eac329937..d29e542bb6df 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 3c456bd575d0..cc8a10268f68 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index ffdae122d94a..679f308c5a89 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 752fe48b2d20..2b2128e52d42 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 85d95c92dfd3..ea115021ee7d 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 253f9e122584..25d1cd35c3e1 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 295542e6bd51..580abbd924dc 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 52fec07064f0..edf62bf5b266 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 2bd83ac57c3a..0cd88f6c95f7 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 607958ff467c..fdc1b27999ef 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index c93b54ce7f78..fdd6a7079b97 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 5c729a9e9131..c5ecd615f145 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 6efd07a4f779..702b9ecfd44b 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 608e838d537e..d4af684620ca 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index 257706e7734f..e972b667b09b 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 3d00b9357233..c6cb6042603c 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 7d41f99f7052..0f2ce9c52f02 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 9af361a191e7..679a112a7d26 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 55c4507957bb..bd72319a38f0 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 15c9ed2be853..ec7fc227b33f 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index cc22f9a585b0..5e6d4dbb8024 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 6b282e85d039..ce0cbbc18ad0 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index ec33f270c5b7..e26c17d4b716 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 647c7b6e6756..50cc3be77724 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index d622ba770000..aa2b80132d0a 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 8a58a1b85aa0..982269c1fa48 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index e37836e27e29..0689d36638d9 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 36be7f0e97ec..d2a97921e249 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index af9fe9103734..f52829cc294b 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 4f8abac231d2..9bd6f050f299 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index a7234e60e985..df18be94fefe 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 8f9a4875ce26..959372451635 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 60f3af08d28c..41a9213dd5af 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 662a4bd5b621..27cda52c76bc 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 309586f5809c..ba1072fb0daa 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 4fd1bdb056b2..c82060fd3821 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 6d6926466a08..29ff5d14e1d5 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 7e865639a928..08f8b3f5ccaa 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 47d91e668a1b..24d05a87a2a3 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index d7e6b52b4482..00e79fb26029 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index f0c0892bc7e5..c5a5357c69e6 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index e611dd961b20..b01e45a415e3 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 0cc6ba01a495..eafef24ea448 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index b161f3544b51..6aa6a1a4d918 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 0988e4a8901d..59aabaeab1d3 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index 3bc3a60194d6..2b0c3be2b1b8 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 4df8f139026c..8d81542194d4 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 2feca5ca9581..40e2b279ea12 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index 4d3389118ec3..d4b970c3630b 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index e636e078ad3d..fe29eee5adb1 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index 78b8b791f2ae..8abb9629443d 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index d0c1b91eb8ca..6064dd4e94c2 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index 1e437bfd8db5..226c806ae986 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 3c4dcc3d1069..d6ebf7ec622d 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index a3c23d686d5f..61a038dbfe23 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index 3f0ca5a12d34..f859b0386fe4 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 77b25fdb459c..1fd868b964fd 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index 35a49aa95609..33bff17c0bbc 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 2e0256983aa6..545da40d7fa7 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 1b1dbc69f087..fd057c72d252 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index ddc76cebdc92..887b8ba8c432 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index 5bc49a553284..07de352fa443 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index bc03d5966829..22cfcfbd9fff 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index f27feb4772f6..9f6a6e7e1c8e 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index c016335fb759..f43fbe0fc3fc 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 1054dfd49207..e252180ce61c 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 63e82329a9e8..7ec02b0f69e0 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 1f15497f00d1..02723a9fb10c 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index a88f02bd6c94..5217a6159a31 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 85ea834199e2..dda6e8c497d3 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 7580f6b3069e..3d706b8fd449 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index f857c5efb79f..97ec3621e71d 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 527d729f6815..e156915fa0e8 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index 96e26e70c63d..16b51c69606a 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 5d54e36ab453..f4c5ee8109bc 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 3f2c68f4e959..49286a39b09e 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index 52eaae404554..1397fadd0d4b 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 9d0919ebf7b0..a39c93dac719 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index 25e03120686d..b081cd46a15f 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index c9f682d640ef..7cfa1d8164d0 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 6c6a5137b728..fb55924e6e0f 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 1f58a8824146..55d014ed6d55 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index 42e658b543f1..3356f0cb0745 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 91b7c00236f4..7965919000b1 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index 0440c958f5a4..d35d109b8da2 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index b1f5f680bc78..db9d8ca57987 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 473d584b1d31..5b2e5e80ecb0 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index c1343a9265fa..9cf736ea4691 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index d814da4b5365..d7726685797e 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index 472b7bf0c5d4..a091cabca4b1 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index eb0e7189075f..c7e9431e16f1 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -8,7 +8,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 86e9735a96bd..2bf965ac06da 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acrestyp.h b/include/acpi/acrestyp.h index 9ffe00feada6..dc6302e94793 100644 --- a/include/acpi/acrestyp.h +++ b/include/acpi/acrestyp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 1b6587952604..ad2001683ba7 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 0b9b430b092b..c637b75b9f3f 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index 6f3dce9991e1..5b02e307bff3 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -1,3 +1,46 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2010, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + #ifndef __ACTBL2_H__ #define __ACTBL2_H__ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 153f12dc3373..4e65c201dcd4 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index fa7689a6fc4b..c05aeba9e8f0 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 6aadbf84ae71..0cd53e3cd1a3 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 09469971472f..e5039a2856f8 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 5df7e6cb42da36c7d878239bebc81907b15f3943 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 10:06:32 +0800 Subject: ACPICA: Remove obsolete ACPI_INTEGER (acpi_integer) type This type was introduced as the code was migrated from ACPI 1.0 (with 32-bit AML integers) to ACPI 2.0 (with 64-bit integers). It is now obsolete and this change removes it from the ACPICA code base, replaced by u64. The original typedef has been retained for now for compatibility with existing device driver code. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acevents.h | 3 +-- drivers/acpi/acpica/acinterp.h | 42 ++++++++++++++----------------- drivers/acpi/acpica/aclocal.h | 2 +- drivers/acpi/acpica/acmacros.h | 12 ++++----- drivers/acpi/acpica/acobject.h | 2 +- drivers/acpi/acpica/acutils.h | 20 ++++++--------- drivers/acpi/acpica/dsfield.c | 10 ++++---- drivers/acpi/acpica/dsobject.c | 2 +- drivers/acpi/acpica/evregion.c | 5 ++-- drivers/acpi/acpica/evrgnini.c | 2 +- drivers/acpi/acpica/exconfig.c | 2 +- drivers/acpi/acpica/exconvrt.c | 19 ++++++-------- drivers/acpi/acpica/exfield.c | 7 +++--- drivers/acpi/acpica/exfldio.c | 57 +++++++++++++++++++----------------------- drivers/acpi/acpica/exmisc.c | 10 +++----- drivers/acpi/acpica/exoparg1.c | 14 +++++------ drivers/acpi/acpica/exoparg2.c | 4 +-- drivers/acpi/acpica/exoparg3.c | 2 +- drivers/acpi/acpica/exoparg6.c | 8 +++--- drivers/acpi/acpica/exregion.c | 33 +++++++++++------------- drivers/acpi/acpica/exsystem.c | 2 +- drivers/acpi/acpica/exutils.c | 22 ++++++++-------- drivers/acpi/acpica/hwtimer.c | 2 +- drivers/acpi/acpica/psargs.c | 2 +- drivers/acpi/acpica/rscreate.c | 2 +- drivers/acpi/acpica/utdebug.c | 3 +-- drivers/acpi/acpica/uteval.c | 2 +- drivers/acpi/acpica/utglobal.c | 2 +- drivers/acpi/acpica/utmath.c | 25 ++++++++---------- drivers/acpi/acpica/utmisc.c | 14 +++++------ include/acpi/acpiosxf.h | 4 +-- include/acpi/acrestyp.h | 2 +- include/acpi/actypes.h | 27 ++++++++++++-------- 33 files changed, 169 insertions(+), 196 deletions(-) (limited to 'include') diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 13d2b0bc2144..31056bc89774 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -139,8 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void); acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, - u32 region_offset, - u32 bit_width, acpi_integer * value); + u32 region_offset, u32 bit_width, u64 *value); acpi_status acpi_ev_attach_region(union acpi_operand_object *handler_obj, diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index c9d7802f9118..6df3f8428168 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -129,18 +129,17 @@ acpi_ex_common_buffer_setup(union acpi_operand_object *obj_desc, acpi_status acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, - acpi_integer mask, - acpi_integer field_value, - u32 field_datum_byte_offset); + u64 mask, + u64 field_value, u32 field_datum_byte_offset); void -acpi_ex_get_buffer_datum(acpi_integer * datum, +acpi_ex_get_buffer_datum(u64 *datum, void *buffer, u32 buffer_length, u32 byte_granularity, u32 buffer_offset); void -acpi_ex_set_buffer_datum(acpi_integer merged_datum, +acpi_ex_set_buffer_datum(u64 merged_datum, void *buffer, u32 buffer_length, u32 byte_granularity, u32 buffer_offset); @@ -168,8 +167,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, acpi_status acpi_ex_access_region(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer * value, u32 read_write); + u32 field_datum_byte_offset, u64 *value, u32 read_write); /* * exmisc - misc support routines @@ -193,16 +191,14 @@ acpi_ex_do_concatenate(union acpi_operand_object *obj_desc, acpi_status acpi_ex_do_logical_numeric_op(u16 opcode, - acpi_integer integer0, - acpi_integer integer1, u8 * logical_result); + u64 integer0, u64 integer1, u8 *logical_result); acpi_status acpi_ex_do_logical_op(u16 opcode, union acpi_operand_object *operand0, - union acpi_operand_object *operand1, u8 * logical_result); + union acpi_operand_object *operand1, u8 *logical_result); -acpi_integer -acpi_ex_do_math_op(u16 opcode, acpi_integer operand0, acpi_integer operand1); +u64 acpi_ex_do_math_op(u16 opcode, u64 operand0, u64 operand1); acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state); @@ -278,7 +274,7 @@ acpi_status acpi_ex_system_do_notify_op(union acpi_operand_object *value, union acpi_operand_object *obj_desc); -acpi_status acpi_ex_system_do_suspend(acpi_integer time); +acpi_status acpi_ex_system_do_suspend(u64 time); acpi_status acpi_ex_system_do_stall(u32 time); @@ -461,9 +457,9 @@ void acpi_ex_acquire_global_lock(u32 rule); void acpi_ex_release_global_lock(u32 rule); -void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id); +void acpi_ex_eisa_id_to_string(char *dest, u64 compressed_id); -void acpi_ex_integer_to_string(char *dest, acpi_integer value); +void acpi_ex_integer_to_string(char *dest, u64 value); /* * exregion - default op_region handlers @@ -472,7 +468,7 @@ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); @@ -480,35 +476,35 @@ acpi_status acpi_ex_system_io_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_pci_config_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_cmos_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_pci_bar_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_embedded_controller_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); @@ -516,14 +512,14 @@ acpi_status acpi_ex_sm_bus_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_data_table_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); #endif /* __INTERP_H__ */ diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 681205c75563..4894decfdcf5 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -650,7 +650,7 @@ struct acpi_opcode_info { }; union acpi_parse_value { - acpi_integer integer; /* Integer constant (Up to 64 bits) */ + u64 integer; /* Integer constant (Up to 64 bits) */ struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */ u32 size; /* bytelist or field size */ char *string; /* NULL terminated string */ diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index a4a9519a1288..9894929a2abb 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -272,8 +272,8 @@ * MASK_BITS_ABOVE creates a mask starting AT the position and above * MASK_BITS_BELOW creates a mask starting one bit BELOW the position */ -#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((u32) (position)))) -#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((u32) (position))) +#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_UINT64_MAX) << ((u32) (position)))) +#define ACPI_MASK_BITS_BELOW(position) ((ACPI_UINT64_MAX) << ((u32) (position))) /* Bitfields within ACPI registers */ @@ -414,16 +414,16 @@ acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) _s); \ return (_s); }) #define return_VALUE(s) ACPI_DO_WHILE0 ({ \ - register acpi_integer _s = (s); \ + register u64 _s = (s); \ acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ return (_s); }) #define return_UINT8(s) ACPI_DO_WHILE0 ({ \ register u8 _s = (u8) (s); \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \ return (_s); }) #define return_UINT32(s) ACPI_DO_WHILE0 ({ \ register u32 _s = (u32) (s); \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \ return (_s); }) #else /* Use original less-safe macros */ @@ -434,7 +434,7 @@ acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) (s)); \ return((s)); }) #define return_VALUE(s) ACPI_DO_WHILE0 ({ \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) (s)); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) (s)); \ return((s)); }) #define return_UINT8(s) return_VALUE(s) #define return_UINT32(s) return_VALUE(s) diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 6d0b4de68cf6..3b5d8bf51251 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -111,7 +111,7 @@ ACPI_OBJECT_COMMON_HEADER}; struct acpi_object_integer { ACPI_OBJECT_COMMON_HEADER u8 fill[3]; /* Prevent warning on some compilers */ - acpi_integer value; + u64 value; }; /* diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index d3ae626cf715..35df755251ce 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -134,7 +134,7 @@ char *acpi_ut_get_region_name(u8 space_id); char *acpi_ut_get_event_name(u32 event_id); -char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position); +char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); u8 acpi_ut_valid_object_type(acpi_object_type type); @@ -279,8 +279,7 @@ acpi_ut_status_exit(u32 line_number, void acpi_ut_value_exit(u32 line_number, const char *function_name, - const char *module_name, - u32 component_id, acpi_integer value); + const char *module_name, u32 component_id, u64 value); void acpi_ut_ptr_exit(u32 line_number, @@ -324,7 +323,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, - acpi_integer *value); + u64 *value); acpi_status acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags); @@ -437,14 +436,12 @@ void acpi_ut_delete_generic_state(union acpi_generic_state *state); * utmath */ acpi_status -acpi_ut_divide(acpi_integer in_dividend, - acpi_integer in_divisor, - acpi_integer * out_quotient, acpi_integer * out_remainder); +acpi_ut_divide(u64 in_dividend, + u64 in_divisor, u64 *out_quotient, u64 *out_remainder); acpi_status -acpi_ut_short_divide(acpi_integer in_dividend, - u32 divisor, - acpi_integer * out_quotient, u32 * out_remainder); +acpi_ut_short_divide(u64 in_dividend, + u32 divisor, u64 *out_quotient, u32 *out_remainder); /* * utmisc @@ -474,8 +471,7 @@ acpi_name acpi_ut_repair_name(char *name); u8 acpi_ut_valid_acpi_char(char character, u32 position); -acpi_status -acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); void ACPI_INTERNAL_VAR_XFACE acpi_ut_predefined_warning(const char *module_name, diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index effbf1550b03..bb13817e0c31 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -220,7 +220,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, union acpi_parse_object *arg) { acpi_status status; - acpi_integer position; + u64 position; ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); @@ -240,8 +240,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, switch (arg->common.aml_opcode) { case AML_INT_RESERVEDFIELD_OP: - position = (acpi_integer) info->field_bit_position - + (acpi_integer) arg->common.value.size; + position = (u64) info->field_bit_position + + (u64) arg->common.value.size; if (position > ACPI_UINT32_MAX) { ACPI_ERROR((AE_INFO, @@ -305,8 +305,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, /* Keep track of bit position for the next field */ - position = (acpi_integer) info->field_bit_position - + (acpi_integer) arg->common.value.size; + position = (u64) info->field_bit_position + + (u64) arg->common.value.size; if (position > ACPI_UINT32_MAX) { ACPI_ERROR((AE_INFO, diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index edd7aa238cf1..891e08bf560b 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -684,7 +684,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, case AML_ONES_OP: - obj_desc->integer.value = ACPI_INTEGER_MAX; + obj_desc->integer.value = ACPI_UINT64_MAX; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 654b2833598c..98fd210e87b2 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -329,7 +329,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) * region_offset - Where in the region to read or write * bit_width - Field width in bits (8, 16, 32, or 64) * Value - Pointer to in or out value, must be - * full 64-bit acpi_integer + * a full 64-bit integer * * RETURN: Status * @@ -341,8 +341,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, - u32 region_offset, - u32 bit_width, acpi_integer * value) + u32 region_offset, u32 bit_width, u64 *value) { acpi_status status; acpi_adr_space_handler handler; diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 86bd5a7f40d0..2e3b0334072f 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -168,7 +168,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, void *handler_context, void **region_context) { acpi_status status = AE_OK; - acpi_integer pci_value; + u64 pci_value; struct acpi_pci_id *pci_id = *region_context; union acpi_operand_object *handler_obj; struct acpi_namespace_node *parent_node; diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index cee2bceb2169..7e8b3bedc376 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -284,7 +284,7 @@ static acpi_status acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) { acpi_status status; - acpi_integer value; + u64 value; u32 region_offset = 0; u32 i; diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index adcaf3b89587..bda7aed0404b 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -51,8 +51,7 @@ ACPI_MODULE_NAME("exconvrt") /* Local prototypes */ static u32 -acpi_ex_convert_to_ascii(acpi_integer integer, - u16 base, u8 * string, u8 max_length); +acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length); /******************************************************************************* * @@ -75,7 +74,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, { union acpi_operand_object *return_desc; u8 *pointer; - acpi_integer result; + u64 result; u32 i; u32 count; acpi_status status; @@ -155,7 +154,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, * Little endian is used, meaning that the first byte of the buffer * is the LSB of the integer */ - result |= (((acpi_integer) pointer[i]) << (i * 8)); + result |= (((u64) pointer[i]) << (i * 8)); } break; @@ -285,10 +284,9 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, ******************************************************************************/ static u32 -acpi_ex_convert_to_ascii(acpi_integer integer, - u16 base, u8 * string, u8 data_width) +acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width) { - acpi_integer digit; + u64 digit; u32 i; u32 j; u32 k = 0; @@ -531,10 +529,9 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, * (separated by commas or spaces) */ for (i = 0; i < obj_desc->buffer.length; i++) { - new_buf += acpi_ex_convert_to_ascii((acpi_integer) - obj_desc->buffer. - pointer[i], base, - new_buf, 1); + new_buf += acpi_ex_convert_to_ascii((u64) obj_desc-> + buffer.pointer[i], + base, new_buf, 1); *new_buf++ = separator; /* each separated by a comma or space */ } diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index c9190c784194..6c79fecbee42 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -130,7 +130,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, /* Call the region handler for the read */ status = acpi_ex_access_region(obj_desc, 0, - ACPI_CAST_PTR(acpi_integer, + ACPI_CAST_PTR(u64, buffer_desc-> buffer.pointer), function); @@ -141,7 +141,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, /* * Allocate a buffer for the contents of the field. * - * If the field is larger than the size of an acpi_integer, create + * If the field is larger than the current integer width, create * a BUFFER to hold it. Otherwise, use an INTEGER. This allows * the use of arithmetic operators on the returned value if the * field size is equal or smaller than an Integer. @@ -306,8 +306,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, * same buffer) */ status = acpi_ex_access_region(obj_desc, 0, - (acpi_integer *) buffer, - function); + (u64 *) buffer, function); acpi_ex_release_global_lock(obj_desc->common_field.field_flags); *result_desc = buffer_desc; diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index dc2f9e8bee6e..f68a216168be 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -55,11 +55,10 @@ ACPI_MODULE_NAME("exfldio") static acpi_status acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, u32 field_datum_byte_offset, - acpi_integer * value, u32 read_write); + u64 *value, u32 read_write); static u8 -acpi_ex_register_overflow(union acpi_operand_object *obj_desc, - acpi_integer value); +acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value); static acpi_status acpi_ex_setup_region(union acpi_operand_object *obj_desc, @@ -212,7 +211,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * field_datum_byte_offset - Byte offset of this datum within the * parent field * Value - Where to store value (must at least - * the size of acpi_integer) + * 64 bits) * Function - Read or Write flag plus other region- * dependent flags * @@ -224,8 +223,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, acpi_status acpi_ex_access_region(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer * value, u32 function) + u32 field_datum_byte_offset, u64 *value, u32 function) { acpi_status status; union acpi_operand_object *rgn_desc; @@ -317,8 +315,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, ******************************************************************************/ static u8 -acpi_ex_register_overflow(union acpi_operand_object *obj_desc, - acpi_integer value) +acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value) { if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) { @@ -329,7 +326,7 @@ acpi_ex_register_overflow(union acpi_operand_object *obj_desc, return (FALSE); } - if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) { + if (value >= ((u64) 1 << obj_desc->common_field.bit_length)) { /* * The Value is larger than the maximum value that can fit into * the register. @@ -362,11 +359,10 @@ acpi_ex_register_overflow(union acpi_operand_object *obj_desc, static acpi_status acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer * value, u32 read_write) + u32 field_datum_byte_offset, u64 *value, u32 read_write) { acpi_status status; - acpi_integer local_value; + u64 local_value; ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset); @@ -439,8 +435,8 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, * the register */ if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj, - (acpi_integer) obj_desc-> - bank_field.value)) { + (u64) obj_desc->bank_field. + value)) { return_ACPI_STATUS(AE_AML_REGISTER_LIMIT); } @@ -481,8 +477,8 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, * the register */ if (acpi_ex_register_overflow(obj_desc->index_field.index_obj, - (acpi_integer) obj_desc-> - index_field.value)) { + (u64) obj_desc->index_field. + value)) { return_ACPI_STATUS(AE_AML_REGISTER_LIMIT); } @@ -512,7 +508,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, status = acpi_ex_extract_from_field(obj_desc->index_field. data_obj, value, - sizeof(acpi_integer)); + sizeof(u64)); } else { /* Write the datum to the data_register */ @@ -523,7 +519,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, status = acpi_ex_insert_into_field(obj_desc->index_field. data_obj, value, - sizeof(acpi_integer)); + sizeof(u64)); } break; @@ -571,13 +567,12 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, acpi_status acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, - acpi_integer mask, - acpi_integer field_value, - u32 field_datum_byte_offset) + u64 mask, + u64 field_value, u32 field_datum_byte_offset) { acpi_status status = AE_OK; - acpi_integer merged_value; - acpi_integer current_value; + u64 merged_value; + u64 current_value; ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask); @@ -587,7 +582,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, /* If the mask is all ones, we don't need to worry about the update rule */ - if (mask != ACPI_INTEGER_MAX) { + if (mask != ACPI_UINT64_MAX) { /* Decode the update rule */ @@ -678,8 +673,8 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; - acpi_integer raw_datum; - acpi_integer merged_datum; + u64 raw_datum; + u64 merged_datum; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; @@ -804,10 +799,10 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; - acpi_integer mask; - acpi_integer width_mask; - acpi_integer merged_datum; - acpi_integer raw_datum = 0; + u64 mask; + u64 width_mask; + u64 merged_datum; + u64 raw_datum = 0; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; @@ -855,7 +850,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, * shift operator */ if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { - width_mask = ACPI_INTEGER_MAX; + width_mask = ACPI_UINT64_MAX; } else { width_mask = ACPI_MASK_BITS_ABOVE(obj_desc->common_field. diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index d29e542bb6df..c5bb1eeed2df 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -409,8 +409,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, * ******************************************************************************/ -acpi_integer -acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1) +u64 acpi_ex_do_math_op(u16 opcode, u64 integer0, u64 integer1) { ACPI_FUNCTION_ENTRY(); @@ -498,8 +497,7 @@ acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1) acpi_status acpi_ex_do_logical_numeric_op(u16 opcode, - acpi_integer integer0, - acpi_integer integer1, u8 * logical_result) + u64 integer0, u64 integer1, u8 *logical_result) { acpi_status status = AE_OK; u8 local_result = FALSE; @@ -564,8 +562,8 @@ acpi_ex_do_logical_op(u16 opcode, union acpi_operand_object *operand1, u8 * logical_result) { union acpi_operand_object *local_operand1 = operand1; - acpi_integer integer0; - acpi_integer integer1; + u64 integer0; + u64 integer1; u32 length0; u32 length1; acpi_status status = AE_OK; diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 2b2128e52d42..99adbab5acbf 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -261,8 +261,8 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc2 = NULL; u32 temp32; u32 i; - acpi_integer power_of_ten; - acpi_integer digit; + u64 power_of_ten; + u64 digit; ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R, acpi_ps_get_opcode_name(walk_state->opcode)); @@ -362,7 +362,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Sum the digit into the result with the current power of 10 */ return_desc->integer.value += - (((acpi_integer) temp32) * power_of_ten); + (((u64) temp32) * power_of_ten); /* Shift to next BCD digit */ @@ -392,7 +392,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) * remainder from above */ return_desc->integer.value |= - (((acpi_integer) temp32) << ACPI_MUL_4(i)); + (((u64) temp32) << ACPI_MUL_4(i)); } /* Overflow if there is any data left in Digit */ @@ -439,7 +439,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* The object exists in the namespace, return TRUE */ - return_desc->integer.value = ACPI_INTEGER_MAX; + return_desc->integer.value = ACPI_UINT64_MAX; goto cleanup; default: @@ -589,7 +589,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; u32 type; - acpi_integer value; + u64 value; ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R, acpi_ps_get_opcode_name(walk_state->opcode)); @@ -610,7 +610,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) * return_desc->Integer.Value is initially == 0 (FALSE) from above. */ if (!operand[0]->integer.value) { - return_desc->integer.value = ACPI_INTEGER_MAX; + return_desc->integer.value = ACPI_UINT64_MAX; } break; diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index ea115021ee7d..22841bbbe63c 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -282,7 +282,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) { union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; - acpi_integer index; + u64 index; acpi_status status = AE_OK; acpi_size length; @@ -584,7 +584,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) * Default is FALSE (zero) */ if (logical_result) { - return_desc->integer.value = ACPI_INTEGER_MAX; + return_desc->integer.value = ACPI_UINT64_MAX; } cleanup: diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 25d1cd35c3e1..8bb1012ef44e 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -148,7 +148,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc = NULL; char *buffer = NULL; acpi_status status = AE_OK; - acpi_integer index; + u64 index; acpi_size length; ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_1T_1R, diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 580abbd924dc..f256b6a25f2e 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -218,7 +218,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; - acpi_integer index; + u64 index; union acpi_operand_object *this_element; ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R, @@ -253,9 +253,9 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) } /* Create an integer for the return value */ - /* Default return value is ACPI_INTEGER_MAX if no match found */ + /* Default return value is ACPI_UINT64_MAX if no match found */ - return_desc = acpi_ut_create_integer_object(ACPI_INTEGER_MAX); + return_desc = acpi_ut_create_integer_object(ACPI_UINT64_MAX); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -270,7 +270,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) * * Upon finding a match, the loop will terminate via "break" at * the bottom. If it terminates "normally", match_value will be - * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no + * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no * match was found. */ for (; index < operand[0]->package.count; index++) { diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 0cd88f6c95f7..486b2e5661b6 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -70,7 +70,7 @@ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -115,8 +115,7 @@ acpi_ex_system_memory_space_handler(u32 function, * Hardware does not support non-aligned data transfers, we must verify * the request. */ - (void)acpi_ut_short_divide((acpi_integer) address, length, NULL, - &remainder); + (void)acpi_ut_short_divide((u64) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS(AE_AML_ALIGNMENT); } @@ -128,10 +127,9 @@ acpi_ex_system_memory_space_handler(u32 function, * 2) Address beyond the current mapping? */ if ((address < mem_info->mapped_physical_address) || - (((acpi_integer) address + length) > ((acpi_integer) - mem_info-> - mapped_physical_address + - mem_info->mapped_length))) { + (((u64) address + length) > ((u64) + mem_info->mapped_physical_address + + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. @@ -193,8 +191,7 @@ acpi_ex_system_memory_space_handler(u32 function, * access */ logical_addr_ptr = mem_info->mapped_logical_address + - ((acpi_integer) address - - (acpi_integer) mem_info->mapped_physical_address); + ((u64) address - (u64) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", @@ -215,19 +212,19 @@ acpi_ex_system_memory_space_handler(u32 function, *value = 0; switch (bit_width) { case 8: - *value = (acpi_integer) ACPI_GET8(logical_addr_ptr); + *value = (u64) ACPI_GET8(logical_addr_ptr); break; case 16: - *value = (acpi_integer) ACPI_GET16(logical_addr_ptr); + *value = (u64) ACPI_GET16(logical_addr_ptr); break; case 32: - *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); + *value = (u64) ACPI_GET32(logical_addr_ptr); break; case 64: - *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); + *value = (u64) ACPI_GET64(logical_addr_ptr); break; default: @@ -291,7 +288,7 @@ acpi_status acpi_ex_system_io_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -350,7 +347,7 @@ acpi_status acpi_ex_pci_config_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -425,7 +422,7 @@ acpi_status acpi_ex_cmos_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -457,7 +454,7 @@ acpi_status acpi_ex_pci_bar_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -489,7 +486,7 @@ acpi_status acpi_ex_data_table_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { ACPI_FUNCTION_TRACE(ex_data_table_space_handler); diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index c6cb6042603c..e11b6cb42a57 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -193,7 +193,7 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) * ******************************************************************************/ -acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) +acpi_status acpi_ex_system_do_suspend(u64 how_long) { ACPI_FUNCTION_ENTRY(); diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 0f2ce9c52f02..74c24d517f81 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -67,7 +67,7 @@ ACPI_MODULE_NAME("exutils") /* Local prototypes */ -static u32 acpi_ex_digits_needed(acpi_integer value, u32 base); +static u32 acpi_ex_digits_needed(u64 value, u32 base); #ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* @@ -230,7 +230,7 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) * We are running a method that exists in a 32-bit ACPI table. * Truncate the value to 32 bits by zeroing out the upper 32-bit field */ - obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX; + obj_desc->integer.value &= (u64) ACPI_UINT32_MAX; } } @@ -327,14 +327,14 @@ void acpi_ex_release_global_lock(u32 field_flags) * ******************************************************************************/ -static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) +static u32 acpi_ex_digits_needed(u64 value, u32 base) { u32 num_digits; - acpi_integer current_value; + u64 current_value; ACPI_FUNCTION_TRACE(ex_digits_needed); - /* acpi_integer is unsigned, so we don't worry about a '-' prefix */ + /* u64 is unsigned, so we don't worry about a '-' prefix */ if (value == 0) { return_UINT32(1); @@ -370,7 +370,7 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) * ******************************************************************************/ -void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) +void acpi_ex_eisa_id_to_string(char *out_string, u64 compressed_id) { u32 swapped_id; @@ -394,10 +394,10 @@ void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F)); out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F)); out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F)); - out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12); - out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8); - out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4); - out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0); + out_string[3] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 12); + out_string[4] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 8); + out_string[5] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 4); + out_string[6] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 0); out_string[7] = 0; } @@ -418,7 +418,7 @@ void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) * ******************************************************************************/ -void acpi_ex_integer_to_string(char *out_string, acpi_integer value) +void acpi_ex_integer_to_string(char *out_string, u64 value) { u32 count; u32 digits_needed; diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index ce0cbbc18ad0..1ef8e0bb250b 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -140,7 +140,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) { acpi_status status; u32 delta_ticks; - acpi_integer quotient; + u64 quotient; ACPI_FUNCTION_TRACE(acpi_get_timer_duration); diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 6aa6a1a4d918..00493e108a01 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -403,7 +403,7 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, /* Get 1 byte from the AML stream */ opcode = AML_BYTE_OP; - arg->common.value.integer = (acpi_integer) * aml; + arg->common.value.integer = (u64) *aml; length = 1; break; diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 61a038dbfe23..f2ee3b548609 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -182,7 +182,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a - * package that in turn contains an acpi_integer Address, a u8 Pin, + * package that in turn contains an u64 Address, a u8 Pin, * a Name, and a u8 source_index. */ top_object_list = package_object->package.elements; diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index e156915fa0e8..983510640059 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -460,8 +460,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) void acpi_ut_value_exit(u32 line_number, const char *function_name, - const char *module_name, - u32 component_id, acpi_integer value) + const char *module_name, u32 component_id, u64 value) { acpi_debug_print(ACPI_LV_FUNCTIONS, diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index f4c5ee8109bc..7f5e734ce7f7 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -348,7 +348,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, - acpi_integer *value) + u64 *value) { union acpi_operand_object *obj_desc; acpi_status status; diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 49286a39b09e..eda3e656c4af 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -234,7 +234,7 @@ static const char acpi_gbl_hex_to_ascii[] = { * ******************************************************************************/ -char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) +char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) { return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 7cfa1d8164d0..35059a14eb72 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -70,9 +70,8 @@ ACPI_MODULE_NAME("utmath") * ******************************************************************************/ acpi_status -acpi_ut_short_divide(acpi_integer dividend, - u32 divisor, - acpi_integer * out_quotient, u32 * out_remainder) +acpi_ut_short_divide(u64 dividend, + u32 divisor, u64 *out_quotient, u32 *out_remainder) { union uint64_overlay dividend_ovl; union uint64_overlay quotient; @@ -126,9 +125,8 @@ acpi_ut_short_divide(acpi_integer dividend, ******************************************************************************/ acpi_status -acpi_ut_divide(acpi_integer in_dividend, - acpi_integer in_divisor, - acpi_integer * out_quotient, acpi_integer * out_remainder) +acpi_ut_divide(u64 in_dividend, + u64 in_divisor, u64 *out_quotient, u64 *out_remainder) { union uint64_overlay dividend; union uint64_overlay divisor; @@ -199,9 +197,8 @@ acpi_ut_divide(acpi_integer in_dividend, * The 64-bit remainder must be generated. */ partial1 = quotient.part.lo * divisor.part.hi; - partial2.full = - (acpi_integer) quotient.part.lo * divisor.part.lo; - partial3.full = (acpi_integer) partial2.part.hi + partial1; + partial2.full = (u64) quotient.part.lo * divisor.part.lo; + partial3.full = (u64) partial2.part.hi + partial1; remainder.part.hi = partial3.part.lo; remainder.part.lo = partial2.part.lo; @@ -257,9 +254,8 @@ acpi_ut_divide(acpi_integer in_dividend, * ******************************************************************************/ acpi_status -acpi_ut_short_divide(acpi_integer in_dividend, - u32 divisor, - acpi_integer * out_quotient, u32 * out_remainder) +acpi_ut_short_divide(u64 in_dividend, + u32 divisor, u64 *out_quotient, u32 *out_remainder) { ACPI_FUNCTION_TRACE(ut_short_divide); @@ -284,9 +280,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, } acpi_status -acpi_ut_divide(acpi_integer in_dividend, - acpi_integer in_divisor, - acpi_integer * out_quotient, acpi_integer * out_remainder) +acpi_ut_divide(u64 in_dividend, + u64 in_divisor, u64 *out_quotient, u64 *out_remainder) { ACPI_FUNCTION_TRACE(ut_divide); diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index fb55924e6e0f..32982e2ac384 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -724,13 +724,12 @@ acpi_name acpi_ut_repair_name(char *name) * ******************************************************************************/ -acpi_status -acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer) { u32 this_digit = 0; - acpi_integer return_value = 0; - acpi_integer quotient; - acpi_integer dividend; + u64 return_value = 0; + u64 quotient; + u64 dividend; u32 to_integer_op = (base == ACPI_ANY_BASE); u32 mode32 = (acpi_gbl_integer_byte_width == 4); u8 valid_digits = 0; @@ -844,9 +843,8 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) /* Divide the digit into the correct position */ - (void) - acpi_ut_short_divide((dividend - (acpi_integer) this_digit), - base, "ient, NULL); + (void)acpi_ut_short_divide((dividend - (u64) this_digit), + base, "ient, NULL); if (return_value > quotient) { if (to_integer_op) { diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index c7e9431e16f1..b396854b83b0 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -196,7 +196,7 @@ acpi_os_hotplug_execute(acpi_osd_exec_callback function, void *context); void acpi_os_wait_events_complete(void *context); -void acpi_os_sleep(acpi_integer milliseconds); +void acpi_os_sleep(u64 milliseconds); void acpi_os_stall(u32 microseconds); @@ -227,7 +227,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, acpi_status acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, - u32 reg, acpi_integer value, u32 width); + u32 reg, u64 value, u32 width); /* * Interim function needed for PCI IRQ routing diff --git a/include/acpi/acrestyp.h b/include/acpi/acrestyp.h index dc6302e94793..e5526354ba5e 100644 --- a/include/acpi/acrestyp.h +++ b/include/acpi/acrestyp.h @@ -397,7 +397,7 @@ struct acpi_resource { struct acpi_pci_routing_table { u32 length; u32 pin; - acpi_integer address; /* here for 64-bit alignment */ + u64 address; /* here for 64-bit alignment */ u32 source_index; char source[4]; /* pad to 64 bits so sizeof() works in all cases */ }; diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 4e65c201dcd4..07f2cdcc5eb1 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -390,14 +390,6 @@ struct uint32_struct { u32 hi; }; -/* - * Acpi integer width. In ACPI version 1, integers are 32 bits. In ACPI - * version 2, integers are 64 bits. Note that this pertains to the ACPI integer - * type only, not other integers used in the implementation of the ACPI CA - * subsystem. - */ -typedef unsigned long long acpi_integer; -#define ACPI_INTEGER_MAX ACPI_UINT64_MAX #define ACPI_INTEGER_BIT_SIZE 64 #define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ @@ -421,6 +413,19 @@ typedef unsigned long long acpi_integer; #define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */ #define ACPI_DO_NOT_WAIT 0 +/* + * Obsolete: Acpi integer width. In ACPI version 1 (1996), integers are 32 bits. + * In ACPI version 2 (2000) and later, integers are 64 bits. Note that this + * pertains to the ACPI integer type only, not to other integers used in the + * implementation of the ACPICA subsystem. + * + * 01/2010: This type is obsolete and has been removed from the entire ACPICA + * code base. It remains here for compatibility with device drivers that use + * the type. However, it will be removed in the future. + */ +typedef u64 acpi_integer; +#define ACPI_INTEGER_MAX ACPI_UINT64_MAX + /******************************************************************************* * * Commonly used macros @@ -801,7 +806,7 @@ union acpi_object { acpi_object_type type; /* See definition of acpi_ns_type for values */ struct { acpi_object_type type; /* ACPI_TYPE_INTEGER */ - acpi_integer value; /* The actual number */ + u64 value; /* The actual number */ } integer; struct { @@ -945,7 +950,7 @@ typedef acpi_status(*acpi_adr_space_handler) (u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); @@ -1005,7 +1010,7 @@ struct acpi_device_info { u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */ u32 current_status; /* _STA value */ - acpi_integer address; /* _ADR value */ + u64 address; /* _ADR value */ struct acpica_device_id hardware_id; /* _HID value */ struct acpica_device_id unique_id; /* _UID value */ struct acpica_device_id_list compatible_id_list; /* _CID list */ -- cgit v1.2.3 From a8f13b7083a10580eeed0723df4b414ed741e0d2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 10:09:43 +0800 Subject: ACPICA: Remove unused uint32_struct type This type is not used in ACPICA and thus removed. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/actypes.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 07f2cdcc5eb1..2ccfa47a0ed7 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -385,11 +385,6 @@ union uint64_overlay { struct uint64_struct part; }; -struct uint32_struct { - u32 lo; - u32 hi; -}; - #define ACPI_INTEGER_BIT_SIZE 64 #define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ -- cgit v1.2.3 From aea9c04bcc257caad9841c283b90ec1b28267fae Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 22 Jan 2010 19:09:06 +0800 Subject: ACPICA: Update version to 20100121. Version 20100121. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/acpixf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2bf965ac06da..06adbaccb912 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20091214 +#define ACPI_CA_VERSION 0x20100121 #include "actypes.h" #include "actbl.h" -- cgit v1.2.3 From 8484c63f4b363d79febe35f95328e38018b65026 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 21 Jan 2010 21:10:47 +0100 Subject: ASoC: add simplified versions of widget macros Many macros from include/sound/soc-dapm.h take an array and a number of elements in it as arguments, whereas most users use static arrays and use "x, ARRAY_SIZE(x)" as arguments. This patch adds simplified versions of those macros, calling ARRAY_SIZE() internally. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include') diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index c5c95e1da65b..c0922a034223 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -95,6 +95,21 @@ .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ .num_kcontrols = 1} +/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ +#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ + wcontrols) \ +{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)} +#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \ + wcontrols)\ +{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)} +#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \ + wcontrols)\ +{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \ + .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ + .num_kcontrols = ARRAY_SIZE(wcontrols)} + /* path domain with event - event handler must return 0 for success */ #define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \ wncontrols, wevent, wflags) \ @@ -126,6 +141,23 @@ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ .event = wevent, .event_flags = wflags} +/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ +#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ + wevent, wflags) \ +{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \ + .event = wevent, .event_flags = wflags} +#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ + wevent, wflags) \ +{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \ + .event = wevent, .event_flags = wflags} +#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \ + wcontrols, wevent, wflags) \ +{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, \ + .num_kcontrols = ARRAY_SIZE(wcontrols), .event = wevent, .event_flags = wflags} + /* events that are pre and post DAPM */ #define SND_SOC_DAPM_PRE(wname, wevent) \ { .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ -- cgit v1.2.3 From 6c2fb6a8d8c43544e7665859f29373c98d17df75 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 21 Jan 2010 22:04:03 +0100 Subject: ASoC: add helper macros to declare struct soc_enum instances Several shortcuts for popular uses of some of SOC_ENUM_* and SOC_VALUE_ENUM_* macros. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index a8768ea7571a..4bbeb9f83ece 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -168,6 +168,23 @@ .get = xhandler_get, .put = xhandler_put, \ .private_value = (unsigned long)&xenum } +/* + * Simplified versions of above macros, declaring a struct and calculating + * ARRAY_SIZE internally + */ +#define SOC_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xtexts) \ + struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ + ARRAY_SIZE(xtexts), xtexts) +#define SOC_ENUM_SINGLE_DECL(name, xreg, xshift, xtexts) \ + SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) +#define SOC_ENUM_SINGLE_EXT_DECL(name, xtexts) \ + struct soc_enum name = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(xtexts), xtexts) +#define SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xmask, xtexts, xvalues) \ + struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \ + ARRAY_SIZE(xtexts), xtexts, xvalues) +#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \ + SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues) + /* * Bias levels * -- cgit v1.2.3 From e7636925789b042ff9d98c51d48392e8c5549480 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 26 Jan 2010 17:08:24 +0100 Subject: ALSA: pcm_lib - return back hw_ptr_interrupt Clemens Ladisch noted for hw_ptr_removal in "cleanup & merge hw_ptr update functions" commit: "It is possible for the status/delay ioctls to be called when the sound card's pointer register alreay shows a position at the beginning of the new period, but immediately before the interrupt is actually executed. (This happens regularly on a SMP machine with mplayer.) When that happens, the code thinks that the position must be at least one period ahead of the current position and drops an entire buffer of data." Return back the hw_ptr_interrupt variable. The last interrupt pointer is always computed from the latest hw_ptr instead of tracking it separately (in this case all hw_ptr checks and modifications might influence also hw_ptr_interrupt and it is difficult to keep it consistent). Signed-off-by: Jaroslav Kysela --- include/sound/pcm.h | 1 + sound/core/oss/pcm_oss.c | 3 +-- sound/core/pcm_lib.c | 7 +++++-- sound/core/pcm_native.c | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 3bc9bca771ec..13bc83ca35fb 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -271,6 +271,7 @@ struct snd_pcm_runtime { int overrange; snd_pcm_uframes_t avail_max; snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ + snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 255ad910077a..82d4e3329b3d 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -635,8 +635,7 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes) static inline snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime) { - snd_pcm_uframes_t ptr = runtime->status->hw_ptr; - return ptr - (ptr % runtime->period_size); + return runtime->hw_ptr_interrupt; } /* define extended formats in the recent OSS versions (if any) */ diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index e2a817eac2a9..aa54195ef3b0 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -325,8 +325,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (in_interrupt) { /* we know that one period was processed */ /* delta = "expected next hw_ptr" for in_interrupt != 0 */ - delta = old_hw_ptr - (old_hw_ptr % runtime->period_size) - + runtime->period_size; + delta = runtime->hw_ptr_interrupt + runtime->period_size; if (delta > new_hw_ptr) { hw_base += runtime->buffer_size; if (hw_base >= runtime->boundary) @@ -437,6 +436,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); + if (in_interrupt) { + runtime->hw_ptr_interrupt = new_hw_ptr - + (new_hw_ptr % runtime->period_size); + } runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; runtime->hw_ptr_jiffies = jiffies; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 56ec35e8510b..7a002db512b4 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1252,6 +1252,8 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) if (err < 0) return err; runtime->hw_ptr_base = 0; + runtime->hw_ptr_interrupt = runtime->status->hw_ptr - + runtime->status->hw_ptr % runtime->period_size; runtime->silence_start = runtime->status->hw_ptr; runtime->silence_filled = 0; return 0; -- cgit v1.2.3 From 439913fffd39374c3737186b22d2d56c3a0ae526 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 28 Jan 2010 10:53:19 +0800 Subject: ACPI: replace acpi_integer by u64 acpi_integer is now obsolete and removed from the ACPICA code base, replaced by u64. Signed-off-by: Lin Ming Signed-off-by: Len Brown --- arch/ia64/hp/common/aml_nfw.c | 6 ++--- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 6 ++--- drivers/acpi/battery.c | 4 +-- drivers/acpi/ec.c | 4 +-- drivers/acpi/glue.c | 4 +-- drivers/acpi/osl.c | 4 +-- drivers/acpi/power_meter.c | 30 +++++++++++----------- drivers/acpi/processor_idle.c | 2 +- drivers/acpi/processor_throttling.c | 24 +++++++++--------- drivers/acpi/utils.c | 16 ++++++------ drivers/acpi/video.c | 2 +- drivers/ata/libata-acpi.c | 4 +-- drivers/ide/ide-acpi.c | 8 +++--- drivers/input/misc/atlas_btns.c | 2 +- drivers/pci/pci-acpi.c | 2 +- drivers/platform/x86/toshiba_bluetooth.c | 4 +-- drivers/platform/x86/wmi.c | 4 +-- include/acpi/acpi_bus.h | 6 ++--- include/acpi/processor.h | 42 +++++++++++++++---------------- 19 files changed, 87 insertions(+), 87 deletions(-) (limited to 'include') diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c index 4abd2c79bb1d..22078486d35d 100644 --- a/arch/ia64/hp/common/aml_nfw.c +++ b/arch/ia64/hp/common/aml_nfw.c @@ -77,7 +77,7 @@ static void aml_nfw_execute(struct ia64_nfw_context *c) c->arg[4], c->arg[5], c->arg[6], c->arg[7]); } -static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value) +static void aml_nfw_read_arg(u8 *offset, u32 bit_width, u64 *value) { switch (bit_width) { case 8: @@ -95,7 +95,7 @@ static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value) } } -static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value) +static void aml_nfw_write_arg(u8 *offset, u32 bit_width, u64 *value) { switch (bit_width) { case 8: @@ -114,7 +114,7 @@ static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value) } static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address, - u32 bit_width, acpi_integer *value, void *handler_context, + u32 bit_width, u64 *value, void *handler_context, void *region_context) { struct ia64_nfw_context *context = handler_context; diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index f125e5c551c0..55d42bc443e8 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -806,7 +806,7 @@ static int find_psb_table(struct powernow_k8_data *data) static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { - acpi_integer control; + u64 control; if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) return; @@ -824,7 +824,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { struct cpufreq_frequency_table *powernow_table; int ret_val = -ENODEV; - acpi_integer control, status; + u64 control, status; if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { dprintk("register performance failed: bad ACPI data\n"); @@ -948,7 +948,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, u32 fid; u32 vid; u32 freq, index; - acpi_integer status, control; + u64 status, control; if (data->exttype) { status = data->acpi_data.states[i].status; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index cada73ffdfa7..58d2c91ba62b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -324,8 +324,8 @@ static int extract_package(struct acpi_battery *battery, strncpy(ptr, element->string.pointer, 32); else if (element->type == ACPI_TYPE_INTEGER) { strncpy(ptr, (u8 *)&element->integer.value, - sizeof(acpi_integer)); - ptr[sizeof(acpi_integer)] = 0; + sizeof(u64)); + ptr[sizeof(u64)] = 0; } else *ptr = 0; /* don't have value */ } else { diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d6471bb6852f..748ced85dec5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -589,7 +589,7 @@ static u32 acpi_ec_gpe_handler(void *data) static acpi_status acpi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, acpi_integer *value, + u32 bits, u64 *value, void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; @@ -620,7 +620,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, ++address; if (function == ACPI_READ) { result = acpi_ec_read(ec, address, &temp); - (*value) |= ((acpi_integer)temp) << i; + (*value) |= ((u64)temp) << i; } else { temp = 0xff & ((*value) >> i); result = acpi_ec_write(ec, address, temp); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4c8fcff662cf..6d5b64b7d526 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -87,7 +87,7 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) /* Get device's handler per its address under its parent */ struct acpi_find_child { acpi_handle handle; - acpi_integer address; + u64 address; }; static acpi_status @@ -106,7 +106,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address) +acpi_handle acpi_get_child(acpi_handle parent, u64 address) { struct acpi_find_child find = { NULL, address }; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 02e8464e480f..8e6d8665f0ae 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -436,7 +436,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) * Running in interpreter thread context, safe to sleep */ -void acpi_os_sleep(acpi_integer ms) +void acpi_os_sleep(u64 ms) { schedule_timeout_interruptible(msecs_to_jiffies(ms)); } @@ -603,7 +603,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, acpi_status acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, - acpi_integer value, u32 width) + u64 value, u32 width) { int result, size; diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c index dc4ffadf8122..834c5af0de4b 100644 --- a/drivers/acpi/power_meter.c +++ b/drivers/acpi/power_meter.c @@ -71,17 +71,17 @@ static const struct acpi_device_id power_meter_ids[] = { MODULE_DEVICE_TABLE(acpi, power_meter_ids); struct acpi_power_meter_capabilities { - acpi_integer flags; - acpi_integer units; - acpi_integer type; - acpi_integer accuracy; - acpi_integer sampling_time; - acpi_integer min_avg_interval; - acpi_integer max_avg_interval; - acpi_integer hysteresis; - acpi_integer configurable_cap; - acpi_integer min_cap; - acpi_integer max_cap; + u64 flags; + u64 units; + u64 type; + u64 accuracy; + u64 sampling_time; + u64 min_avg_interval; + u64 max_avg_interval; + u64 hysteresis; + u64 configurable_cap; + u64 min_cap; + u64 max_cap; }; struct acpi_power_meter_resource { @@ -93,9 +93,9 @@ struct acpi_power_meter_resource { acpi_string model_number; acpi_string serial_number; acpi_string oem_info; - acpi_integer power; - acpi_integer cap; - acpi_integer avg_interval; + u64 power; + u64 cap; + u64 avg_interval; int sensors_valid; unsigned long sensors_last_updated; struct sensor_device_attribute sensors[NUM_SENSORS]; @@ -402,7 +402,7 @@ static ssize_t show_val(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - acpi_integer val = 0; + u64 val = 0; switch (attr->index) { case 0: diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 7c0441f63b39..3455d7abf5f3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -352,7 +352,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) { acpi_status status = 0; - acpi_integer count; + u64 count; int current_count; int i; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 1c5d7a8b2fdf..7ded7542fc9d 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -660,7 +660,7 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) #ifdef CONFIG_X86 static int acpi_throttling_rdmsr(struct acpi_processor *pr, - acpi_integer * value) + u64 *value) { struct cpuinfo_x86 *c; u64 msr_high, msr_low; @@ -681,13 +681,13 @@ static int acpi_throttling_rdmsr(struct acpi_processor *pr, rdmsr_safe(MSR_IA32_THERM_CONTROL, (u32 *)&msr_low , (u32 *) &msr_high); msr = (msr_high << 32) | msr_low; - *value = (acpi_integer) msr; + *value = (u64) msr; ret = 0; } return ret; } -static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) +static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) { struct cpuinfo_x86 *c; unsigned int cpu; @@ -711,14 +711,14 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) } #else static int acpi_throttling_rdmsr(struct acpi_processor *pr, - acpi_integer * value) + u64 *value) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); return -1; } -static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) +static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); @@ -727,7 +727,7 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) #endif static int acpi_read_throttling_status(struct acpi_processor *pr, - acpi_integer *value) + u64 *value) { u32 bit_width, bit_offset; u64 ptc_value; @@ -746,7 +746,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, address, (u32 *) &ptc_value, (u32) (bit_width + bit_offset)); ptc_mask = (1 << bit_width) - 1; - *value = (acpi_integer) ((ptc_value >> bit_offset) & ptc_mask); + *value = (u64) ((ptc_value >> bit_offset) & ptc_mask); ret = 0; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: @@ -760,7 +760,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, } static int acpi_write_throttling_state(struct acpi_processor *pr, - acpi_integer value) + u64 value) { u32 bit_width, bit_offset; u64 ptc_value; @@ -793,7 +793,7 @@ static int acpi_write_throttling_state(struct acpi_processor *pr, } static int acpi_get_throttling_state(struct acpi_processor *pr, - acpi_integer value) + u64 value) { int i; @@ -808,7 +808,7 @@ static int acpi_get_throttling_state(struct acpi_processor *pr, } static int acpi_get_throttling_value(struct acpi_processor *pr, - int state, acpi_integer *value) + int state, u64 *value) { int ret = -1; @@ -826,7 +826,7 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) { int state = 0; int ret; - acpi_integer value; + u64 value; if (!pr) return -EINVAL; @@ -993,7 +993,7 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, int state, bool force) { int ret; - acpi_integer value; + u64 value; if (!pr) return -EINVAL; diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 811fec10462b..11882dbe2094 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -107,12 +107,12 @@ acpi_extract_package(union acpi_object *package, case ACPI_TYPE_INTEGER: switch (format_string[i]) { case 'N': - size_required += sizeof(acpi_integer); - tail_offset += sizeof(acpi_integer); + size_required += sizeof(u64); + tail_offset += sizeof(u64); break; case 'S': size_required += - sizeof(char *) + sizeof(acpi_integer) + + sizeof(char *) + sizeof(u64) + sizeof(char); tail_offset += sizeof(char *); break; @@ -193,17 +193,17 @@ acpi_extract_package(union acpi_object *package, case ACPI_TYPE_INTEGER: switch (format_string[i]) { case 'N': - *((acpi_integer *) head) = + *((u64 *) head) = element->integer.value; - head += sizeof(acpi_integer); + head += sizeof(u64); break; case 'S': pointer = (u8 **) head; *pointer = tail; - *((acpi_integer *) tail) = + *((u64 *) tail) = element->integer.value; - head += sizeof(acpi_integer *); - tail += sizeof(acpi_integer); + head += sizeof(u64 *); + tail += sizeof(u64); /* NULL terminate string */ *tail = (char)0; tail += sizeof(char); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index b765790b32be..6e9b49149fce 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -759,7 +759,7 @@ acpi_video_bus_POST_options(struct acpi_video_bus *video, static int acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) { - acpi_integer status = 0; + u64 status = 0; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 1245838ac13d..292fdbc0431a 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -64,7 +64,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap) WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA)); if (!sata_pmp_attached(ap)) { - acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT); + u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT); ap->link.device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr); @@ -74,7 +74,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap) ap->link.device->acpi_handle = NULL; ata_for_each_link(link, ap, EDGE) { - acpi_integer adr = SATA_ADR(ap->port_no, link->pmp); + u64 adr = SATA_ADR(ap->port_no, link->pmp); link->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr); diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index c0cf45a11b93..5cb01e5c323c 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -108,11 +108,11 @@ bool ide_port_acpi(ide_hwif_t *hwif) * Returns 0 on success, <0 on error. */ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) + u64 *pcidevfn) { struct pci_dev *pdev = to_pci_dev(dev); unsigned int bus, devnum, func; - acpi_integer addr; + u64 addr; acpi_handle dev_handle; acpi_status status; struct acpi_device_info *dinfo = NULL; @@ -122,7 +122,7 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, devnum = PCI_SLOT(pdev->devfn); func = PCI_FUNC(pdev->devfn); /* ACPI _ADR encoding for PCI bus: */ - addr = (acpi_integer)(devnum << 16 | func); + addr = (u64)(devnum << 16 | func); DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func); @@ -169,7 +169,7 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) { struct device *dev = hwif->gendev.parent; acpi_handle uninitialized_var(dev_handle); - acpi_integer pcidevfn; + u64 pcidevfn; acpi_handle chan_handle; int err; diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 1b871917340a..dfaa9a045ed8 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c @@ -47,7 +47,7 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle, static acpi_status acpi_atlas_button_handler(u32 function, acpi_physical_address address, - u32 bit_width, acpi_integer *value, + u32 bit_width, u64 *value, void *handler_context, void *region_context) { acpi_status status; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 7e2829538a4c..441326c44138 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -143,7 +143,7 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) { struct pci_dev * pci_dev; - acpi_integer addr; + u64 addr; pci_dev = to_pci_dev(dev); /* Please ref to ACPI spec for the syntax of _ADR */ diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index a350418e87ea..944068611919 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -57,7 +57,7 @@ static struct acpi_driver toshiba_bt_rfkill_driver = { static int toshiba_bluetooth_enable(acpi_handle handle) { acpi_status res1, res2; - acpi_integer result; + u64 result; /* * Query ACPI to verify RFKill switch is set to 'on'. @@ -95,7 +95,7 @@ static int toshiba_bt_resume(struct acpi_device *device) static int toshiba_bt_rfkill_add(struct acpi_device *device) { acpi_status status; - acpi_integer bt_present; + u64 bt_present; int result = -ENODEV; /* diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index b104302fea0a..09e9918c69c1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -796,7 +796,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) */ static acpi_status acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, acpi_integer * value, + u32 bits, u64 *value, void *handler_context, void *region_context) { int result = 0, i = 0; @@ -813,7 +813,7 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, if (function == ACPI_READ) { result = ec_read(address, &temp); - (*value) |= ((acpi_integer)temp) << i; + (*value) |= ((u64)temp) << i; } else { temp = 0xff & ((*value) >> i); result = ec_write(address, temp); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 3cd9ccdcbd8f..71c105c9b0ee 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -250,8 +250,8 @@ struct acpi_device_wakeup_state { struct acpi_device_wakeup { acpi_handle gpe_device; - acpi_integer gpe_number; - acpi_integer sleep_state; + u64 gpe_number; + u64 sleep_state; struct acpi_handle_list resources; struct acpi_device_wakeup_state state; struct acpi_device_wakeup_flags flags; @@ -380,7 +380,7 @@ struct acpi_pci_root { }; /* helper */ -acpi_handle acpi_get_child(acpi_handle, acpi_integer); +acpi_handle acpi_get_child(acpi_handle, u64); int acpi_is_root_bridge(acpi_handle); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 0ea5ef4eb6a9..29831768c0e6 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -92,11 +92,11 @@ struct acpi_processor_power { /* Performance Management */ struct acpi_psd_package { - acpi_integer num_entries; - acpi_integer revision; - acpi_integer domain; - acpi_integer coord_type; - acpi_integer num_processors; + u64 num_entries; + u64 revision; + u64 domain; + u64 coord_type; + u64 num_processors; } __attribute__ ((packed)); struct acpi_pct_register { @@ -110,12 +110,12 @@ struct acpi_pct_register { } __attribute__ ((packed)); struct acpi_processor_px { - acpi_integer core_frequency; /* megahertz */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer bus_master_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ + u64 core_frequency; /* megahertz */ + u64 power; /* milliWatts */ + u64 transition_latency; /* microseconds */ + u64 bus_master_latency; /* microseconds */ + u64 control; /* control value */ + u64 status; /* success indicator */ }; struct acpi_processor_performance { @@ -133,11 +133,11 @@ struct acpi_processor_performance { /* Throttling Control */ struct acpi_tsd_package { - acpi_integer num_entries; - acpi_integer revision; - acpi_integer domain; - acpi_integer coord_type; - acpi_integer num_processors; + u64 num_entries; + u64 revision; + u64 domain; + u64 coord_type; + u64 num_processors; } __attribute__ ((packed)); struct acpi_ptc_register { @@ -151,11 +151,11 @@ struct acpi_ptc_register { } __attribute__ ((packed)); struct acpi_processor_tx_tss { - acpi_integer freqpercentage; /* */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ + u64 freqpercentage; /* */ + u64 power; /* milliWatts */ + u64 transition_latency; /* microseconds */ + u64 control; /* control value */ + u64 status; /* success indicator */ }; struct acpi_processor_tx { u16 power; -- cgit v1.2.3 From 488991e28e55b4fbca8067edf0259f69d1a6f92c Mon Sep 17 00:00:00 2001 From: "Alan D. Brunelle" Date: Fri, 29 Jan 2010 09:04:08 +0100 Subject: block: Added in stricter no merge semantics for block I/O Updated 'nomerges' tunable to accept a value of '2' - indicating that _no_ merges at all are to be attempted (not even the simple one-hit cache). The following table illustrates the additional benefit - 5 minute runs of a random I/O load were applied to a dozen devices on a 16-way x86_64 system. nomerges Throughput %System Improvement (tput / %sys) -------- ------------ ----------- ------------------------- 0 12.45 MB/sec 0.669365609 1 12.50 MB/sec 0.641519199 0.40% / 2.71% 2 12.52 MB/sec 0.639849750 0.56% / 2.96% Signed-off-by: Alan D. Brunelle Signed-off-by: Jens Axboe --- Documentation/ABI/testing/sysfs-block | 14 ++++++++++++++ Documentation/block/queue-sysfs.txt | 10 +++++----- block/blk-sysfs.c | 11 +++++++---- block/elevator.c | 11 ++++++++++- include/linux/blkdev.h | 3 +++ 5 files changed, 39 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block index d2f90334bb93..4873c759d535 100644 --- a/Documentation/ABI/testing/sysfs-block +++ b/Documentation/ABI/testing/sysfs-block @@ -128,3 +128,17 @@ Description: preferred request size for workloads where sustained throughput is desired. If no optimal I/O size is reported this file contains 0. + +What: /sys/block//queue/nomerges +Date: January 2010 +Contact: +Description: + Standard I/O elevator operations include attempts to + merge contiguous I/Os. For known random I/O loads these + attempts will always fail and result in extra cycles + being spent in the kernel. This allows one to turn off + this behavior on one of two ways: When set to 1, complex + merge checks are disabled, but the simple one-shot merges + with the previous I/O request are enabled. When set to 2, + all merge tries are disabled. The default value is 0 - + which enables all types of merge tries. diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index e164403f60e1..f65274081c8d 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt @@ -25,11 +25,11 @@ size allowed by the hardware. nomerges (RW) ------------- -This enables the user to disable the lookup logic involved with IO merging -requests in the block layer. Merging may still occur through a direct -1-hit cache, since that comes for (almost) free. The IO scheduler will not -waste cycles doing tree/hash lookups for merges if nomerges is 1. Defaults -to 0, enabling all merges. +This enables the user to disable the lookup logic involved with IO +merging requests in the block layer. By default (0) all merges are +enabled. When set to 1 only simple one-hit merges will be tried. When +set to 2 no merge algorithms will be tried (including one-hit or more +complex tree/hash lookups). nr_requests (RW) ---------------- diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 8606c9543fdd..e85442415db3 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -189,7 +189,8 @@ static ssize_t queue_nonrot_store(struct request_queue *q, const char *page, static ssize_t queue_nomerges_show(struct request_queue *q, char *page) { - return queue_var_show(blk_queue_nomerges(q), page); + return queue_var_show((blk_queue_nomerges(q) << 1) | + blk_queue_noxmerges(q), page); } static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, @@ -199,10 +200,12 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, ssize_t ret = queue_var_store(&nm, page, count); spin_lock_irq(q->queue_lock); - if (nm) + queue_flag_clear(QUEUE_FLAG_NOMERGES, q); + queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); + if (nm == 2) queue_flag_set(QUEUE_FLAG_NOMERGES, q); - else - queue_flag_clear(QUEUE_FLAG_NOMERGES, q); + else if (nm) + queue_flag_set(QUEUE_FLAG_NOXMERGES, q); spin_unlock_irq(q->queue_lock); return ret; diff --git a/block/elevator.c b/block/elevator.c index 9ad5ccc4c5ee..ee3a883840f2 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -473,6 +473,15 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) struct request *__rq; int ret; + /* + * Levels of merges: + * nomerges: No merges at all attempted + * noxmerges: Only simple one-hit cache try + * merges: All merge tries attempted + */ + if (blk_queue_nomerges(q)) + return ELEVATOR_NO_MERGE; + /* * First try one-hit cache. */ @@ -484,7 +493,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) } } - if (blk_queue_nomerges(q)) + if (blk_queue_noxmerges(q)) return ELEVATOR_NO_MERGE; /* diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ffb13ad35716..f71f5c58620c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -463,6 +463,7 @@ struct request_queue #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ #define QUEUE_FLAG_CQ 16 /* hardware does queuing */ #define QUEUE_FLAG_DISCARD 17 /* supports DISCARD */ +#define QUEUE_FLAG_NOXMERGES 18 /* No extended merges */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_CLUSTER) | \ @@ -589,6 +590,8 @@ enum { #define blk_queue_queuing(q) test_bit(QUEUE_FLAG_CQ, &(q)->queue_flags) #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) +#define blk_queue_noxmerges(q) \ + test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags) #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) #define blk_queue_io_stat(q) test_bit(QUEUE_FLAG_IO_STAT, &(q)->queue_flags) #define blk_queue_flushing(q) ((q)->ordseq) -- cgit v1.2.3 From 1f5b8f8a2031ae9507eb67743cad4d424739bfff Mon Sep 17 00:00:00 2001 From: john stultz Date: Thu, 28 Jan 2010 15:02:41 -0800 Subject: ntp: Make time_esterror and time_maxerror static Make time_esterror and time_maxerror static as no one uses them outside of ntp.c Signed-off-by: John Stultz Cc: richard@rsk.demon.co.uk LKML-Reference: <1264719761.3437.47.camel@localhost.localdomain> Signed-off-by: Thomas Gleixner --- include/linux/timex.h | 3 --- kernel/time/ntp.c | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/timex.h b/include/linux/timex.h index 94f8faecdcbc..7a082b32d8e1 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -238,9 +238,6 @@ extern int tickadj; /* amount of adjustment per tick */ * phase-lock loop variables */ extern int time_status; /* clock synchronization status bits */ -extern long time_maxerror; /* maximum error */ -extern long time_esterror; /* estimated error */ - extern long time_adjust; /* The amount of adjtime left */ extern void ntp_init(void); diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 4800f933910e..74b1b37b1595 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -58,10 +58,10 @@ static s64 time_offset; static long time_constant = 2; /* maximum error (usecs): */ -long time_maxerror = NTP_PHASE_LIMIT; +static long time_maxerror = NTP_PHASE_LIMIT; /* estimated error (usecs): */ -long time_esterror = NTP_PHASE_LIMIT; +static long time_esterror = NTP_PHASE_LIMIT; /* frequency offset (scaled nsecs/secs): */ static s64 time_freq; -- cgit v1.2.3 From ef7995f4e46b1677f3eaaf547316e1a910b38dcb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 29 Jan 2010 23:59:12 -0800 Subject: Input: implement input filters Sometimes it is desirable to suppress certain events from reaching input handlers and thus user space. One such example is Mac mouse button emulation code which catches certain key presses and converts them into button clicks as if they were emitted by a virtual mouse. The original key press events should be completely suppressed, otherwise user space will be confused, and while keyboard driver does it on its own evdev is blissfully unaware of this arrangement. This patch adds notion of 'filter' to the standard input handlers, which may flag event as filtered thus preventing it from reaching other input handlers. Filters don't (nor will they ever) have a notion of priority relative to each other, input core will run all of them first and any one of them may mark event as filtered. This patch is inspired by similar patch by Matthew Garret but the implementation and intended usage are quite different. Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 41 ++++++++++++++++++++++++++++++++++------- include/linux/input.h | 8 ++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/input/input.c b/drivers/input/input.c index 6c161e220868..7080a9d4b840 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -86,12 +86,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) } /* - * Pass event through all open handles. This function is called with + * Pass event first through all filters and then, if event has not been + * filtered out, through all open handles. This function is called with * dev->event_lock held and interrupts disabled. */ static void input_pass_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { + struct input_handler *handler; struct input_handle *handle; rcu_read_lock(); @@ -99,11 +101,25 @@ static void input_pass_event(struct input_dev *dev, handle = rcu_dereference(dev->grab); if (handle) handle->handler->event(handle, type, code, value); - else - list_for_each_entry_rcu(handle, &dev->h_list, d_node) - if (handle->open) - handle->handler->event(handle, - type, code, value); + else { + bool filtered = false; + + list_for_each_entry_rcu(handle, &dev->h_list, d_node) { + if (!handle->open) + continue; + + handler = handle->handler; + if (!handler->filter) { + if (filtered) + break; + + handler->event(handle, type, code, value); + + } else if (handler->filter(handle, type, code, value)) + filtered = true; + } + } + rcu_read_unlock(); } @@ -990,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) union input_seq_state *state = (union input_seq_state *)&seq->private; seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); + if (handler->filter) + seq_puts(seq, " (filter)"); if (handler->fops) seq_printf(seq, " Minor=%d", handler->minor); seq_putc(seq, '\n'); @@ -1803,7 +1821,16 @@ int input_register_handle(struct input_handle *handle) error = mutex_lock_interruptible(&dev->mutex); if (error) return error; - list_add_tail_rcu(&handle->d_node, &dev->h_list); + + /* + * Filters go to the head of the list, normal handlers + * to the tail. + */ + if (handler->filter) + list_add_rcu(&handle->d_node, &dev->h_list); + else + list_add_tail_rcu(&handle->d_node, &dev->h_list); + mutex_unlock(&dev->mutex); /* diff --git a/include/linux/input.h b/include/linux/input.h index 7be8a6537b57..6c9d3d49fa91 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1198,6 +1198,8 @@ struct input_handle; * @event: event handler. This method is being called by input core with * interrupts disabled and dev->event_lock spinlock held and so * it may not sleep + * @filter: similar to @event; separates normal event handlers from + * "filters". * @connect: called when attaching a handler to an input device * @disconnect: disconnects a handler from input device * @start: starts handler for given handle. This function is called by @@ -1219,6 +1221,11 @@ struct input_handle; * same time. All of them will get their copy of input event generated by * the device. * + * The very same structure is used to implement input filters. Input core + * allows filters to run first and will not pass event to regular handlers + * if any of the filters indicate that the event should be filtered (by + * returning %true from their filter() method). + * * Note that input core serializes calls to connect() and disconnect() * methods. */ @@ -1227,6 +1234,7 @@ struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); + bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); -- cgit v1.2.3 From 99b089c3c38a83ebaeb1cc4584ddcde841626467 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 30 Jan 2010 00:53:29 -0800 Subject: Input: Mac button emulation - implement as an input filter Current implementation of Mac mouse button emulation plugs into legacy keyboard driver, converts certain keys into button events on a separate device, and suppresses the real events from reaching tty. This worked well enough until user space started using evdev which was completely unaware of this arrangement and kept sending original key presses to its users. Change the implementation to use newly added input filter framework so that original key presses are not transmitted to any handlers. As a bonus remove SYSCTL dependencies from the code and use Kconfig instead; also do not create the emulated mouse device until user activates emulation. Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 5 - drivers/macintosh/Kconfig | 1 + drivers/macintosh/mac_hid.c | 257 ++++++++++++++++++++++++++++++++------------ include/linux/kbd_kern.h | 3 - 4 files changed, 188 insertions(+), 78 deletions(-) (limited to 'include') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index f706b1dffdb3..cbf64b985ef4 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1185,11 +1185,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) rep = (down == 2); -#ifdef CONFIG_MAC_EMUMOUSEBTN - if (mac_hid_mouse_emulate_buttons(1, keycode, down)) - return; -#endif /* CONFIG_MAC_EMUMOUSEBTN */ - if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) if (emulate_raw(vc, keycode, !down << 7)) if (keycode < BTN_MISC && printk_ratelimit()) diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 3d906833948d..aa3c27e5255d 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -172,6 +172,7 @@ config INPUT_ADBHID config MAC_EMUMOUSEBTN bool "Support for mouse button 2+3 emulation" + depends on SYSCTL select INPUT help This provides generic support for emulating the 2nd and 3rd mouse diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 7b4ef5bb556b..0b210a90aef5 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -13,17 +13,195 @@ #include #include #include -#include - -static struct input_dev *emumousebtn; -static int emumousebtn_input_register(void); static int mouse_emulate_buttons; static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */ -static int mouse_last_keycode; -#if defined(CONFIG_SYSCTL) +static struct input_dev *mac_hid_emumouse_dev; + +static int mac_hid_create_emumouse(void) +{ + static struct lock_class_key mac_hid_emumouse_dev_event_class; + static struct lock_class_key mac_hid_emumouse_dev_mutex_class; + int err; + + mac_hid_emumouse_dev = input_allocate_device(); + if (!mac_hid_emumouse_dev) + return -ENOMEM; + + lockdep_set_class(&mac_hid_emumouse_dev->event_lock, + &mac_hid_emumouse_dev_event_class); + lockdep_set_class(&mac_hid_emumouse_dev->mutex, + &mac_hid_emumouse_dev_mutex_class); + + mac_hid_emumouse_dev->name = "Macintosh mouse button emulation"; + mac_hid_emumouse_dev->id.bustype = BUS_ADB; + mac_hid_emumouse_dev->id.vendor = 0x0001; + mac_hid_emumouse_dev->id.product = 0x0001; + mac_hid_emumouse_dev->id.version = 0x0100; + + mac_hid_emumouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + mac_hid_emumouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + mac_hid_emumouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + + err = input_register_device(mac_hid_emumouse_dev); + if (err) { + input_free_device(mac_hid_emumouse_dev); + mac_hid_emumouse_dev = NULL; + return err; + } + + return 0; +} + +static void mac_hid_destroy_emumouse(void) +{ + input_unregister_device(mac_hid_emumouse_dev); + mac_hid_emumouse_dev = NULL; +} + +static bool mac_hid_emumouse_filter(struct input_handle *handle, + unsigned int type, unsigned int code, + int value) +{ + unsigned int btn; + + if (type != EV_KEY) + return false; + + if (code == mouse_button2_keycode) + btn = BTN_MIDDLE; + else if (code == mouse_button3_keycode) + btn = BTN_RIGHT; + else + return false; + + input_report_key(mac_hid_emumouse_dev, btn, value); + input_sync(mac_hid_emumouse_dev); + + return true; +} + +static int mac_hid_emumouse_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + int error; + + /* Don't bind to ourselves */ + if (dev == mac_hid_emumouse_dev) + return -ENODEV; + + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; + + handle->dev = dev; + handle->handler = handler; + handle->name = "mac-button-emul"; + + error = input_register_handle(handle); + if (error) { + printk(KERN_ERR + "mac_hid: Failed to register button emulation handle, " + "error %d\n", error); + goto err_free; + } + + error = input_open_device(handle); + if (error) { + printk(KERN_ERR + "mac_hid: Failed to open input device, error %d\n", + error); + goto err_unregister; + } + + return 0; + + err_unregister: + input_unregister_handle(handle); + err_free: + kfree(handle); + return error; +} + +static void mac_hid_emumouse_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + kfree(handle); +} + +static const struct input_device_id mac_hid_emumouse_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, + .evbit = { BIT_MASK(EV_KEY) }, + }, + { }, +}; + +MODULE_DEVICE_TABLE(input, mac_hid_emumouse_ids); + +static struct input_handler mac_hid_emumouse_handler = { + .filter = mac_hid_emumouse_filter, + .connect = mac_hid_emumouse_connect, + .disconnect = mac_hid_emumouse_disconnect, + .name = "mac-button-emul", + .id_table = mac_hid_emumouse_ids, +}; + +static int mac_hid_start_emulation(void) +{ + int err; + + err = mac_hid_create_emumouse(); + if (err) + return err; + + err = input_register_handler(&mac_hid_emumouse_handler); + if (err) { + mac_hid_destroy_emumouse(); + return err; + } + + return 0; +} + +static void mac_hid_stop_emulation(void) +{ + input_unregister_handler(&mac_hid_emumouse_handler); + mac_hid_destroy_emumouse(); +} + +static int mac_hid_toggle_emumouse(ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int *valp = table->data; + int old_val = *valp; + int rc; + + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { + if (*valp == 1) + rc = mac_hid_start_emulation(); + else if (*valp == 0) + mac_hid_stop_emulation(); + else + rc = -EINVAL; + } + + /* Restore the old value in case of error */ + if (rc) + *valp = old_val; + + return rc; +} + /* file(s) in /proc/sys/dev/mac_hid */ static ctl_table mac_hid_files[] = { { @@ -31,7 +209,7 @@ static ctl_table mac_hid_files[] = { .data = &mouse_emulate_buttons, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = mac_hid_toggle_emumouse, }, { .procname = "mouse_button2_keycode", @@ -74,73 +252,12 @@ static ctl_table mac_hid_root_dir[] = { static struct ctl_table_header *mac_hid_sysctl_header; -#endif /* endif CONFIG_SYSCTL */ - -int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) -{ - switch (caller) { - case 1: - /* Called from keyboard.c */ - if (mouse_emulate_buttons - && (keycode == mouse_button2_keycode - || keycode == mouse_button3_keycode)) { - if (mouse_emulate_buttons == 1) { - input_report_key(emumousebtn, - keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT, - down); - input_sync(emumousebtn); - return 1; - } - mouse_last_keycode = down ? keycode : 0; - } - break; - } - return 0; -} - -static struct lock_class_key emumousebtn_event_class; -static struct lock_class_key emumousebtn_mutex_class; - -static int emumousebtn_input_register(void) -{ - int ret; - - emumousebtn = input_allocate_device(); - if (!emumousebtn) - return -ENOMEM; - - lockdep_set_class(&emumousebtn->event_lock, &emumousebtn_event_class); - lockdep_set_class(&emumousebtn->mutex, &emumousebtn_mutex_class); - - emumousebtn->name = "Macintosh mouse button emulation"; - emumousebtn->id.bustype = BUS_ADB; - emumousebtn->id.vendor = 0x0001; - emumousebtn->id.product = 0x0001; - emumousebtn->id.version = 0x0100; - - emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - - ret = input_register_device(emumousebtn); - if (ret) - input_free_device(emumousebtn); - - return ret; -} static int __init mac_hid_init(void) { - int err; - - err = emumousebtn_input_register(); - if (err) - return err; - -#if defined(CONFIG_SYSCTL) mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir); -#endif /* CONFIG_SYSCTL */ + if (!mac_hid_sysctl_header) + return -ENOMEM; return 0; } diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 8bdb16bfe5fb..506ad20c18f8 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -161,7 +161,4 @@ static inline void con_schedule_flip(struct tty_struct *t) schedule_delayed_work(&t->buf.work, 0); } -/* mac_hid.c */ -extern int mac_hid_mouse_emulate_buttons(int, unsigned int, int); - #endif -- cgit v1.2.3 From 8c961bcca1d10be4f2c06375eb561679167653a0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 1 Feb 2010 18:46:10 +0000 Subject: ASoC: Allow CODECs to ask soc-cache to suppress physical writes Currently the soc-cache code will always write to the device, meaning that we need the device to be powered and active at pretty much all times the system is active. Allowing cache only writes lays some groundwork for future enhancements to allow devices to be put into a full off state when the audio subsystem is idle. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 1 + sound/soc/soc-cache.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index 4bbeb9f83ece..4e8f14bc8ed3 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -423,6 +423,7 @@ struct snd_soc_codec { short reg_cache_step; unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ + unsigned int cache_only:1; /* Suppress writes to hardware */ /* dapm */ u32 pop_time; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 097e33510a7a..84b6916db87d 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -38,6 +38,10 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; + + if (codec->cache_only) + return 0; + ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; @@ -100,6 +104,10 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; + + if (codec->cache_only) + return 0; + ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; @@ -153,6 +161,9 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; + if (codec->cache_only) + return 0; + if (codec->hw_write(codec->control_data, data, 2) == 2) return 0; else @@ -181,6 +192,9 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, if (!snd_soc_codec_volatile_register(codec, reg)) reg_cache[reg] = value; + if (codec->cache_only) + return 0; + if (codec->hw_write(codec->control_data, data, 3) == 3) return 0; else @@ -193,10 +207,14 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, u16 *cache = codec->reg_cache; if (reg >= codec->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg)) + snd_soc_codec_volatile_register(codec, reg)) { + if (codec->cache_only) + return -EINVAL; + return codec->hw_read(codec, reg); - else + } else { return cache[reg]; + } } #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) @@ -294,6 +312,10 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, reg &= 0xff; if (reg < codec->reg_cache_size) cache[reg] = value; + + if (codec->cache_only) + return 0; + ret = codec->hw_write(codec->control_data, data, 3); if (ret == 3) return 0; -- cgit v1.2.3 From 0b7024ac4df5821347141c18e680b7166bc1cb20 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 2 Feb 2010 21:08:26 -0800 Subject: Input: add match() method to input hanlders Get rid of blacklist in input handler structure and instead allow handlers to define their own match() method to perform fine-grained filtering of supported devices. Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 24 ++++++++++++++++-------- drivers/input/input.c | 13 ++++++------- drivers/input/joydev.c | 32 +++++++++++++++----------------- include/linux/input.h | 6 +++--- 4 files changed, 40 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cbf64b985ef4..ada25bb8941e 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, schedule_console_callback(); } +static bool kbd_match(struct input_handler *handler, struct input_dev *dev) +{ + int i; + + if (test_bit(EV_SND, dev->evbit)) + return true; + + if (test_bit(EV_KEY, dev->evbit)) + for (i = KEY_RESERVED; i < BTN_MISC; i++) + if (test_bit(i, dev->keybit)) + return true; + + return false; +} + /* * When a keyboard (or other input device) is found, the kbd_connect * function is called. The function then looks at the device, and if it @@ -1334,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, { struct input_handle *handle; int error; - int i; - - for (i = KEY_RESERVED; i < BTN_MISC; i++) - if (test_bit(i, dev->keybit)) - break; - - if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) - return -ENODEV; handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); if (!handle) @@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids); static struct input_handler kbd_handler = { .event = kbd_event, + .match = kbd_match, .connect = kbd_connect, .disconnect = kbd_disconnect, .start = kbd_start, diff --git a/drivers/input/input.c b/drivers/input/input.c index 7080a9d4b840..dae49eba6ccd 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode); if (i != BITS_TO_LONGS(max)) \ continue; -static const struct input_device_id *input_match_device(const struct input_device_id *id, +static const struct input_device_id *input_match_device(struct input_handler *handler, struct input_dev *dev) { + const struct input_device_id *id; int i; - for (; id->flags || id->driver_info; id++) { + for (id = handler->id_table; id->flags || id->driver_info; id++) { if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) if (id->bustype != dev->id.bustype) @@ -756,7 +757,8 @@ static const struct input_device_id *input_match_device(const struct input_devic MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(swbit, SW_MAX); - return id; + if (!handler->match || handler->match(handler, dev)) + return id; } return NULL; @@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han const struct input_device_id *id; int error; - if (handler->blacklist && input_match_device(handler->blacklist, dev)) - return -ENODEV; - - id = input_match_device(handler->id_table, dev); + id = input_match_device(handler, dev); if (!id) return -ENODEV; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..63e71f2a7acc 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev) input_close_device(handle); } + +static bool joydev_match(struct input_handler *handler, struct input_dev *dev) +{ + /* Avoid touchpads and touchscreens */ + if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) + return false; + + /* Avoid tablets, digitisers and similar devices */ + if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) + return false; + + return true; +} + static int joydev_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { @@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle) put_device(&joydev->dev); } -static const struct input_device_id joydev_blacklist[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - }, /* Avoid itouchpads and touchscreens */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, - }, /* Avoid tablets, digitisers and similar devices */ - { } /* Terminating entry */ -}; - static const struct input_device_id joydev_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | @@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); static struct input_handler joydev_handler = { .event = joydev_event, + .match = joydev_match, .connect = joydev_connect, .disconnect = joydev_disconnect, .fops = &joydev_fops, .minor = JOYDEV_MINOR_BASE, .name = "joydev", .id_table = joydev_ids, - .blacklist = joydev_blacklist, }; static int __init joydev_init(void) diff --git a/include/linux/input.h b/include/linux/input.h index 6c9d3d49fa91..8dc5d724c703 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1200,6 +1200,8 @@ struct input_handle; * it may not sleep * @filter: similar to @event; separates normal event handlers from * "filters". + * @match: called after comparing device's id with handler's id_table + * to perform fine-grained matching between device and handler * @connect: called when attaching a handler to an input device * @disconnect: disconnects a handler from input device * @start: starts handler for given handle. This function is called by @@ -1211,8 +1213,6 @@ struct input_handle; * @name: name of the handler, to be shown in /proc/bus/input/handlers * @id_table: pointer to a table of input_device_ids this driver can * handle - * @blacklist: pointer to a table of input_device_ids this driver should - * ignore even if they match @id_table * @h_list: list of input handles associated with the handler * @node: for placing the driver onto input_handler_list * @@ -1235,6 +1235,7 @@ struct input_handler { void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); + bool (*match)(struct input_handler *handler, struct input_dev *dev); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); @@ -1244,7 +1245,6 @@ struct input_handler { const char *name; const struct input_device_id *id_table; - const struct input_device_id *blacklist; struct list_head h_list; struct list_head node; -- cgit v1.2.3 From 9e3af04f8787315f63f55b191bb9a06741dbf183 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 4 Feb 2010 00:48:00 -0800 Subject: Input: gpio-keys - add support for disabling gpios through sysfs Now gpio-keys input driver exports 4 new attributes to userland through sysfs: /sys/devices/platform/gpio-keys/keys [ro] /sys/devices/platform/gpio-keys/switches [ro] /sys/devices/platform/gpio-keys/disabled_keys [rw] /sys/devices/platform/gpio-keys/disables_switches [rw] With these attributes, userland program can read which keys and switches can be disabled and then disable/enable them as needed. Keys and switches are exported as stringified bitmap of codes (keycodes or switch codes). For example keys 15, 89, 100, 101, 102 are exported as: '15,89,100-102'. Description of the attributes: keys - bitmap of keys which can be disabled switches - bitmap of switches which can be disabled disabled_keys - bitmap of currently disabled keys (bit 1 means disabled, 0 enabled) disabled_switches - bitmap of currently disabled switches (bit 1 means disabled, 0 enabled) Signed-off-by: Mika Westerberg Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 318 +++++++++++++++++++++++++++++++++++-- include/linux/gpio_keys.h | 1 + 2 files changed, 308 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 1aff3b76effd..2b708aa85553 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -30,13 +30,289 @@ struct gpio_button_data { struct input_dev *input; struct timer_list timer; struct work_struct work; + bool disabled; }; struct gpio_keys_drvdata { struct input_dev *input; + struct mutex disable_lock; + unsigned int n_buttons; struct gpio_button_data data[0]; }; +/* + * SYSFS interface for enabling/disabling keys and switches: + * + * There are 4 attributes under /sys/devices/platform/gpio-keys/ + * keys [ro] - bitmap of keys (EV_KEY) which can be + * disabled + * switches [ro] - bitmap of switches (EV_SW) which can be + * disabled + * disabled_keys [rw] - bitmap of keys currently disabled + * disabled_switches [rw] - bitmap of switches currently disabled + * + * Userland can change these values and hence disable event generation + * for each key (or switch). Disabling a key means its interrupt line + * is disabled. + * + * For example, if we have following switches set up as gpio-keys: + * SW_DOCK = 5 + * SW_CAMERA_LENS_COVER = 9 + * SW_KEYPAD_SLIDE = 10 + * SW_FRONT_PROXIMITY = 11 + * This is read from switches: + * 11-9,5 + * Next we want to disable proximity (11) and dock (5), we write: + * 11,5 + * to file disabled_switches. Now proximity and dock IRQs are disabled. + * This can be verified by reading the file disabled_switches: + * 11,5 + * If we now want to enable proximity (11) switch we write: + * 5 + * to disabled_switches. + * + * We can disable only those keys which don't allow sharing the irq. + */ + +/** + * get_n_events_by_type() - returns maximum number of events per @type + * @type: type of button (%EV_KEY, %EV_SW) + * + * Return value of this function can be used to allocate bitmap + * large enough to hold all bits for given type. + */ +static inline int get_n_events_by_type(int type) +{ + BUG_ON(type != EV_SW && type != EV_KEY); + + return (type == EV_KEY) ? KEY_CNT : SW_CNT; +} + +/** + * gpio_keys_disable_button() - disables given GPIO button + * @bdata: button data for button to be disabled + * + * Disables button pointed by @bdata. This is done by masking + * IRQ line. After this function is called, button won't generate + * input events anymore. Note that one can only disable buttons + * that don't share IRQs. + * + * Make sure that @bdata->disable_lock is locked when entering + * this function to avoid races when concurrent threads are + * disabling buttons at the same time. + */ +static void gpio_keys_disable_button(struct gpio_button_data *bdata) +{ + if (!bdata->disabled) { + /* + * Disable IRQ and possible debouncing timer. + */ + disable_irq(gpio_to_irq(bdata->button->gpio)); + if (bdata->button->debounce_interval) + del_timer_sync(&bdata->timer); + + bdata->disabled = true; + } +} + +/** + * gpio_keys_enable_button() - enables given GPIO button + * @bdata: button data for button to be disabled + * + * Enables given button pointed by @bdata. + * + * Make sure that @bdata->disable_lock is locked when entering + * this function to avoid races with concurrent threads trying + * to enable the same button at the same time. + */ +static void gpio_keys_enable_button(struct gpio_button_data *bdata) +{ + if (bdata->disabled) { + enable_irq(gpio_to_irq(bdata->button->gpio)); + bdata->disabled = false; + } +} + +/** + * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons + * @ddata: pointer to drvdata + * @buf: buffer where stringified bitmap is written + * @type: button type (%EV_KEY, %EV_SW) + * @only_disabled: does caller want only those buttons that are + * currently disabled or all buttons that can be + * disabled + * + * This function writes buttons that can be disabled to @buf. If + * @only_disabled is true, then @buf contains only those buttons + * that are currently disabled. Returns 0 on success or negative + * errno on failure. + */ +static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, + char *buf, unsigned int type, + bool only_disabled) +{ + int n_events = get_n_events_by_type(type); + unsigned long *bits; + ssize_t ret; + int i; + + bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); + if (!bits) + return -ENOMEM; + + for (i = 0; i < ddata->n_buttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (bdata->button->type != type) + continue; + + if (only_disabled && !bdata->disabled) + continue; + + __set_bit(bdata->button->code, bits); + } + + ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); + buf[ret++] = '\n'; + buf[ret] = '\0'; + + kfree(bits); + + return ret; +} + +/** + * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap + * @ddata: pointer to drvdata + * @buf: buffer from userspace that contains stringified bitmap + * @type: button type (%EV_KEY, %EV_SW) + * + * This function parses stringified bitmap from @buf and disables/enables + * GPIO buttons accordinly. Returns 0 on success and negative error + * on failure. + */ +static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, + const char *buf, unsigned int type) +{ + int n_events = get_n_events_by_type(type); + unsigned long *bits; + ssize_t error; + int i; + + bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); + if (!bits) + return -ENOMEM; + + error = bitmap_parselist(buf, bits, n_events); + if (error) + goto out; + + /* First validate */ + for (i = 0; i < ddata->n_buttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (bdata->button->type != type) + continue; + + if (test_bit(bdata->button->code, bits) && + !bdata->button->can_disable) { + error = -EINVAL; + goto out; + } + } + + mutex_lock(&ddata->disable_lock); + + for (i = 0; i < ddata->n_buttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (bdata->button->type != type) + continue; + + if (test_bit(bdata->button->code, bits)) + gpio_keys_disable_button(bdata); + else + gpio_keys_enable_button(bdata); + } + + mutex_unlock(&ddata->disable_lock); + +out: + kfree(bits); + return error; +} + +#define ATTR_SHOW_FN(name, type, only_disabled) \ +static ssize_t gpio_keys_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct platform_device *pdev = to_platform_device(dev); \ + struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ + \ + return gpio_keys_attr_show_helper(ddata, buf, \ + type, only_disabled); \ +} + +ATTR_SHOW_FN(keys, EV_KEY, false); +ATTR_SHOW_FN(switches, EV_SW, false); +ATTR_SHOW_FN(disabled_keys, EV_KEY, true); +ATTR_SHOW_FN(disabled_switches, EV_SW, true); + +/* + * ATTRIBUTES: + * + * /sys/devices/platform/gpio-keys/keys [ro] + * /sys/devices/platform/gpio-keys/switches [ro] + */ +static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); +static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); + +#define ATTR_STORE_FN(name, type) \ +static ssize_t gpio_keys_store_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, \ + size_t count) \ +{ \ + struct platform_device *pdev = to_platform_device(dev); \ + struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ + ssize_t error; \ + \ + error = gpio_keys_attr_store_helper(ddata, buf, type); \ + if (error) \ + return error; \ + \ + return count; \ +} + +ATTR_STORE_FN(disabled_keys, EV_KEY); +ATTR_STORE_FN(disabled_switches, EV_SW); + +/* + * ATTRIBUTES: + * + * /sys/devices/platform/gpio-keys/disabled_keys [rw] + * /sys/devices/platform/gpio-keys/disables_switches [rw] + */ +static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, + gpio_keys_show_disabled_keys, + gpio_keys_store_disabled_keys); +static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, + gpio_keys_show_disabled_switches, + gpio_keys_store_disabled_switches); + +static struct attribute *gpio_keys_attrs[] = { + &dev_attr_keys.attr, + &dev_attr_switches.attr, + &dev_attr_disabled_keys.attr, + &dev_attr_disabled_switches.attr, + NULL, +}; + +static struct attribute_group gpio_keys_attr_group = { + .attrs = gpio_keys_attrs, +}; + static void gpio_keys_report_event(struct gpio_button_data *bdata) { struct gpio_keys_button *button = bdata->button; @@ -79,11 +355,13 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit gpio_keys_setup_key(struct device *dev, +static int __devinit gpio_keys_setup_key(struct platform_device *pdev, struct gpio_button_data *bdata, struct gpio_keys_button *button) { char *desc = button->desc ? button->desc : "gpio_keys"; + struct device *dev = &pdev->dev; + unsigned long irqflags; int irq, error; setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); @@ -112,10 +390,15 @@ static int __devinit gpio_keys_setup_key(struct device *dev, goto fail3; } - error = request_irq(irq, gpio_keys_isr, - IRQF_SHARED | - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - desc, bdata); + irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + /* + * If platform has specified that the button can be disabled, + * we don't want it to share the interrupt line. + */ + if (!button->can_disable) + irqflags |= IRQF_SHARED; + + error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", irq, error); @@ -149,6 +432,10 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) goto fail1; } + ddata->input = input; + ddata->n_buttons = pdata->nbuttons; + mutex_init(&ddata->disable_lock); + platform_set_drvdata(pdev, ddata); input->name = pdev->name; @@ -164,8 +451,6 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) if (pdata->rep) __set_bit(EV_REP, input->evbit); - ddata->input = input; - for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_button_data *bdata = &ddata->data[i]; @@ -174,7 +459,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) bdata->input = input; bdata->button = button; - error = gpio_keys_setup_key(dev, bdata, button); + error = gpio_keys_setup_key(pdev, bdata, button); if (error) goto fail2; @@ -184,13 +469,20 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input_set_capability(input, type, button->code); } - error = input_register_device(input); + error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); if (error) { - dev_err(dev, "Unable to register input device, " - "error: %d\n", error); + dev_err(dev, "Unable to export keys/switches, error: %d\n", + error); goto fail2; } + error = input_register_device(input); + if (error) { + dev_err(dev, "Unable to register input device, error: %d\n", + error); + goto fail3; + } + /* get current state of buttons */ for (i = 0; i < pdata->nbuttons; i++) gpio_keys_report_event(&ddata->data[i]); @@ -200,6 +492,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) return 0; + fail3: + sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); fail2: while (--i >= 0) { free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); @@ -224,6 +518,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) struct input_dev *input = ddata->input; int i; + sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); + device_init_wakeup(&pdev->dev, 0); for (i = 0; i < pdata->nbuttons; i++) { diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 1289fa7623ca..cd0b3f30f48e 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -10,6 +10,7 @@ struct gpio_keys_button { int type; /* input event type (EV_KEY, EV_SW) */ int wakeup; /* configure the button as a wake-up source */ int debounce_interval; /* debounce ticks interval in msecs */ + bool can_disable; }; struct gpio_keys_platform_data { -- cgit v1.2.3 From a3032b47c46920ed3f2fd58e64f484e3dab49f23 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 1 Feb 2010 18:48:03 +0000 Subject: ASoC: Add a cache_sync bit to the CODEC structure Add a bit to the CODEC structure indicating if a cache sync is required. By default this will be set if a cache only write is done to a soc-cache register cache. This allows us to avoid syncing the cache back after using cache only writes if there were no changes. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 1 + sound/soc/soc-cache.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/sound/soc.h b/include/sound/soc.h index 4e8f14bc8ed3..e6a6d10de1d3 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -424,6 +424,7 @@ struct snd_soc_codec { unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ unsigned int cache_only:1; /* Suppress writes to hardware */ + unsigned int cache_sync:1; /* Cache needs to be synced to hardware */ /* dapm */ u32 pop_time; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 84b6916db87d..5869dc3be781 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -39,8 +39,10 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; - if (codec->cache_only) + if (codec->cache_only) { + codec->cache_sync = 1; return 0; + } ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) @@ -105,8 +107,10 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; - if (codec->cache_only) + if (codec->cache_only) { + codec->cache_sync = 1; return 0; + } ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) @@ -161,8 +165,10 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; - if (codec->cache_only) + if (codec->cache_only) { + codec->cache_sync = 1; return 0; + } if (codec->hw_write(codec->control_data, data, 2) == 2) return 0; @@ -192,8 +198,10 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, if (!snd_soc_codec_volatile_register(codec, reg)) reg_cache[reg] = value; - if (codec->cache_only) + if (codec->cache_only) { + codec->cache_sync = 1; return 0; + } if (codec->hw_write(codec->control_data, data, 3) == 3) return 0; @@ -313,8 +321,10 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, if (reg < codec->reg_cache_size) cache[reg] = value; - if (codec->cache_only) + if (codec->cache_only) { + codec->cache_sync = 1; return 0; + } ret = codec->hw_write(codec->control_data, data, 3); if (ret == 3) -- cgit v1.2.3 From 8ee2bf9ab792d0c02b13ca3acbd036debb7745d9 Mon Sep 17 00:00:00 2001 From: Sriramakrishnan Date: Thu, 19 Nov 2009 15:58:25 +0530 Subject: TI Davinci EMAC : Re-use driver for other platforms. The davinci EMAC peripheral is also available on other TI platforms -notably TI AM3517 SoC. This patch modifies the config option and the platform structure header files so that the driver can be reused on non-davinci platforms as well. Signed-off-by: Sriramakrishnan Acked-by: Chaithrika U S Acked-by: David S. Miller Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/common.c | 2 +- arch/arm/mach-davinci/include/mach/da8xx.h | 2 +- arch/arm/mach-davinci/include/mach/dm365.h | 2 +- arch/arm/mach-davinci/include/mach/dm644x.h | 2 +- arch/arm/mach-davinci/include/mach/dm646x.h | 2 +- arch/arm/mach-davinci/include/mach/emac.h | 36 ----------------------------- drivers/net/Kconfig | 2 +- drivers/net/davinci_emac.c | 3 +-- include/linux/davinci_emac.h | 36 +++++++++++++++++++++++++++++ 9 files changed, 43 insertions(+), 44 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/emac.h create mode 100644 include/linux/davinci_emac.h (limited to 'include') diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index c2de94cde56a..94f27cbcd55a 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -11,13 +11,13 @@ #include #include #include +#include #include #include #include #include -#include #include "clock.h" diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index d43a4b6b6d76..d9a7f11894c4 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -13,10 +13,10 @@ #include