···798798 setup before initializing the codecs. This option is799799 available only when CONFIG_SND_HDA_PATCH_LOADER=y is set.800800 See HD-Audio.txt for details.801801+ beep_mode - Selects the beep registration mode (0=off, 1=on, 2=802802+ dynamic registration via mute switch on/off); the default803803+ value is set via CONFIG_SND_HDA_INPUT_BEEP_MODE kconfig.801804802805 [Single (global) options]803806 single_cmd - Use single immediate commands to communicate with
+1
Documentation/sound/alsa/HD-Audio-Models.txt
···391391 ref Reference board392392 mic-ref Reference board with power management for ports393393 dell-s14 Dell laptop394394+ hp HP laptops with (inverted) mute-LED394395 auto BIOS setup (default)395396396397STAC9872
+321
include/sound/ak4113.h
···11+#ifndef __SOUND_AK4113_H22+#define __SOUND_AK4113_H33+44+/*55+ * Routines for Asahi Kasei AK411366+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,77+ * Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com>,88+ *99+ *1010+ * This program is free software; you can redistribute it and/or modify1111+ * it under the terms of the GNU General Public License as published by1212+ * the Free Software Foundation; either version 2 of the License, or1313+ * (at your option) any later version.1414+ *1515+ * This program is distributed in the hope that it will be useful,1616+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1717+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1818+ * GNU General Public License for more details.1919+ *2020+ * You should have received a copy of the GNU General Public License2121+ * along with this program; if not, write to the Free Software2222+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA2323+ *2424+ */2525+2626+/* AK4113 registers */2727+/* power down */2828+#define AK4113_REG_PWRDN 0x002929+/* format control */3030+#define AK4113_REG_FORMAT 0x013131+/* input/output control */3232+#define AK4113_REG_IO0 0x023333+/* input/output control */3434+#define AK4113_REG_IO1 0x033535+/* interrupt0 mask */3636+#define AK4113_REG_INT0_MASK 0x043737+/* interrupt1 mask */3838+#define AK4113_REG_INT1_MASK 0x053939+/* DAT mask & DTS select */4040+#define AK4113_REG_DATDTS 0x064141+/* receiver status 0 */4242+#define AK4113_REG_RCS0 0x074343+/* receiver status 1 */4444+#define AK4113_REG_RCS1 0x084545+/* receiver status 2 */4646+#define AK4113_REG_RCS2 0x094747+/* RX channel status byte 0 */4848+#define AK4113_REG_RXCSB0 0x0a4949+/* RX channel status byte 1 */5050+#define AK4113_REG_RXCSB1 0x0b5151+/* RX channel status byte 2 */5252+#define AK4113_REG_RXCSB2 0x0c5353+/* RX channel status byte 3 */5454+#define AK4113_REG_RXCSB3 0x0d5555+/* RX channel status byte 4 */5656+#define AK4113_REG_RXCSB4 0x0e5757+/* burst preamble Pc byte 0 */5858+#define AK4113_REG_Pc0 0x0f5959+/* burst preamble Pc byte 1 */6060+#define AK4113_REG_Pc1 0x106161+/* burst preamble Pd byte 0 */6262+#define AK4113_REG_Pd0 0x116363+/* burst preamble Pd byte 1 */6464+#define AK4113_REG_Pd1 0x126565+/* Q-subcode address + control */6666+#define AK4113_REG_QSUB_ADDR 0x136767+/* Q-subcode track */6868+#define AK4113_REG_QSUB_TRACK 0x146969+/* Q-subcode index */7070+#define AK4113_REG_QSUB_INDEX 0x157171+/* Q-subcode minute */7272+#define AK4113_REG_QSUB_MINUTE 0x167373+/* Q-subcode second */7474+#define AK4113_REG_QSUB_SECOND 0x177575+/* Q-subcode frame */7676+#define AK4113_REG_QSUB_FRAME 0x187777+/* Q-subcode zero */7878+#define AK4113_REG_QSUB_ZERO 0x197979+/* Q-subcode absolute minute */8080+#define AK4113_REG_QSUB_ABSMIN 0x1a8181+/* Q-subcode absolute second */8282+#define AK4113_REG_QSUB_ABSSEC 0x1b8383+/* Q-subcode absolute frame */8484+#define AK4113_REG_QSUB_ABSFRM 0x1c8585+8686+/* sizes */8787+#define AK4113_REG_RXCSB_SIZE ((AK4113_REG_RXCSB4-AK4113_REG_RXCSB0)+1)8888+#define AK4113_REG_QSUB_SIZE ((AK4113_REG_QSUB_ABSFRM-AK4113_REG_QSUB_ADDR)\8989+ +1)9090+9191+#define AK4113_WRITABLE_REGS (AK4113_REG_DATDTS + 1)9292+9393+/* AK4113_REG_PWRDN bits */9494+/* Channel Status Select */9595+#define AK4113_CS12 (1<<7)9696+/* Block Start & C/U Output Mode */9797+#define AK4113_BCU (1<<6)9898+/* Master Clock Operation Select */9999+#define AK4113_CM1 (1<<5)100100+/* Master Clock Operation Select */101101+#define AK4113_CM0 (1<<4)102102+/* Master Clock Frequency Select */103103+#define AK4113_OCKS1 (1<<3)104104+/* Master Clock Frequency Select */105105+#define AK4113_OCKS0 (1<<2)106106+/* 0 = power down, 1 = normal operation */107107+#define AK4113_PWN (1<<1)108108+/* 0 = reset & initialize (except thisregister), 1 = normal operation */109109+#define AK4113_RST (1<<0)110110+111111+/* AK4113_REQ_FORMAT bits */112112+/* V/TX Output select: 0 = Validity Flag Output, 1 = TX */113113+#define AK4113_VTX (1<<7)114114+/* Audio Data Control */115115+#define AK4113_DIF2 (1<<6)116116+/* Audio Data Control */117117+#define AK4113_DIF1 (1<<5)118118+/* Audio Data Control */119119+#define AK4113_DIF0 (1<<4)120120+/* Deemphasis Autodetect Enable (1 = enable) */121121+#define AK4113_DEAU (1<<3)122122+/* 32kHz-48kHz Deemphasis Control */123123+#define AK4113_DEM1 (1<<2)124124+/* 32kHz-48kHz Deemphasis Control */125125+#define AK4113_DEM0 (1<<1)126126+#define AK4113_DEM_OFF (AK4113_DEM0)127127+#define AK4113_DEM_44KHZ (0)128128+#define AK4113_DEM_48KHZ (AK4113_DEM1)129129+#define AK4113_DEM_32KHZ (AK4113_DEM0|AK4113_DEM1)130130+/* STDO: 16-bit, right justified */131131+#define AK4113_DIF_16R (0)132132+/* STDO: 18-bit, right justified */133133+#define AK4113_DIF_18R (AK4113_DIF0)134134+/* STDO: 20-bit, right justified */135135+#define AK4113_DIF_20R (AK4113_DIF1)136136+/* STDO: 24-bit, right justified */137137+#define AK4113_DIF_24R (AK4113_DIF1|AK4113_DIF0)138138+/* STDO: 24-bit, left justified */139139+#define AK4113_DIF_24L (AK4113_DIF2)140140+/* STDO: I2S */141141+#define AK4113_DIF_24I2S (AK4113_DIF2|AK4113_DIF0)142142+/* STDO: 24-bit, left justified; LRCLK, BICK = Input */143143+#define AK4113_DIF_I24L (AK4113_DIF2|AK4113_DIF1)144144+/* STDO: I2S; LRCLK, BICK = Input */145145+#define AK4113_DIF_I24I2S (AK4113_DIF2|AK4113_DIF1|AK4113_DIF0)146146+147147+/* AK4113_REG_IO0 */148148+/* XTL1=0,XTL0=0 -> 11.2896Mhz; XTL1=0,XTL0=1 -> 12.288Mhz */149149+#define AK4113_XTL1 (1<<6)150150+/* XTL1=1,XTL0=0 -> 24.576Mhz; XTL1=1,XTL0=1 -> use channel status */151151+#define AK4113_XTL0 (1<<5)152152+/* Block Start Signal Output: 0 = U-bit, 1 = C-bit (req. BCU = 1) */153153+#define AK4113_UCE (1<<4)154154+/* TX Output Enable (1 = enable) */155155+#define AK4113_TXE (1<<3)156156+/* Output Through Data Selector for TX pin */157157+#define AK4113_OPS2 (1<<2)158158+/* Output Through Data Selector for TX pin */159159+#define AK4113_OPS1 (1<<1)160160+/* Output Through Data Selector for TX pin */161161+#define AK4113_OPS0 (1<<0)162162+/* 11.2896 MHz ref. Xtal freq. */163163+#define AK4113_XTL_11_2896M (0)164164+/* 12.288 MHz ref. Xtal freq. */165165+#define AK4113_XTL_12_288M (AK4113_XTL0)166166+/* 24.576 MHz ref. Xtal freq. */167167+#define AK4113_XTL_24_576M (AK4113_XTL1)168168+169169+/* AK4113_REG_IO1 */170170+/* Interrupt 0 pin Hold */171171+#define AK4113_EFH1 (1<<7)172172+/* Interrupt 0 pin Hold */173173+#define AK4113_EFH0 (1<<6)174174+#define AK4113_EFH_512LRCLK (0)175175+#define AK4113_EFH_1024LRCLK (AK4113_EFH0)176176+#define AK4113_EFH_2048LRCLK (AK4113_EFH1)177177+#define AK4113_EFH_4096LRCLK (AK4113_EFH1|AK4113_EFH0)178178+/* PLL Lock Time: 0 = 384/fs, 1 = 1/fs */179179+#define AK4113_FAST (1<<5)180180+/* MCKO2 Output Select: 0 = CMx/OCKSx, 1 = Xtal */181181+#define AK4113_XMCK (1<<4)182182+/* MCKO2 Output Freq. Select: 0 = x1, 1 = x0.5 (req. XMCK = 1) */183183+#define AK4113_DIV (1<<3)184184+/* Input Recovery Data Select */185185+#define AK4113_IPS2 (1<<2)186186+/* Input Recovery Data Select */187187+#define AK4113_IPS1 (1<<1)188188+/* Input Recovery Data Select */189189+#define AK4113_IPS0 (1<<0)190190+#define AK4113_IPS(x) ((x)&7)191191+192192+/* AK4113_REG_INT0_MASK && AK4113_REG_INT1_MASK*/193193+/* mask enable for QINT bit */194194+#define AK4113_MQI (1<<7)195195+/* mask enable for AUTO bit */196196+#define AK4113_MAUT (1<<6)197197+/* mask enable for CINT bit */198198+#define AK4113_MCIT (1<<5)199199+/* mask enable for UNLOCK bit */200200+#define AK4113_MULK (1<<4)201201+/* mask enable for V bit */202202+#define AK4113_V (1<<3)203203+/* mask enable for STC bit */204204+#define AK4113_STC (1<<2)205205+/* mask enable for AUDN bit */206206+#define AK4113_MAN (1<<1)207207+/* mask enable for PAR bit */208208+#define AK4113_MPR (1<<0)209209+210210+/* AK4113_REG_DATDTS */211211+/* DAT Start ID Counter */212212+#define AK4113_DCNT (1<<4)213213+/* DTS-CD 16-bit Sync Word Detect */214214+#define AK4113_DTS16 (1<<3)215215+/* DTS-CD 14-bit Sync Word Detect */216216+#define AK4113_DTS14 (1<<2)217217+/* mask enable for DAT bit (if 1, no INT1 effect */218218+#define AK4113_MDAT1 (1<<1)219219+/* mask enable for DAT bit (if 1, no INT0 effect */220220+#define AK4113_MDAT0 (1<<0)221221+222222+/* AK4113_REG_RCS0 */223223+/* Q-subcode buffer interrupt, 0 = no change, 1 = changed */224224+#define AK4113_QINT (1<<7)225225+/* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */226226+#define AK4113_AUTO (1<<6)227227+/* channel status buffer interrupt, 0 = no change, 1 = change */228228+#define AK4113_CINT (1<<5)229229+/* PLL lock status, 0 = lock, 1 = unlock */230230+#define AK4113_UNLCK (1<<4)231231+/* Validity bit, 0 = valid, 1 = invalid */232232+#define AK4113_V (1<<3)233233+/* sampling frequency or Pre-emphasis change, 0 = no detect, 1 = detect */234234+#define AK4113_STC (1<<2)235235+/* audio bit output, 0 = audio, 1 = non-audio */236236+#define AK4113_AUDION (1<<1)237237+/* parity error or biphase error status, 0 = no error, 1 = error */238238+#define AK4113_PAR (1<<0)239239+240240+/* AK4113_REG_RCS1 */241241+/* sampling frequency detection */242242+#define AK4113_FS3 (1<<7)243243+#define AK4113_FS2 (1<<6)244244+#define AK4113_FS1 (1<<5)245245+#define AK4113_FS0 (1<<4)246246+/* Pre-emphasis detect, 0 = OFF, 1 = ON */247247+#define AK4113_PEM (1<<3)248248+/* DAT Start ID Detect, 0 = no detect, 1 = detect */249249+#define AK4113_DAT (1<<2)250250+/* DTS-CD bit audio stream detect, 0 = no detect, 1 = detect */251251+#define AK4113_DTSCD (1<<1)252252+/* Non-PCM bit stream detection, 0 = no detect, 1 = detect */253253+#define AK4113_NPCM (1<<0)254254+#define AK4113_FS_8000HZ (AK4113_FS3|AK4113_FS0)255255+#define AK4113_FS_11025HZ (AK4113_FS2|AK4113_FS0)256256+#define AK4113_FS_16000HZ (AK4113_FS2|AK4113_FS1|AK4113_FS0)257257+#define AK4113_FS_22050HZ (AK4113_FS2)258258+#define AK4113_FS_24000HZ (AK4113_FS2|AK4113_FS1)259259+#define AK4113_FS_32000HZ (AK4113_FS1|AK4113_FS0)260260+#define AK4113_FS_44100HZ (0)261261+#define AK4113_FS_48000HZ (AK4113_FS1)262262+#define AK4113_FS_64000HZ (AK4113_FS3|AK4113_FS1|AK4113_FS0)263263+#define AK4113_FS_88200HZ (AK4113_FS3)264264+#define AK4113_FS_96000HZ (AK4113_FS3|AK4113_FS1)265265+#define AK4113_FS_176400HZ (AK4113_FS3|AK4113_FS2)266266+#define AK4113_FS_192000HZ (AK4113_FS3|AK4113_FS2|AK4113_FS1)267267+268268+/* AK4113_REG_RCS2 */269269+/* CRC for Q-subcode, 0 = no error, 1 = error */270270+#define AK4113_QCRC (1<<1)271271+/* CRC for channel status, 0 = no error, 1 = error */272272+#define AK4113_CCRC (1<<0)273273+274274+/* flags for snd_ak4113_check_rate_and_errors() */275275+#define AK4113_CHECK_NO_STAT (1<<0) /* no statistics */276276+#define AK4113_CHECK_NO_RATE (1<<1) /* no rate check */277277+278278+#define AK4113_CONTROLS 13279279+280280+typedef void (ak4113_write_t)(void *private_data, unsigned char addr,281281+ unsigned char data);282282+typedef unsigned char (ak4113_read_t)(void *private_data, unsigned char addr);283283+284284+struct ak4113 {285285+ struct snd_card *card;286286+ ak4113_write_t *write;287287+ ak4113_read_t *read;288288+ void *private_data;289289+ unsigned int init:1;290290+ spinlock_t lock;291291+ unsigned char regmap[AK4113_WRITABLE_REGS];292292+ struct snd_kcontrol *kctls[AK4113_CONTROLS];293293+ struct snd_pcm_substream *substream;294294+ unsigned long parity_errors;295295+ unsigned long v_bit_errors;296296+ unsigned long qcrc_errors;297297+ unsigned long ccrc_errors;298298+ unsigned char rcs0;299299+ unsigned char rcs1;300300+ unsigned char rcs2;301301+ struct delayed_work work;302302+ unsigned int check_flags;303303+ void *change_callback_private;304304+ void (*change_callback)(struct ak4113 *ak4113, unsigned char c0,305305+ unsigned char c1);306306+};307307+308308+int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,309309+ ak4113_write_t *write,310310+ const unsigned char pgm[AK4113_WRITABLE_REGS],311311+ void *private_data, struct ak4113 **r_ak4113);312312+void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,313313+ unsigned char mask, unsigned char val);314314+void snd_ak4113_reinit(struct ak4113 *ak4113);315315+int snd_ak4113_build(struct ak4113 *ak4113,316316+ struct snd_pcm_substream *capture_substream);317317+int snd_ak4113_external_rate(struct ak4113 *ak4113);318318+int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags);319319+320320+#endif /* __SOUND_AK4113_H */321321+
+6-6
include/sound/ak4114.h
···95959696/* AK4114_REG_IO0 */9797#define AK4114_TX1E (1<<7) /* TX1 Output Enable (1 = enable) */9898-#define AK4114_OPS12 (1<<2) /* Output Though Data Selector for TX1 pin */9999-#define AK4114_OPS11 (1<<1) /* Output Though Data Selector for TX1 pin */100100-#define AK4114_OPS10 (1<<0) /* Output Though Data Selector for TX1 pin */9898+#define AK4114_OPS12 (1<<6) /* Output Data Selector for TX1 pin */9999+#define AK4114_OPS11 (1<<5) /* Output Data Selector for TX1 pin */100100+#define AK4114_OPS10 (1<<4) /* Output Data Selector for TX1 pin */101101#define AK4114_TX0E (1<<3) /* TX0 Output Enable (1 = enable) */102102-#define AK4114_OPS02 (1<<2) /* Output Though Data Selector for TX0 pin */103103-#define AK4114_OPS01 (1<<1) /* Output Though Data Selector for TX0 pin */104104-#define AK4114_OPS00 (1<<0) /* Output Though Data Selector for TX0 pin */102102+#define AK4114_OPS02 (1<<2) /* Output Data Selector for TX0 pin */103103+#define AK4114_OPS01 (1<<1) /* Output Data Selector for TX0 pin */104104+#define AK4114_OPS00 (1<<0) /* Output Data Selector for TX0 pin */105105106106/* AK4114_REG_IO1 */107107#define AK4114_EFH1 (1<<7) /* Interrupt 0 pin Hold */
+4-1
include/sound/ak4xxx-adda.h
···6868 enum {6969 SND_AK4524, SND_AK4528, SND_AK4529,7070 SND_AK4355, SND_AK4358, SND_AK4381,7171- SND_AK53657171+ SND_AK5365, SND_AK4620,7272 } type;73737474 /* (array) information of combined codecs */···7676 const struct snd_akm4xxx_adc_channel *adc_info;77777878 struct snd_ak4xxx_ops ops;7979+ unsigned int num_chips;8080+ unsigned int total_regs;8181+ const char *name;7982};80838184void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg,
···11+/*22+ * Routines for control of the AK4113 via I2C/4-wire serial interface33+ * IEC958 (S/PDIF) receiver by Asahi Kasei44+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>55+ * Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com>66+ *77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License as published by1010+ * the Free Software Foundation; either version 2 of the License, or1111+ * (at your option) any later version.1212+ *1313+ * This program is distributed in the hope that it will be useful,1414+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1515+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1616+ * GNU General Public License for more details.1717+ *1818+ * You should have received a copy of the GNU General Public License1919+ * along with this program; if not, write to the Free Software2020+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA2121+ *2222+ */2323+2424+#include <linux/slab.h>2525+#include <linux/delay.h>2626+#include <sound/core.h>2727+#include <sound/control.h>2828+#include <sound/pcm.h>2929+#include <sound/ak4113.h>3030+#include <sound/asoundef.h>3131+#include <sound/info.h>3232+3333+MODULE_AUTHOR("Pavel Hofman <pavel.hofman@ivitera.com>");3434+MODULE_DESCRIPTION("AK4113 IEC958 (S/PDIF) receiver by Asahi Kasei");3535+MODULE_LICENSE("GPL");3636+3737+#define AK4113_ADDR 0x00 /* fixed address */3838+3939+static void ak4113_stats(struct work_struct *work);4040+static void ak4113_init_regs(struct ak4113 *chip);4141+4242+4343+static void reg_write(struct ak4113 *ak4113, unsigned char reg,4444+ unsigned char val)4545+{4646+ ak4113->write(ak4113->private_data, reg, val);4747+ if (reg < sizeof(ak4113->regmap))4848+ ak4113->regmap[reg] = val;4949+}5050+5151+static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)5252+{5353+ return ak4113->read(ak4113->private_data, reg);5454+}5555+5656+static void snd_ak4113_free(struct ak4113 *chip)5757+{5858+ chip->init = 1; /* don't schedule new work */5959+ mb();6060+ cancel_delayed_work(&chip->work);6161+ flush_scheduled_work();6262+ kfree(chip);6363+}6464+6565+static int snd_ak4113_dev_free(struct snd_device *device)6666+{6767+ struct ak4113 *chip = device->device_data;6868+ snd_ak4113_free(chip);6969+ return 0;7070+}7171+7272+int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,7373+ ak4113_write_t *write, const unsigned char pgm[5],7474+ void *private_data, struct ak4113 **r_ak4113)7575+{7676+ struct ak4113 *chip;7777+ int err = 0;7878+ unsigned char reg;7979+ static struct snd_device_ops ops = {8080+ .dev_free = snd_ak4113_dev_free,8181+ };8282+8383+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);8484+ if (chip == NULL)8585+ return -ENOMEM;8686+ spin_lock_init(&chip->lock);8787+ chip->card = card;8888+ chip->read = read;8989+ chip->write = write;9090+ chip->private_data = private_data;9191+ INIT_DELAYED_WORK(&chip->work, ak4113_stats);9292+9393+ for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)9494+ chip->regmap[reg] = pgm[reg];9595+ ak4113_init_regs(chip);9696+9797+ chip->rcs0 = reg_read(chip, AK4113_REG_RCS0) & ~(AK4113_QINT |9898+ AK4113_CINT | AK4113_STC);9999+ chip->rcs1 = reg_read(chip, AK4113_REG_RCS1);100100+ chip->rcs2 = reg_read(chip, AK4113_REG_RCS2);101101+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);102102+ if (err < 0)103103+ goto __fail;104104+105105+ if (r_ak4113)106106+ *r_ak4113 = chip;107107+ return 0;108108+109109+__fail:110110+ snd_ak4113_free(chip);111111+ return err < 0 ? err : -EIO;112112+}113113+EXPORT_SYMBOL_GPL(snd_ak4113_create);114114+115115+void snd_ak4113_reg_write(struct ak4113 *chip, unsigned char reg,116116+ unsigned char mask, unsigned char val)117117+{118118+ if (reg >= AK4113_WRITABLE_REGS)119119+ return;120120+ reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);121121+}122122+EXPORT_SYMBOL_GPL(snd_ak4113_reg_write);123123+124124+static void ak4113_init_regs(struct ak4113 *chip)125125+{126126+ unsigned char old = chip->regmap[AK4113_REG_PWRDN], reg;127127+128128+ /* bring the chip to reset state and powerdown state */129129+ reg_write(chip, AK4113_REG_PWRDN, old & ~(AK4113_RST|AK4113_PWN));130130+ udelay(200);131131+ /* release reset, but leave powerdown */132132+ reg_write(chip, AK4113_REG_PWRDN, (old | AK4113_RST) & ~AK4113_PWN);133133+ udelay(200);134134+ for (reg = 1; reg < AK4113_WRITABLE_REGS; reg++)135135+ reg_write(chip, reg, chip->regmap[reg]);136136+ /* release powerdown, everything is initialized now */137137+ reg_write(chip, AK4113_REG_PWRDN, old | AK4113_RST | AK4113_PWN);138138+}139139+140140+void snd_ak4113_reinit(struct ak4113 *chip)141141+{142142+ chip->init = 1;143143+ mb();144144+ flush_scheduled_work();145145+ ak4113_init_regs(chip);146146+ /* bring up statistics / event queing */147147+ chip->init = 0;148148+ if (chip->kctls[0])149149+ schedule_delayed_work(&chip->work, HZ / 10);150150+}151151+EXPORT_SYMBOL_GPL(snd_ak4113_reinit);152152+153153+static unsigned int external_rate(unsigned char rcs1)154154+{155155+ switch (rcs1 & (AK4113_FS0|AK4113_FS1|AK4113_FS2|AK4113_FS3)) {156156+ case AK4113_FS_8000HZ:157157+ return 8000;158158+ case AK4113_FS_11025HZ:159159+ return 11025;160160+ case AK4113_FS_16000HZ:161161+ return 16000;162162+ case AK4113_FS_22050HZ:163163+ return 22050;164164+ case AK4113_FS_24000HZ:165165+ return 24000;166166+ case AK4113_FS_32000HZ:167167+ return 32000;168168+ case AK4113_FS_44100HZ:169169+ return 44100;170170+ case AK4113_FS_48000HZ:171171+ return 48000;172172+ case AK4113_FS_64000HZ:173173+ return 64000;174174+ case AK4113_FS_88200HZ:175175+ return 88200;176176+ case AK4113_FS_96000HZ:177177+ return 96000;178178+ case AK4113_FS_176400HZ:179179+ return 176400;180180+ case AK4113_FS_192000HZ:181181+ return 192000;182182+ default:183183+ return 0;184184+ }185185+}186186+187187+static int snd_ak4113_in_error_info(struct snd_kcontrol *kcontrol,188188+ struct snd_ctl_elem_info *uinfo)189189+{190190+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;191191+ uinfo->count = 1;192192+ uinfo->value.integer.min = 0;193193+ uinfo->value.integer.max = LONG_MAX;194194+ return 0;195195+}196196+197197+static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol,198198+ struct snd_ctl_elem_value *ucontrol)199199+{200200+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);201201+ long *ptr;202202+203203+ spin_lock_irq(&chip->lock);204204+ ptr = (long *)(((char *)chip) + kcontrol->private_value);205205+ ucontrol->value.integer.value[0] = *ptr;206206+ *ptr = 0;207207+ spin_unlock_irq(&chip->lock);208208+ return 0;209209+}210210+211211+#define snd_ak4113_in_bit_info snd_ctl_boolean_mono_info212212+213213+static int snd_ak4113_in_bit_get(struct snd_kcontrol *kcontrol,214214+ struct snd_ctl_elem_value *ucontrol)215215+{216216+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);217217+ unsigned char reg = kcontrol->private_value & 0xff;218218+ unsigned char bit = (kcontrol->private_value >> 8) & 0xff;219219+ unsigned char inv = (kcontrol->private_value >> 31) & 1;220220+221221+ ucontrol->value.integer.value[0] =222222+ ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;223223+ return 0;224224+}225225+226226+static int snd_ak4113_rx_info(struct snd_kcontrol *kcontrol,227227+ struct snd_ctl_elem_info *uinfo)228228+{229229+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;230230+ uinfo->count = 1;231231+ uinfo->value.integer.min = 0;232232+ uinfo->value.integer.max = 5;233233+ return 0;234234+}235235+236236+static int snd_ak4113_rx_get(struct snd_kcontrol *kcontrol,237237+ struct snd_ctl_elem_value *ucontrol)238238+{239239+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);240240+241241+ ucontrol->value.integer.value[0] =242242+ (AK4113_IPS(chip->regmap[AK4113_REG_IO1]));243243+ return 0;244244+}245245+246246+static int snd_ak4113_rx_put(struct snd_kcontrol *kcontrol,247247+ struct snd_ctl_elem_value *ucontrol)248248+{249249+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);250250+ int change;251251+ u8 old_val;252252+253253+ spin_lock_irq(&chip->lock);254254+ old_val = chip->regmap[AK4113_REG_IO1];255255+ change = ucontrol->value.integer.value[0] != AK4113_IPS(old_val);256256+ if (change)257257+ reg_write(chip, AK4113_REG_IO1,258258+ (old_val & (~AK4113_IPS(0xff))) |259259+ (AK4113_IPS(ucontrol->value.integer.value[0])));260260+ spin_unlock_irq(&chip->lock);261261+ return change;262262+}263263+264264+static int snd_ak4113_rate_info(struct snd_kcontrol *kcontrol,265265+ struct snd_ctl_elem_info *uinfo)266266+{267267+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;268268+ uinfo->count = 1;269269+ uinfo->value.integer.min = 0;270270+ uinfo->value.integer.max = 192000;271271+ return 0;272272+}273273+274274+static int snd_ak4113_rate_get(struct snd_kcontrol *kcontrol,275275+ struct snd_ctl_elem_value *ucontrol)276276+{277277+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);278278+279279+ ucontrol->value.integer.value[0] = external_rate(reg_read(chip,280280+ AK4113_REG_RCS1));281281+ return 0;282282+}283283+284284+static int snd_ak4113_spdif_info(struct snd_kcontrol *kcontrol,285285+ struct snd_ctl_elem_info *uinfo)286286+{287287+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;288288+ uinfo->count = 1;289289+ return 0;290290+}291291+292292+static int snd_ak4113_spdif_get(struct snd_kcontrol *kcontrol,293293+ struct snd_ctl_elem_value *ucontrol)294294+{295295+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);296296+ unsigned i;297297+298298+ for (i = 0; i < AK4113_REG_RXCSB_SIZE; i++)299299+ ucontrol->value.iec958.status[i] = reg_read(chip,300300+ AK4113_REG_RXCSB0 + i);301301+ return 0;302302+}303303+304304+static int snd_ak4113_spdif_mask_info(struct snd_kcontrol *kcontrol,305305+ struct snd_ctl_elem_info *uinfo)306306+{307307+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;308308+ uinfo->count = 1;309309+ return 0;310310+}311311+312312+static int snd_ak4113_spdif_mask_get(struct snd_kcontrol *kcontrol,313313+ struct snd_ctl_elem_value *ucontrol)314314+{315315+ memset(ucontrol->value.iec958.status, 0xff, AK4113_REG_RXCSB_SIZE);316316+ return 0;317317+}318318+319319+static int snd_ak4113_spdif_pinfo(struct snd_kcontrol *kcontrol,320320+ struct snd_ctl_elem_info *uinfo)321321+{322322+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;323323+ uinfo->value.integer.min = 0;324324+ uinfo->value.integer.max = 0xffff;325325+ uinfo->count = 4;326326+ return 0;327327+}328328+329329+static int snd_ak4113_spdif_pget(struct snd_kcontrol *kcontrol,330330+ struct snd_ctl_elem_value *ucontrol)331331+{332332+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);333333+ unsigned short tmp;334334+335335+ ucontrol->value.integer.value[0] = 0xf8f2;336336+ ucontrol->value.integer.value[1] = 0x4e1f;337337+ tmp = reg_read(chip, AK4113_REG_Pc0) |338338+ (reg_read(chip, AK4113_REG_Pc1) << 8);339339+ ucontrol->value.integer.value[2] = tmp;340340+ tmp = reg_read(chip, AK4113_REG_Pd0) |341341+ (reg_read(chip, AK4113_REG_Pd1) << 8);342342+ ucontrol->value.integer.value[3] = tmp;343343+ return 0;344344+}345345+346346+static int snd_ak4113_spdif_qinfo(struct snd_kcontrol *kcontrol,347347+ struct snd_ctl_elem_info *uinfo)348348+{349349+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;350350+ uinfo->count = AK4113_REG_QSUB_SIZE;351351+ return 0;352352+}353353+354354+static int snd_ak4113_spdif_qget(struct snd_kcontrol *kcontrol,355355+ struct snd_ctl_elem_value *ucontrol)356356+{357357+ struct ak4113 *chip = snd_kcontrol_chip(kcontrol);358358+ unsigned i;359359+360360+ for (i = 0; i < AK4113_REG_QSUB_SIZE; i++)361361+ ucontrol->value.bytes.data[i] = reg_read(chip,362362+ AK4113_REG_QSUB_ADDR + i);363363+ return 0;364364+}365365+366366+/* Don't forget to change AK4113_CONTROLS define!!! */367367+static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = {368368+{369369+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,370370+ .name = "IEC958 Parity Errors",371371+ .access = SNDRV_CTL_ELEM_ACCESS_READ |372372+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,373373+ .info = snd_ak4113_in_error_info,374374+ .get = snd_ak4113_in_error_get,375375+ .private_value = offsetof(struct ak4113, parity_errors),376376+},377377+{378378+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,379379+ .name = "IEC958 V-Bit Errors",380380+ .access = SNDRV_CTL_ELEM_ACCESS_READ |381381+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,382382+ .info = snd_ak4113_in_error_info,383383+ .get = snd_ak4113_in_error_get,384384+ .private_value = offsetof(struct ak4113, v_bit_errors),385385+},386386+{387387+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,388388+ .name = "IEC958 C-CRC Errors",389389+ .access = SNDRV_CTL_ELEM_ACCESS_READ |390390+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,391391+ .info = snd_ak4113_in_error_info,392392+ .get = snd_ak4113_in_error_get,393393+ .private_value = offsetof(struct ak4113, ccrc_errors),394394+},395395+{396396+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,397397+ .name = "IEC958 Q-CRC Errors",398398+ .access = SNDRV_CTL_ELEM_ACCESS_READ |399399+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,400400+ .info = snd_ak4113_in_error_info,401401+ .get = snd_ak4113_in_error_get,402402+ .private_value = offsetof(struct ak4113, qcrc_errors),403403+},404404+{405405+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,406406+ .name = "IEC958 External Rate",407407+ .access = SNDRV_CTL_ELEM_ACCESS_READ |408408+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,409409+ .info = snd_ak4113_rate_info,410410+ .get = snd_ak4113_rate_get,411411+},412412+{413413+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,414414+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),415415+ .access = SNDRV_CTL_ELEM_ACCESS_READ,416416+ .info = snd_ak4113_spdif_mask_info,417417+ .get = snd_ak4113_spdif_mask_get,418418+},419419+{420420+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,421421+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),422422+ .access = SNDRV_CTL_ELEM_ACCESS_READ |423423+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,424424+ .info = snd_ak4113_spdif_info,425425+ .get = snd_ak4113_spdif_get,426426+},427427+{428428+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,429429+ .name = "IEC958 Preample Capture Default",430430+ .access = SNDRV_CTL_ELEM_ACCESS_READ |431431+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,432432+ .info = snd_ak4113_spdif_pinfo,433433+ .get = snd_ak4113_spdif_pget,434434+},435435+{436436+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,437437+ .name = "IEC958 Q-subcode Capture Default",438438+ .access = SNDRV_CTL_ELEM_ACCESS_READ |439439+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,440440+ .info = snd_ak4113_spdif_qinfo,441441+ .get = snd_ak4113_spdif_qget,442442+},443443+{444444+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,445445+ .name = "IEC958 Audio",446446+ .access = SNDRV_CTL_ELEM_ACCESS_READ |447447+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,448448+ .info = snd_ak4113_in_bit_info,449449+ .get = snd_ak4113_in_bit_get,450450+ .private_value = (1<<31) | (1<<8) | AK4113_REG_RCS0,451451+},452452+{453453+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,454454+ .name = "IEC958 Non-PCM Bitstream",455455+ .access = SNDRV_CTL_ELEM_ACCESS_READ |456456+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,457457+ .info = snd_ak4113_in_bit_info,458458+ .get = snd_ak4113_in_bit_get,459459+ .private_value = (0<<8) | AK4113_REG_RCS1,460460+},461461+{462462+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,463463+ .name = "IEC958 DTS Bitstream",464464+ .access = SNDRV_CTL_ELEM_ACCESS_READ |465465+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,466466+ .info = snd_ak4113_in_bit_info,467467+ .get = snd_ak4113_in_bit_get,468468+ .private_value = (1<<8) | AK4113_REG_RCS1,469469+},470470+{471471+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,472472+ .name = "AK4113 Input Select",473473+ .access = SNDRV_CTL_ELEM_ACCESS_READ |474474+ SNDRV_CTL_ELEM_ACCESS_WRITE,475475+ .info = snd_ak4113_rx_info,476476+ .get = snd_ak4113_rx_get,477477+ .put = snd_ak4113_rx_put,478478+}479479+};480480+481481+static void snd_ak4113_proc_regs_read(struct snd_info_entry *entry,482482+ struct snd_info_buffer *buffer)483483+{484484+ struct ak4113 *ak4113 = entry->private_data;485485+ int reg, val;486486+ /* all ak4113 registers 0x00 - 0x1c */487487+ for (reg = 0; reg < 0x1d; reg++) {488488+ val = reg_read(ak4113, reg);489489+ snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);490490+ }491491+}492492+493493+static void snd_ak4113_proc_init(struct ak4113 *ak4113)494494+{495495+ struct snd_info_entry *entry;496496+ if (!snd_card_proc_new(ak4113->card, "ak4113", &entry))497497+ snd_info_set_text_ops(entry, ak4113, snd_ak4113_proc_regs_read);498498+}499499+500500+int snd_ak4113_build(struct ak4113 *ak4113,501501+ struct snd_pcm_substream *cap_substream)502502+{503503+ struct snd_kcontrol *kctl;504504+ unsigned int idx;505505+ int err;506506+507507+ if (snd_BUG_ON(!cap_substream))508508+ return -EINVAL;509509+ ak4113->substream = cap_substream;510510+ for (idx = 0; idx < AK4113_CONTROLS; idx++) {511511+ kctl = snd_ctl_new1(&snd_ak4113_iec958_controls[idx], ak4113);512512+ if (kctl == NULL)513513+ return -ENOMEM;514514+ kctl->id.device = cap_substream->pcm->device;515515+ kctl->id.subdevice = cap_substream->number;516516+ err = snd_ctl_add(ak4113->card, kctl);517517+ if (err < 0)518518+ return err;519519+ ak4113->kctls[idx] = kctl;520520+ }521521+ snd_ak4113_proc_init(ak4113);522522+ /* trigger workq */523523+ schedule_delayed_work(&ak4113->work, HZ / 10);524524+ return 0;525525+}526526+EXPORT_SYMBOL_GPL(snd_ak4113_build);527527+528528+int snd_ak4113_external_rate(struct ak4113 *ak4113)529529+{530530+ unsigned char rcs1;531531+532532+ rcs1 = reg_read(ak4113, AK4113_REG_RCS1);533533+ return external_rate(rcs1);534534+}535535+EXPORT_SYMBOL_GPL(snd_ak4113_external_rate);536536+537537+int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags)538538+{539539+ struct snd_pcm_runtime *runtime =540540+ ak4113->substream ? ak4113->substream->runtime : NULL;541541+ unsigned long _flags;542542+ int res = 0;543543+ unsigned char rcs0, rcs1, rcs2;544544+ unsigned char c0, c1;545545+546546+ rcs1 = reg_read(ak4113, AK4113_REG_RCS1);547547+ if (flags & AK4113_CHECK_NO_STAT)548548+ goto __rate;549549+ rcs0 = reg_read(ak4113, AK4113_REG_RCS0);550550+ rcs2 = reg_read(ak4113, AK4113_REG_RCS2);551551+ spin_lock_irqsave(&ak4113->lock, _flags);552552+ if (rcs0 & AK4113_PAR)553553+ ak4113->parity_errors++;554554+ if (rcs0 & AK4113_V)555555+ ak4113->v_bit_errors++;556556+ if (rcs2 & AK4113_CCRC)557557+ ak4113->ccrc_errors++;558558+ if (rcs2 & AK4113_QCRC)559559+ ak4113->qcrc_errors++;560560+ c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |561561+ AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^562562+ (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |563563+ AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK));564564+ c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |565565+ AK4113_DAT | 0xf0)) ^566566+ (rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |567567+ AK4113_DAT | 0xf0));568568+ ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC);569569+ ak4113->rcs1 = rcs1;570570+ ak4113->rcs2 = rcs2;571571+ spin_unlock_irqrestore(&ak4113->lock, _flags);572572+573573+ if (rcs0 & AK4113_PAR)574574+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,575575+ &ak4113->kctls[0]->id);576576+ if (rcs0 & AK4113_V)577577+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,578578+ &ak4113->kctls[1]->id);579579+ if (rcs2 & AK4113_CCRC)580580+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,581581+ &ak4113->kctls[2]->id);582582+ if (rcs2 & AK4113_QCRC)583583+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,584584+ &ak4113->kctls[3]->id);585585+586586+ /* rate change */587587+ if (c1 & 0xf0)588588+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,589589+ &ak4113->kctls[4]->id);590590+591591+ if ((c1 & AK4113_PEM) | (c0 & AK4113_CINT))592592+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,593593+ &ak4113->kctls[6]->id);594594+ if (c0 & AK4113_QINT)595595+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,596596+ &ak4113->kctls[8]->id);597597+598598+ if (c0 & AK4113_AUDION)599599+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,600600+ &ak4113->kctls[9]->id);601601+ if (c1 & AK4113_NPCM)602602+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,603603+ &ak4113->kctls[10]->id);604604+ if (c1 & AK4113_DTSCD)605605+ snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,606606+ &ak4113->kctls[11]->id);607607+608608+ if (ak4113->change_callback && (c0 | c1) != 0)609609+ ak4113->change_callback(ak4113, c0, c1);610610+611611+__rate:612612+ /* compare rate */613613+ res = external_rate(rcs1);614614+ if (!(flags & AK4113_CHECK_NO_RATE) && runtime &&615615+ (runtime->rate != res)) {616616+ snd_pcm_stream_lock_irqsave(ak4113->substream, _flags);617617+ if (snd_pcm_running(ak4113->substream)) {618618+ /*printk(KERN_DEBUG "rate changed (%i <- %i)\n",619619+ * runtime->rate, res); */620620+ snd_pcm_stop(ak4113->substream,621621+ SNDRV_PCM_STATE_DRAINING);622622+ wake_up(&runtime->sleep);623623+ res = 1;624624+ }625625+ snd_pcm_stream_unlock_irqrestore(ak4113->substream, _flags);626626+ }627627+ return res;628628+}629629+EXPORT_SYMBOL_GPL(snd_ak4113_check_rate_and_errors);630630+631631+static void ak4113_stats(struct work_struct *work)632632+{633633+ struct ak4113 *chip = container_of(work, struct ak4113, work.work);634634+635635+ if (!chip->init)636636+ snd_ak4113_check_rate_and_errors(chip, chip->check_flags);637637+638638+ schedule_delayed_work(&chip->work, HZ / 10);639639+}
+104-32
sound/i2c/other/ak4xxx-adda.c
···1919 * along with this program; if not, write to the Free Software2020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA2121 *2222- */ 2222+ */23232424#include <asm/io.h>2525#include <linux/delay.h>···2929#include <sound/control.h>3030#include <sound/tlv.h>3131#include <sound/ak4xxx-adda.h>3232+#include <sound/info.h>32333334MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");3435MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters");···5352static void ak4524_reset(struct snd_akm4xxx *ak, int state)5453{5554 unsigned int chip;5656- unsigned char reg, maxreg;5555+ unsigned char reg;57565858- if (ak->type == SND_AK4528)5959- maxreg = 0x06;6060- else6161- maxreg = 0x08;6257 for (chip = 0; chip < ak->num_dacs/2; chip++) {6358 snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);6459 if (state)6560 continue;6661 /* DAC volumes */6767- for (reg = 0x04; reg < maxreg; reg++)6262+ for (reg = 0x04; reg < ak->total_regs; reg++)6863 snd_akm4xxx_write(ak, chip, reg,6964 snd_akm4xxx_get(ak, chip, reg));7065 }7166}72677368/* reset procedure for AK4355 and AK4358 */7474-static void ak435X_reset(struct snd_akm4xxx *ak, int state,7575- unsigned char total_regs)6969+static void ak435X_reset(struct snd_akm4xxx *ak, int state)7670{7771 unsigned char reg;7872···7579 snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */7680 return;7781 }7878- for (reg = 0x00; reg < total_regs; reg++)8282+ for (reg = 0x00; reg < ak->total_regs; reg++)7983 if (reg != 0x01)8084 snd_akm4xxx_write(ak, 0, reg,8185 snd_akm4xxx_get(ak, 0, reg));···8791{8892 unsigned int chip;8993 unsigned char reg;9090-9194 for (chip = 0; chip < ak->num_dacs/2; chip++) {9295 snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);9396 if (state)9497 continue;9595- for (reg = 0x01; reg < 0x05; reg++)9898+ for (reg = 0x01; reg < ak->total_regs; reg++)9699 snd_akm4xxx_write(ak, chip, reg,97100 snd_akm4xxx_get(ak, chip, reg));98101 }···108113 switch (ak->type) {109114 case SND_AK4524:110115 case SND_AK4528:116116+ case SND_AK4620:111117 ak4524_reset(ak, state);112118 break;113119 case SND_AK4529:114120 /* FIXME: needed for ak4529? */115121 break;116122 case SND_AK4355:117117- ak435X_reset(ak, state, 0x0b);123123+ ak435X_reset(ak, state);118124 break;119125 case SND_AK4358:120120- ak435X_reset(ak, state, 0x10);126126+ ak435X_reset(ak, state);121127 break;122128 case SND_AK4381:123129 ak4381_reset(ak, state);···135139 * Volume conversion table for non-linear volumes136140 * from -63.5dB (mute) to 0dB step 0.5dB137141 *138138- * Used for AK4524 input/ouput attenuation, AK4528, and142142+ * Used for AK4524/AK4620 input/ouput attenuation, AK4528, and139143 * AK5365 input attenuation140144 */141145static const unsigned char vol_cvt_datt[128] = {···255259 0x00, 0x0f, /* 0: power-up, un-reset */256260 0xff, 0xff257261 };262262+ static const unsigned char inits_ak4620[] = {263263+ 0x00, 0x07, /* 0: normal */264264+ 0x01, 0x00, /* 0: reset */265265+ 0x01, 0x02, /* 1: RSTAD */266266+ 0x01, 0x03, /* 1: RSTDA */267267+ 0x01, 0x0f, /* 1: normal */268268+ 0x02, 0x60, /* 2: 24bit I2S */269269+ 0x03, 0x01, /* 3: deemphasis off */270270+ 0x04, 0x00, /* 4: LIN muted */271271+ 0x05, 0x00, /* 5: RIN muted */272272+ 0x06, 0x00, /* 6: LOUT muted */273273+ 0x07, 0x00, /* 7: ROUT muted */274274+ 0xff, 0xff275275+ };258276259259- int chip, num_chips;277277+ int chip;260278 const unsigned char *ptr, *inits;261279 unsigned char reg, data;262280···280270 switch (ak->type) {281271 case SND_AK4524:282272 inits = inits_ak4524;283283- num_chips = ak->num_dacs / 2;273273+ ak->num_chips = ak->num_dacs / 2;274274+ ak->name = "ak4524";275275+ ak->total_regs = 0x08;284276 break;285277 case SND_AK4528:286278 inits = inits_ak4528;287287- num_chips = ak->num_dacs / 2;279279+ ak->num_chips = ak->num_dacs / 2;280280+ ak->name = "ak4528";281281+ ak->total_regs = 0x06;288282 break;289283 case SND_AK4529:290284 inits = inits_ak4529;291291- num_chips = 1;285285+ ak->num_chips = 1;286286+ ak->name = "ak4529";287287+ ak->total_regs = 0x0d;292288 break;293289 case SND_AK4355:294290 inits = inits_ak4355;295295- num_chips = 1;291291+ ak->num_chips = 1;292292+ ak->name = "ak4355";293293+ ak->total_regs = 0x0b;296294 break;297295 case SND_AK4358:298296 inits = inits_ak4358;299299- num_chips = 1;297297+ ak->num_chips = 1;298298+ ak->name = "ak4358";299299+ ak->total_regs = 0x10;300300 break;301301 case SND_AK4381:302302 inits = inits_ak4381;303303- num_chips = ak->num_dacs / 2;303303+ ak->num_chips = ak->num_dacs / 2;304304+ ak->name = "ak4381";305305+ ak->total_regs = 0x05;304306 break;305307 case SND_AK5365:306308 /* FIXME: any init sequence? */309309+ ak->num_chips = 1;310310+ ak->name = "ak5365";311311+ ak->total_regs = 0x08;307312 return;313313+ case SND_AK4620:314314+ inits = inits_ak4620;315315+ ak->num_chips = ak->num_dacs / 2;316316+ ak->name = "ak4620";317317+ ak->total_regs = 0x08;318318+ break;308319 default:309320 snd_BUG();310321 return;311322 }312323313313- for (chip = 0; chip < num_chips; chip++) {324324+ for (chip = 0; chip < ak->num_chips; chip++) {314325 ptr = inits;315326 while (*ptr != 0xff) {316327 reg = *ptr++;317328 data = *ptr++;318329 snd_akm4xxx_write(ak, chip, reg, data);330330+ udelay(10);319331 }320332 }321333}···720688 AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255);721689 knew.tlv.p = db_scale_linear;722690 break;691691+ case SND_AK4620:692692+ /* register 6 & 7 */693693+ knew.private_value =694694+ AK_COMPOSE(idx/2, (idx%2) + 6, 0, 255);695695+ knew.tlv.p = db_scale_linear;696696+ break;723697 default:724698 return -EINVAL;725699 }···742704743705static int build_adc_controls(struct snd_akm4xxx *ak)744706{745745- int idx, err, mixer_ch, num_stereo;707707+ int idx, err, mixer_ch, num_stereo, max_steps;746708 struct snd_kcontrol_new knew;747709748710 mixer_ch = 0;711711+ if (ak->type == SND_AK4528)712712+ return 0; /* no controls */749713 for (idx = 0; idx < ak->num_adcs;) {750714 memset(&knew, 0, sizeof(knew));751715 if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) {···773733 }774734 /* register 4 & 5 */775735 if (ak->type == SND_AK5365)776776- knew.private_value =777777- AK_COMPOSE(idx/2, (idx%2) + 4, 0, 151) |778778- AK_VOL_CVT | AK_IPGA;736736+ max_steps = 152;779737 else780780- knew.private_value =781781- AK_COMPOSE(idx/2, (idx%2) + 4, 0, 163) |782782- AK_VOL_CVT | AK_IPGA;738738+ max_steps = 164;739739+ knew.private_value =740740+ AK_COMPOSE(idx/2, (idx%2) + 4, 0, max_steps) |741741+ AK_VOL_CVT | AK_IPGA;783742 knew.tlv.p = db_scale_vol_datt;784743 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));785744 if (err < 0)···847808 switch (ak->type) {848809 case SND_AK4524:849810 case SND_AK4528:811811+ case SND_AK4620:850812 /* register 3 */851813 knew.private_value = AK_COMPOSE(idx, 3, 0, 0);852814 break;···874834 return 0;875835}876836837837+#ifdef CONFIG_PROC_FS838838+static void proc_regs_read(struct snd_info_entry *entry,839839+ struct snd_info_buffer *buffer)840840+{841841+ struct snd_akm4xxx *ak = (struct snd_akm4xxx *)entry->private_data;842842+ int reg, val, chip;843843+ for (chip = 0; chip < ak->num_chips; chip++) {844844+ for (reg = 0; reg < ak->total_regs; reg++) {845845+ val = snd_akm4xxx_get(ak, chip, reg);846846+ snd_iprintf(buffer, "chip %d: 0x%02x = 0x%02x\n", chip,847847+ reg, val);848848+ }849849+ }850850+}851851+852852+static int proc_init(struct snd_akm4xxx *ak)853853+{854854+ struct snd_info_entry *entry;855855+ int err;856856+ err = snd_card_proc_new(ak->card, ak->name, &entry);857857+ if (err < 0)858858+ return err;859859+ snd_info_set_text_ops(entry, ak, proc_regs_read);860860+ return 0;861861+}862862+#else /* !CONFIG_PROC_FS */863863+static int proc_init(struct snd_akm4xxx *ak) {}864864+#endif865865+877866int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)878867{879868 int err, num_emphs;···914845 err = build_adc_controls(ak);915846 if (err < 0)916847 return err;917917-918848 if (ak->type == SND_AK4355 || ak->type == SND_AK4358)919849 num_emphs = 1;850850+ else if (ak->type == SND_AK4620)851851+ num_emphs = 0;920852 else921853 num_emphs = ak->num_dacs / 2;922854 err = build_deemphasis(ak, num_emphs);923855 if (err < 0)924856 return err;857857+ err = proc_init(ak);858858+ if (err < 0)859859+ return err;925860926861 return 0;927862}928928-929863EXPORT_SYMBOL(snd_akm4xxx_build_controls);930864931865static int __init alsa_akm4xxx_module_init(void)
+12-1
sound/pci/hda/Kconfig
···3838 Say Y here to build a digital beep interface for HD-audio3939 driver. This interface is used to generate digital beeps.40404141+config SND_HDA_INPUT_BEEP_MODE4242+ int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)"4343+ depends on SND_HDA_INPUT_BEEP=y4444+ default "1"4545+ range 0 24646+ help4747+ Set 0 to disable the digital beep interface for HD-audio by default.4848+ Set 1 to always enable the digital beep interface for HD-audio by4949+ default. Set 2 to control the beep device registration to input5050+ layer using a "Beep Switch" in mixer applications.5151+4152config SND_HDA_INPUT_JACK4253 bool "Support jack plugging notification via input layer"4343- depends on INPUT=y || INPUT=SND_HDA_INTEL5454+ depends on INPUT=y || INPUT=SND4455 select SND_JACK4556 help4657 Say Y here to enable the jack plugging notification via
···24242525#include "hda_codec.h"26262727+#define HDA_BEEP_MODE_OFF 02828+#define HDA_BEEP_MODE_ON 12929+#define HDA_BEEP_MODE_SWREG 23030+2731/* beep information */2832struct hda_beep {2933 struct input_dev *dev;3034 struct hda_codec *codec;3535+ unsigned int mode;3136 char phys[32];3237 int tone;3338 hda_nid_t nid;3439 unsigned int enabled:1;4040+ unsigned int request_enable:1;3541 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */4242+ struct work_struct register_work; /* registration work */4343+ struct delayed_work unregister_work; /* unregistration work */3644 struct work_struct beep_work; /* scheduled task for beep event */4545+ struct mutex mutex;3746};38473948#ifdef CONFIG_SND_HDA_INPUT_BEEP4949+int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);4050int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);4151void snd_hda_detach_beep_device(struct hda_codec *codec);4252#else
+514-91
sound/pci/hda/hda_codec.c
···3030#include <sound/tlv.h>3131#include <sound/initval.h>3232#include "hda_local.h"3333+#include "hda_beep.h"3334#include <sound/hda_hwdep.h>34353536/*···9493static inline void hda_keep_power_on(struct hda_codec *codec) {}9594#endif96959696+/**9797+ * snd_hda_get_jack_location - Give a location string of the jack9898+ * @cfg: pin default config value9999+ *100100+ * Parse the pin default config value and returns the string of the101101+ * jack location, e.g. "Rear", "Front", etc.102102+ */97103const char *snd_hda_get_jack_location(u32 cfg)98104{99105 static char *bases[7] = {···128120}129121EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);130122123123+/**124124+ * snd_hda_get_jack_connectivity - Give a connectivity string of the jack125125+ * @cfg: pin default config value126126+ *127127+ * Parse the pin default config value and returns the string of the128128+ * jack connectivity, i.e. external or internal connection.129129+ */131130const char *snd_hda_get_jack_connectivity(u32 cfg)132131{133132 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };···143128}144129EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);145130131131+/**132132+ * snd_hda_get_jack_type - Give a type string of the jack133133+ * @cfg: pin default config value134134+ *135135+ * Parse the pin default config value and returns the string of the136136+ * jack type, i.e. the purpose of the jack, such as Line-Out or CD.137137+ */146138const char *snd_hda_get_jack_type(u32 cfg)147139{148140 static char *jack_types[16] = {···537515 struct hda_codec *codec;538516 list_for_each_entry(codec, &bus->codec_list, list) {539517 snd_hda_hwdep_add_sysfs(codec);518518+ snd_hda_hwdep_add_power_sysfs(codec);540519 }541520 return 0;542521}···843820 return 0;844821}845822823823+/**824824+ * snd_hda_codec_set_pincfg - Override a pin default configuration825825+ * @codec: the HDA codec826826+ * @nid: NID to set the pin config827827+ * @cfg: the pin default config value828828+ *829829+ * Override a pin default configuration value in the cache.830830+ * This value can be read by snd_hda_codec_get_pincfg() in a higher831831+ * priority than the real hardware value.832832+ */846833int snd_hda_codec_set_pincfg(struct hda_codec *codec,847834 hda_nid_t nid, unsigned int cfg)848835{···860827}861828EXPORT_SYMBOL_HDA(snd_hda_codec_set_pincfg);862829863863-/* get the current pin config value of the given pin NID */830830+/**831831+ * snd_hda_codec_get_pincfg - Obtain a pin-default configuration832832+ * @codec: the HDA codec833833+ * @nid: NID to get the pin config834834+ *835835+ * Get the current pin config value of the given pin NID.836836+ * If the pincfg value is cached or overridden via sysfs or driver,837837+ * returns the cached value.838838+ */864839unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)865840{866841 struct hda_pincfg *pin;···985944 mutex_init(&codec->control_mutex);986945 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));987946 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));988988- snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);947947+ snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60);989948 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);990949 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);991950 if (codec->bus->modelname) {···10671026}10681027EXPORT_SYMBOL_HDA(snd_hda_codec_new);1069102810291029+/**10301030+ * snd_hda_codec_configure - (Re-)configure the HD-audio codec10311031+ * @codec: the HDA codec10321032+ *10331033+ * Start parsing of the given codec tree and (re-)initialize the whole10341034+ * patch instance.10351035+ *10361036+ * Returns 0 if successful or a negative error code.10371037+ */10701038int snd_hda_codec_configure(struct hda_codec *codec)10711039{10721040 int err;···11381088}11391089EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);1140109010911091+/**10921092+ * snd_hda_codec_cleanup_stream - clean up the codec for closing10931093+ * @codec: the CODEC to clean up10941094+ * @nid: the NID to clean up10951095+ */11411096void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)11421097{11431098 if (!nid)···12181163 return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key);12191164}1220116512211221-/*12221222- * query AMP capabilities for the given widget and direction11661166+/**11671167+ * query_amp_caps - query AMP capabilities11681168+ * @codec: the HD-auio codec11691169+ * @nid: the NID to query11701170+ * @direction: either #HDA_INPUT or #HDA_OUTPUT11711171+ *11721172+ * Query AMP capabilities for the given widget and direction.11731173+ * Returns the obtained capability bits.11741174+ *11751175+ * When cap bits have been already read, this doesn't read again but11761176+ * returns the cached value.12231177 */12241178u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)12251179{···12511187}12521188EXPORT_SYMBOL_HDA(query_amp_caps);1253118911901190+/**11911191+ * snd_hda_override_amp_caps - Override the AMP capabilities11921192+ * @codec: the CODEC to clean up11931193+ * @nid: the NID to clean up11941194+ * @direction: either #HDA_INPUT or #HDA_OUTPUT11951195+ * @caps: the capability bits to set11961196+ *11971197+ * Override the cached AMP caps bits value by the given one.11981198+ * This function is useful if the driver needs to adjust the AMP ranges,11991199+ * e.g. limit to 0dB, etc.12001200+ *12011201+ * Returns zero if successful or a negative error code.12021202+ */12541203int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,12551204 unsigned int caps)12561205{···12991222 return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);13001223}1301122412251225+/**12261226+ * snd_hda_query_pin_caps - Query PIN capabilities12271227+ * @codec: the HD-auio codec12281228+ * @nid: the NID to query12291229+ *12301230+ * Query PIN capabilities for the given widget.12311231+ * Returns the obtained capability bits.12321232+ *12331233+ * When cap bits have been already read, this doesn't read again but12341234+ * returns the cached value.12351235+ */13021236u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)13031237{13041238 return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),13051239 read_pin_cap);13061240}13071241EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);12421242+12431243+/**12441244+ * snd_hda_pin_sense - execute pin sense measurement12451245+ * @codec: the CODEC to sense12461246+ * @nid: the pin NID to sense12471247+ *12481248+ * Execute necessary pin sense measurement and return its Presence Detect,12491249+ * Impedance, ELD Valid etc. status bits.12501250+ */12511251+u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)12521252+{12531253+ u32 pincap = snd_hda_query_pin_caps(codec, nid);12541254+12551255+ if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */12561256+ snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);12571257+12581258+ return snd_hda_codec_read(codec, nid, 0,12591259+ AC_VERB_GET_PIN_SENSE, 0);12601260+}12611261+EXPORT_SYMBOL_HDA(snd_hda_pin_sense);12621262+12631263+/**12641264+ * snd_hda_jack_detect - query pin Presence Detect status12651265+ * @codec: the CODEC to sense12661266+ * @nid: the pin NID to sense12671267+ *12681268+ * Query and return the pin's Presence Detect status.12691269+ */12701270+int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)12711271+{12721272+ u32 sense = snd_hda_pin_sense(codec, nid);12731273+ return !!(sense & AC_PINSENSE_PRESENCE);12741274+}12751275+EXPORT_SYMBOL_HDA(snd_hda_jack_detect);1308127613091277/*13101278 * read the current volume to info···13911269 info->vol[ch] = val;13921270}1393127113941394-/*13951395- * read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.12721272+/**12731273+ * snd_hda_codec_amp_read - Read AMP value12741274+ * @codec: HD-audio codec12751275+ * @nid: NID to read the AMP value12761276+ * @ch: channel (left=0 or right=1)12771277+ * @direction: #HDA_INPUT or #HDA_OUTPUT12781278+ * @index: the index value (only for input direction)12791279+ *12801280+ * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.13961281 */13971282int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,13981283 int direction, int index)···14121283}14131284EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);1414128514151415-/*14161416- * update the AMP value, mask = bit mask to set, val = the value12861286+/**12871287+ * snd_hda_codec_amp_update - update the AMP value12881288+ * @codec: HD-audio codec12891289+ * @nid: NID to read the AMP value12901290+ * @ch: channel (left=0 or right=1)12911291+ * @direction: #HDA_INPUT or #HDA_OUTPUT12921292+ * @idx: the index value (only for input direction)12931293+ * @mask: bit mask to set12941294+ * @val: the bits value to set12951295+ *12961296+ * Update the AMP value with a bit mask.12971297+ * Returns 0 if the value is unchanged, 1 if changed.14171298 */14181299int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,14191300 int direction, int idx, int mask, int val)···14421303}14431304EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);1444130514451445-/*14461446- * update the AMP stereo with the same mask and value13061306+/**13071307+ * snd_hda_codec_amp_stereo - update the AMP stereo values13081308+ * @codec: HD-audio codec13091309+ * @nid: NID to read the AMP value13101310+ * @direction: #HDA_INPUT or #HDA_OUTPUT13111311+ * @idx: the index value (only for input direction)13121312+ * @mask: bit mask to set13131313+ * @val: the bits value to set13141314+ *13151315+ * Update the AMP values like snd_hda_codec_amp_update(), but for a13161316+ * stereo widget with the same mask and value.14471317 */14481318int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,14491319 int direction, int idx, int mask, int val)···14661318EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);1467131914681320#ifdef SND_HDA_NEEDS_RESUME14691469-/* resume the all amp commands from the cache */13211321+/**13221322+ * snd_hda_codec_resume_amp - Resume all AMP commands from the cache13231323+ * @codec: HD-audio codec13241324+ *13251325+ * Resume the all amp commands from the cache.13261326+ */14701327void snd_hda_codec_resume_amp(struct hda_codec *codec)14711328{14721329 struct hda_amp_info *buffer = codec->amp_cache.buf.list;···14971344EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);14981345#endif /* SND_HDA_NEEDS_RESUME */1499134615001500-/* volume */13471347+/**13481348+ * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer13491349+ *13501350+ * The control element is supposed to have the private_value field13511351+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.13521352+ */15011353int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,15021354 struct snd_ctl_elem_info *uinfo)15031355{···15581400 HDA_AMP_VOLMASK, val);15591401}1560140214031403+/**14041404+ * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume14051405+ *14061406+ * The control element is supposed to have the private_value field14071407+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.14081408+ */15611409int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,15621410 struct snd_ctl_elem_value *ucontrol)15631411{···15831419}15841420EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);1585142114221422+/**14231423+ * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume14241424+ *14251425+ * The control element is supposed to have the private_value field14261426+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.14271427+ */15861428int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,15871429 struct snd_ctl_elem_value *ucontrol)15881430{···16131443}16141444EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);1615144514461446+/**14471447+ * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume14481448+ *14491449+ * The control element is supposed to have the private_value field14501450+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.14511451+ */16161452int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,16171453 unsigned int size, unsigned int __user *_tlv)16181454{···16481472}16491473EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);1650147416511651-/*16521652- * set (static) TLV for virtual master volume; recalculated as max 0dB14751475+/**14761476+ * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control14771477+ * @codec: HD-audio codec14781478+ * @nid: NID of a reference widget14791479+ * @dir: #HDA_INPUT or #HDA_OUTPUT14801480+ * @tlv: TLV data to be stored, at least 4 elements14811481+ *14821482+ * Set (static) TLV data for a virtual master volume using the AMP caps14831483+ * obtained from the reference NID.14841484+ * The volume range is recalculated as if the max volume is 0dB.16531485 */16541486void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,16551487 unsigned int *tlv)···16911507 return snd_ctl_find_id(codec->bus->card, &id);16921508}1693150915101510+/**15111511+ * snd_hda_find_mixer_ctl - Find a mixer control element with the given name15121512+ * @codec: HD-audio codec15131513+ * @name: ctl id name string15141514+ *15151515+ * Get the control element with the given id string and IFACE_MIXER.15161516+ */16941517struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,16951518 const char *name)16961519{···17051514}17061515EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);1707151617081708-/* Add a control element and assign to the codec */17091709-int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl)15171517+/**15181518+ * snd_hda_ctl-add - Add a control element and assign to the codec15191519+ * @codec: HD-audio codec15201520+ * @nid: corresponding NID (optional)15211521+ * @kctl: the control element to assign15221522+ *15231523+ * Add the given control element to an array inside the codec instance.15241524+ * All control elements belonging to a codec are supposed to be added15251525+ * by this function so that a proper clean-up works at the free or15261526+ * reconfiguration time.15271527+ *15281528+ * If non-zero @nid is passed, the NID is assigned to the control element.15291529+ * The assignment is shown in the codec proc file.15301530+ *15311531+ * snd_hda_ctl_add() checks the control subdev id field whether15321532+ * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower15331533+ * bits value is taken as the NID to assign.15341534+ */15351535+int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,15361536+ struct snd_kcontrol *kctl)17101537{17111538 int err;17121712- struct snd_kcontrol **knewp;15391539+ struct hda_nid_item *item;1713154015411541+ if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) {15421542+ if (nid == 0)15431543+ nid = kctl->id.subdevice & 0xffff;15441544+ kctl->id.subdevice = 0;15451545+ }17141546 err = snd_ctl_add(codec->bus->card, kctl);17151547 if (err < 0)17161548 return err;17171717- knewp = snd_array_new(&codec->mixers);17181718- if (!knewp)15491549+ item = snd_array_new(&codec->mixers);15501550+ if (!item)17191551 return -ENOMEM;17201720- *knewp = kctl;15521552+ item->kctl = kctl;15531553+ item->nid = nid;17211554 return 0;17221555}17231556EXPORT_SYMBOL_HDA(snd_hda_ctl_add);1724155717251725-/* Clear all controls assigned to the given codec */15581558+/**15591559+ * snd_hda_ctls_clear - Clear all controls assigned to the given codec15601560+ * @codec: HD-audio codec15611561+ */17261562void snd_hda_ctls_clear(struct hda_codec *codec)17271563{17281564 int i;17291729- struct snd_kcontrol **kctls = codec->mixers.list;15651565+ struct hda_nid_item *items = codec->mixers.list;17301566 for (i = 0; i < codec->mixers.used; i++)17311731- snd_ctl_remove(codec->bus->card, kctls[i]);15671567+ snd_ctl_remove(codec->bus->card, items[i].kctl);17321568 snd_array_free(&codec->mixers);17331569}17341570···17811563 spin_unlock(&card->files_lock);17821564}1783156515661566+/**15671567+ * snd_hda_codec_reset - Clear all objects assigned to the codec15681568+ * @codec: HD-audio codec15691569+ *15701570+ * This frees the all PCM and control elements assigned to the codec, and15711571+ * clears the caches and restores the pin default configurations.15721572+ *15731573+ * When a device is being used, it returns -EBSY. If successfully freed,15741574+ * returns zero.15751575+ */17841576int snd_hda_codec_reset(struct hda_codec *codec)17851577{17861578 struct snd_card *card = codec->bus->card;···18541626 return 0;18551627}1856162818571857-/* create a virtual master control and add slaves */16291629+/**16301630+ * snd_hda_add_vmaster - create a virtual master control and add slaves16311631+ * @codec: HD-audio codec16321632+ * @name: vmaster control name16331633+ * @tlv: TLV data (optional)16341634+ * @slaves: slave control names (optional)16351635+ *16361636+ * Create a virtual master control with the given name. The TLV data16371637+ * must be either NULL or a valid data.16381638+ *16391639+ * @slaves is a NULL-terminated array of strings, each of which is a16401640+ * slave control name. All controls with these names are assigned to16411641+ * the new virtual master control.16421642+ *16431643+ * This function returns zero if successful or a negative error code.16441644+ */18581645int snd_hda_add_vmaster(struct hda_codec *codec, char *name,18591646 unsigned int *tlv, const char **slaves)18601647{···18861643 kctl = snd_ctl_make_virtual_master(name, tlv);18871644 if (!kctl)18881645 return -ENOMEM;18891889- err = snd_hda_ctl_add(codec, kctl);16461646+ err = snd_hda_ctl_add(codec, 0, kctl);18901647 if (err < 0)18911648 return err;18921649···19111668}19121669EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);1913167019141914-/* switch */16711671+/**16721672+ * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch16731673+ *16741674+ * The control element is supposed to have the private_value field16751675+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.16761676+ */19151677int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,19161678 struct snd_ctl_elem_info *uinfo)19171679{···19301682}19311683EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);1932168416851685+/**16861686+ * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch16871687+ *16881688+ * The control element is supposed to have the private_value field16891689+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.16901690+ */19331691int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,19341692 struct snd_ctl_elem_value *ucontrol)19351693{···19561702}19571703EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);1958170417051705+/**17061706+ * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch17071707+ *17081708+ * The control element is supposed to have the private_value field17091709+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.17101710+ */19591711int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,19601712 struct snd_ctl_elem_value *ucontrol)19611713{···19931733}19941734EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);1995173517361736+#ifdef CONFIG_SND_HDA_INPUT_BEEP17371737+/**17381738+ * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch17391739+ *17401740+ * This function calls snd_hda_enable_beep_device(), which behaves differently17411741+ * depending on beep_mode option.17421742+ */17431743+int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,17441744+ struct snd_ctl_elem_value *ucontrol)17451745+{17461746+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);17471747+ long *valp = ucontrol->value.integer.value;17481748+17491749+ snd_hda_enable_beep_device(codec, *valp);17501750+ return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);17511751+}17521752+EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);17531753+#endif /* CONFIG_SND_HDA_INPUT_BEEP */17541754+19961755/*19971756 * bound volume controls19981757 *···20211742#define AMP_VAL_IDX_SHIFT 1920221743#define AMP_VAL_IDX_MASK (0x0f<<19)2023174417451745+/**17461746+ * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control17471747+ *17481748+ * The control element is supposed to have the private_value field17491749+ * set up via HDA_BIND_MUTE*() macros.17501750+ */20241751int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,20251752 struct snd_ctl_elem_value *ucontrol)20261753{···20441759}20451760EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);2046176117621762+/**17631763+ * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control17641764+ *17651765+ * The control element is supposed to have the private_value field17661766+ * set up via HDA_BIND_MUTE*() macros.17671767+ */20471768int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,20481769 struct snd_ctl_elem_value *ucontrol)20491770{···20741783}20751784EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);2076178520772077-/*20782078- * generic bound volume/swtich controls17861786+/**17871787+ * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control17881788+ *17891789+ * The control element is supposed to have the private_value field17901790+ * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.20791791 */20801792int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,20811793 struct snd_ctl_elem_info *uinfo)···20971803}20981804EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);2099180518061806+/**18071807+ * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control18081808+ *18091809+ * The control element is supposed to have the private_value field18101810+ * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.18111811+ */21001812int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,21011813 struct snd_ctl_elem_value *ucontrol)21021814{···21201820}21211821EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);2122182218231823+/**18241824+ * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control18251825+ *18261826+ * The control element is supposed to have the private_value field18271827+ * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.18281828+ */21231829int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,21241830 struct snd_ctl_elem_value *ucontrol)21251831{···21491843}21501844EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);2151184518461846+/**18471847+ * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control18481848+ *18491849+ * The control element is supposed to have the private_value field18501850+ * set up via HDA_BIND_VOL() macro.18511851+ */21521852int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,21531853 unsigned int size, unsigned int __user *tlv)21541854{···24382126 return -ENOMEM;24392127 kctl->id.index = idx;24402128 kctl->private_value = nid;24412441- err = snd_hda_ctl_add(codec, kctl);21292129+ err = snd_hda_ctl_add(codec, nid, kctl);24422130 if (err < 0)24432131 return err;24442132 }···24772165 .put = spdif_share_sw_put,24782166};2479216721682168+/**21692169+ * snd_hda_create_spdif_share_sw - create Default PCM switch21702170+ * @codec: the HDA codec21712171+ * @mout: multi-out instance21722172+ */24802173int snd_hda_create_spdif_share_sw(struct hda_codec *codec,24812174 struct hda_multi_out *mout)24822175{24832176 if (!mout->dig_out_nid)24842177 return 0;24852178 /* ATTENTION: here mout is passed as private_data, instead of codec */24862486- return snd_hda_ctl_add(codec,24872487- snd_ctl_new1(&spdif_share_sw, mout));21792179+ return snd_hda_ctl_add(codec, mout->dig_out_nid,21802180+ snd_ctl_new1(&spdif_share_sw, mout));24882181}24892182EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);24902183···25932276 if (!kctl)25942277 return -ENOMEM;25952278 kctl->private_value = nid;25962596- err = snd_hda_ctl_add(codec, kctl);22792279+ err = snd_hda_ctl_add(codec, nid, kctl);25972280 if (err < 0)25982281 return err;25992282 }···26492332}26502333EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);2651233426522652-/* resume the all commands from the cache */23352335+/**23362336+ * snd_hda_codec_resume_cache - Resume the all commands from the cache23372337+ * @codec: HD-audio codec23382338+ *23392339+ * Execute all verbs recorded in the command caches to resume.23402340+ */26532341void snd_hda_codec_resume_cache(struct hda_codec *codec)26542342{26552343 struct hda_cache_head *buffer = codec->cmd_cache.buf.list;···27742452 codec->afg ? codec->afg : codec->mfg,27752453 AC_PWRST_D3);27762454#ifdef CONFIG_SND_HDA_POWER_SAVE24552455+ snd_hda_update_power_acct(codec);27772456 cancel_delayed_work(&codec->power_work);27782457 codec->power_on = 0;27792458 codec->power_transition = 0;24592459+ codec->power_jiffies = jiffies;27802460#endif27812461}27822462···30802756}3081275730822758/**30833083- * snd_hda_is_supported_format - check whether the given node supports30843084- * the format val27592759+ * snd_hda_is_supported_format - Check the validity of the format27602760+ * @codec: HD-audio codec27612761+ * @nid: NID to check27622762+ * @format: the HD-audio format value to check27632763+ *27642764+ * Check whether the given node supports the format value.30852765 *30862766 * Returns 1 if supported, 0 if not.30872767 */···32052877 return 0;32062878}3207287928802880+/* global */28812881+const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {28822882+ "Audio", "SPDIF", "HDMI", "Modem"28832883+};28842884+32082885/*32092886 * get the empty PCM device number to assign32102887 */32112888static int get_empty_pcm_device(struct hda_bus *bus, int type)32122889{32133213- static const char *dev_name[HDA_PCM_NTYPES] = {32143214- "Audio", "SPDIF", "HDMI", "Modem"28902890+ /* audio device indices; not linear to keep compatibility */28912891+ static int audio_idx[HDA_PCM_NTYPES][5] = {28922892+ [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },28932893+ [HDA_PCM_TYPE_SPDIF] = { 1, -1 },28942894+ [HDA_PCM_TYPE_HDMI] = { 3, 7, 8, 9, -1 },28952895+ [HDA_PCM_TYPE_MODEM] = { 6, -1 },32152896 };32163216- /* starting device index for each PCM type */32173217- static int dev_idx[HDA_PCM_NTYPES] = {32183218- [HDA_PCM_TYPE_AUDIO] = 0,32193219- [HDA_PCM_TYPE_SPDIF] = 1,32203220- [HDA_PCM_TYPE_HDMI] = 3,32213221- [HDA_PCM_TYPE_MODEM] = 632223222- };32233223- /* normal audio device indices; not linear to keep compatibility */32243224- static int audio_idx[4] = { 0, 2, 4, 5 };32253225- int i, dev;28972897+ int i;3226289832273227- switch (type) {32283228- case HDA_PCM_TYPE_AUDIO:32293229- for (i = 0; i < ARRAY_SIZE(audio_idx); i++) {32303230- dev = audio_idx[i];32313231- if (!test_bit(dev, bus->pcm_dev_bits))32323232- goto ok;32333233- }32343234- snd_printk(KERN_WARNING "Too many audio devices\n");32353235- return -EAGAIN;32363236- case HDA_PCM_TYPE_SPDIF:32373237- case HDA_PCM_TYPE_HDMI:32383238- case HDA_PCM_TYPE_MODEM:32393239- dev = dev_idx[type];32403240- if (test_bit(dev, bus->pcm_dev_bits)) {32413241- snd_printk(KERN_WARNING "%s already defined\n",32423242- dev_name[type]);32433243- return -EAGAIN;32443244- }32453245- break;32463246- default:28992899+ if (type >= HDA_PCM_NTYPES) {32472900 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);32482901 return -EINVAL;32492902 }32503250- ok:32513251- set_bit(dev, bus->pcm_dev_bits);32523252- return dev;29032903+29042904+ for (i = 0; audio_idx[type][i] >= 0 ; i++)29052905+ if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))29062906+ return audio_idx[type][i];29072907+29082908+ snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]);29092909+ return -EAGAIN;32532910}3254291132552912/*···34723159 */34733160int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)34743161{34753475- int err;31623162+ int err;3476316334773164 for (; knew->name; knew++) {34783165 struct snd_kcontrol *kctl;34793166 kctl = snd_ctl_new1(knew, codec);34803167 if (!kctl)34813168 return -ENOMEM;34823482- err = snd_hda_ctl_add(codec, kctl);31693169+ err = snd_hda_ctl_add(codec, 0, kctl);34833170 if (err < 0) {34843171 if (!codec->addr)34853172 return err;···34873174 if (!kctl)34883175 return -ENOMEM;34893176 kctl->id.device = codec->addr;34903490- err = snd_hda_ctl_add(codec, kctl);31773177+ err = snd_hda_ctl_add(codec, 0, kctl);34913178 if (err < 0)34923179 return err;34933180 }···35203207{35213208 codec->power_count++;35223209 codec->power_on = 1;32103210+ codec->power_jiffies = jiffies;35233211}3524321232133213+/* update the power on/off account with the current jiffies */32143214+void snd_hda_update_power_acct(struct hda_codec *codec)32153215+{32163216+ unsigned long delta = jiffies - codec->power_jiffies;32173217+ if (codec->power_on)32183218+ codec->power_on_acct += delta;32193219+ else32203220+ codec->power_off_acct += delta;32213221+ codec->power_jiffies += delta;32223222+}32233223+32243224+/**32253225+ * snd_hda_power_up - Power-up the codec32263226+ * @codec: HD-audio codec32273227+ *32283228+ * Increment the power-up counter and power up the hardware really when32293229+ * not turned on yet.32303230+ */ 35253231void snd_hda_power_up(struct hda_codec *codec)35263232{35273233 struct hda_bus *bus = codec->bus;···35493217 if (codec->power_on || codec->power_transition)35503218 return;3551321932203220+ snd_hda_update_power_acct(codec);35523221 codec->power_on = 1;32223222+ codec->power_jiffies = jiffies;35533223 if (bus->ops.pm_notify)35543224 bus->ops.pm_notify(bus);35553225 hda_call_codec_resume(codec);···35633229#define power_save(codec) \35643230 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)3565323135663566-#define power_save(codec) \35673567- ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)35683568-32323232+/**32333233+ * snd_hda_power_down - Power-down the codec32343234+ * @codec: HD-audio codec32353235+ *32363236+ * Decrement the power-up counter and schedules the power-off work if32373237+ * the counter rearches to zero.32383238+ */ 35693239void snd_hda_power_down(struct hda_codec *codec)35703240{35713241 --codec->power_count;···35833245}35843246EXPORT_SYMBOL_HDA(snd_hda_power_down);3585324732483248+/**32493249+ * snd_hda_check_amp_list_power - Check the amp list and update the power32503250+ * @codec: HD-audio codec32513251+ * @check: the object containing an AMP list and the status32523252+ * @nid: NID to check / update32533253+ *32543254+ * Check whether the given NID is in the amp list. If it's in the list,32553255+ * check the current AMP status, and update the the power-status according32563256+ * to the mute status.32573257+ *32583258+ * This function is supposed to be set or called from the check_power_status32593259+ * patch ops.32603260+ */ 35863261int snd_hda_check_amp_list_power(struct hda_codec *codec,35873262 struct hda_loopback_check *check,35883263 hda_nid_t nid)···36373286/*36383287 * Channel mode helper36393288 */32893289+32903290+/**32913291+ * snd_hda_ch_mode_info - Info callback helper for the channel mode enum32923292+ */36403293int snd_hda_ch_mode_info(struct hda_codec *codec,36413294 struct snd_ctl_elem_info *uinfo,36423295 const struct hda_channel_mode *chmode,···36573302}36583303EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);3659330433053305+/**33063306+ * snd_hda_ch_mode_get - Get callback helper for the channel mode enum33073307+ */36603308int snd_hda_ch_mode_get(struct hda_codec *codec,36613309 struct snd_ctl_elem_value *ucontrol,36623310 const struct hda_channel_mode *chmode,···36783320}36793321EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);3680332233233323+/**33243324+ * snd_hda_ch_mode_put - Put callback helper for the channel mode enum33253325+ */36813326int snd_hda_ch_mode_put(struct hda_codec *codec,36823327 struct snd_ctl_elem_value *ucontrol,36833328 const struct hda_channel_mode *chmode,···37053344/*37063345 * input MUX helper37073346 */33473347+33483348+/**33493349+ * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum33503350+ */37083351int snd_hda_input_mux_info(const struct hda_input_mux *imux,37093352 struct snd_ctl_elem_info *uinfo)37103353{···37273362}37283363EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);3729336433653365+/**33663366+ * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum33673367+ */37303368int snd_hda_input_mux_put(struct hda_codec *codec,37313369 const struct hda_input_mux *imux,37323370 struct snd_ctl_elem_value *ucontrol,···37893421 }37903422}3791342337923792-/*37933793- * open the digital out in the exclusive mode34243424+/**34253425+ * snd_hda_bus_reboot_notify - call the reboot notifier of each codec34263426+ * @bus: HD-audio bus34273427+ */34283428+void snd_hda_bus_reboot_notify(struct hda_bus *bus)34293429+{34303430+ struct hda_codec *codec;34313431+34323432+ if (!bus)34333433+ return;34343434+ list_for_each_entry(codec, &bus->codec_list, list) {34353435+#ifdef CONFIG_SND_HDA_POWER_SAVE34363436+ if (!codec->power_on)34373437+ continue;34383438+#endif34393439+ if (codec->patch_ops.reboot_notify)34403440+ codec->patch_ops.reboot_notify(codec);34413441+ }34423442+}34433443+EXPORT_SYMBOL_HDA(snd_hda_bus_reboot_notify);34443444+34453445+/**34463446+ * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode37943447 */37953448int snd_hda_multi_out_dig_open(struct hda_codec *codec,37963449 struct hda_multi_out *mout)···38263437}38273438EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);3828343934403440+/**34413441+ * snd_hda_multi_out_dig_prepare - prepare the digital out stream34423442+ */38293443int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,38303444 struct hda_multi_out *mout,38313445 unsigned int stream_tag,···38423450}38433451EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);3844345234533453+/**34543454+ * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream34553455+ */38453456int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,38463457 struct hda_multi_out *mout)38473458{···38553460}38563461EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup);3857346238583858-/*38593859- * release the digital out34633463+/**34643464+ * snd_hda_multi_out_dig_close - release the digital out stream38603465 */38613466int snd_hda_multi_out_dig_close(struct hda_codec *codec,38623467 struct hda_multi_out *mout)···38683473}38693474EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);3870347538713871-/*38723872- * set up more restrictions for analog out34763476+/**34773477+ * snd_hda_multi_out_analog_open - open analog outputs34783478+ *34793479+ * Open analog outputs and set up the hw-constraints.34803480+ * If the digital outputs can be opened as slave, open the digital34813481+ * outputs, too.38733482 */38743483int snd_hda_multi_out_analog_open(struct hda_codec *codec,38753484 struct hda_multi_out *mout,···39183519}39193520EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);3920352139213921-/*39223922- * set up the i/o for analog out39233923- * when the digital out is available, copy the front out to digital out, too.35223522+/**35233523+ * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.35243524+ *35253525+ * Set up the i/o for analog out.35263526+ * When the digital out is available, copy the front out to digital out, too.39243527 */39253528int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,39263529 struct hda_multi_out *mout,···39793578}39803579EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);3981358039823982-/*39833983- * clean up the setting for analog out35813581+/**35823582+ * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out39843583 */39853584int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,39863585 struct hda_multi_out *mout)···43663965 * generic arrays43673966 */4368396743694369-/* get a new element from the given array43704370- * if it exceeds the pre-allocated array size, re-allocate the array39683968+/**39693969+ * snd_array_new - get a new element from the given array39703970+ * @array: the array object39713971+ * 39723972+ * Get a new element from the given array. If it exceeds the39733973+ * pre-allocated array size, re-allocate the array.39743974+ *39753975+ * Returns NULL if allocation failed.43713976 */43723977void *snd_array_new(struct snd_array *array)43733978{···43973990}43983991EXPORT_SYMBOL_HDA(snd_array_new);4399399244004400-/* free the given array elements */39933993+/**39943994+ * snd_array_free - free the given array elements39953995+ * @array: the array object39963996+ */44013997void snd_array_free(struct snd_array *array)44023998{44033999 kfree(array->list);···44104000}44114001EXPORT_SYMBOL_HDA(snd_array_free);4412400244134413-/*40034003+/**40044004+ * snd_print_pcm_rates - Print the supported PCM rates to the string buffer40054005+ * @pcm: PCM caps bits40064006+ * @buf: the string buffer to write40074007+ * @buflen: the max buffer length40084008+ *44144009 * used by hda_proc.c and hda_eld.c44154010 */44164011void snd_print_pcm_rates(int pcm, char *buf, int buflen)···44344019}44354020EXPORT_SYMBOL_HDA(snd_print_pcm_rates);4436402140224022+/**40234023+ * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer40244024+ * @pcm: PCM caps bits40254025+ * @buf: the string buffer to write40264026+ * @buflen: the max buffer length40274027+ *40284028+ * used by hda_proc.c and hda_eld.c40294029+ */44374030void snd_print_pcm_bits(int pcm, char *buf, int buflen)44384031{44394032 static unsigned int bits[] = { 8, 16, 20, 24, 32 };
+11
sound/pci/hda/hda_codec.h
···286286#define AC_PWRST_D1SUP (1<<1)287287#define AC_PWRST_D2SUP (1<<2)288288#define AC_PWRST_D3SUP (1<<3)289289+#define AC_PWRST_D3COLDSUP (1<<4)290290+#define AC_PWRST_S3D3COLDSUP (1<<29)291291+#define AC_PWRST_CLKSTOP (1<<30)292292+#define AC_PWRST_EPSS (1U<<31)289293290294/* Power state values */291295#define AC_PWRST_SETTING (0xf<<0)···678674#ifdef CONFIG_SND_HDA_POWER_SAVE679675 int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);680676#endif677677+ void (*reboot_notify)(struct hda_codec *codec);681678};682679683680/* record for amp information cache */···776771777772 /* beep device */778773 struct hda_beep *beep;774774+ unsigned int beep_mode;779775780776 /* widget capabilities cache */781777 unsigned int num_nodes;···817811 unsigned int power_transition :1; /* power-state in transition */818812 int power_count; /* current (global) power refcount */819813 struct delayed_work power_work; /* delayed task for powerdown */814814+ unsigned long power_on_acct;815815+ unsigned long power_off_acct;816816+ unsigned long power_jiffies;820817#endif821818822819 /* codec-specific additional proc output */···919910 * Misc920911 */921912void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);913913+void snd_hda_bus_reboot_notify(struct hda_bus *bus);922914923915/*924916 * power management···943933void snd_hda_power_up(struct hda_codec *codec);944934void snd_hda_power_down(struct hda_codec *codec);945935#define snd_hda_codec_needs_resume(codec) codec->power_count936936+void snd_hda_update_power_acct(struct hda_codec *codec);946937#else947938static inline void snd_hda_power_up(struct hda_codec *codec) {}948939static inline void snd_hda_power_down(struct hda_codec *codec) {}
···278278static void oxygen_restore_eeprom(struct oxygen *chip,279279 const struct pci_device_id *id)280280{281281- if (oxygen_read_eeprom(chip, 0) != OXYGEN_EEPROM_ID) {281281+ u16 eeprom_id;282282+283283+ eeprom_id = oxygen_read_eeprom(chip, 0);284284+ if (eeprom_id != OXYGEN_EEPROM_ID &&285285+ (eeprom_id != 0xffff || id->subdevice != 0x8788)) {282286 /*283287 * This function gets called only when a known card model has284288 * been detected, i.e., we know there is a valid subsystem···304300 OXYGEN_MISC_WRITE_PCI_SUBID);305301306302 snd_printk(KERN_INFO "EEPROM ID restored\n");303303+ }304304+}305305+306306+static void pci_bridge_magic(void)307307+{308308+ struct pci_dev *pci = NULL;309309+ u32 tmp;310310+311311+ for (;;) {312312+ /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */313313+ pci = pci_get_device(0x12d8, 0xe110, pci);314314+ if (!pci)315315+ break;316316+ /*317317+ * ... configure its secondary internal arbiter to park to318318+ * the secondary port, instead of to the last master.319319+ */320320+ if (!pci_read_config_dword(pci, 0x40, &tmp)) {321321+ tmp |= 1;322322+ pci_write_config_dword(pci, 0x40, tmp);323323+ }324324+ /* Why? Try asking C-Media. */307325 }308326}309327···607581 snd_card_set_dev(card, &pci->dev);608582 card->private_free = oxygen_card_free;609583584584+ pci_bridge_magic();610585 oxygen_init(chip);611586 chip->model.init(chip);612587
···11+/*22+ * helper functions for HDMI models (Xonar HDAV1.3)33+ *44+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>55+ *66+ *77+ * This driver is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License, version 2.99+ *1010+ * This driver is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this driver; if not, see <http://www.gnu.org/licenses/>.1717+ */1818+1919+#include <linux/pci.h>2020+#include <linux/delay.h>2121+#include <sound/asoundef.h>2222+#include <sound/control.h>2323+#include <sound/core.h>2424+#include <sound/pcm.h>2525+#include <sound/pcm_params.h>2626+#include <sound/tlv.h>2727+#include "xonar.h"2828+2929+static void hdmi_write_command(struct oxygen *chip, u8 command,3030+ unsigned int count, const u8 *params)3131+{3232+ unsigned int i;3333+ u8 checksum;3434+3535+ oxygen_write_uart(chip, 0xfb);3636+ oxygen_write_uart(chip, 0xef);3737+ oxygen_write_uart(chip, command);3838+ oxygen_write_uart(chip, count);3939+ for (i = 0; i < count; ++i)4040+ oxygen_write_uart(chip, params[i]);4141+ checksum = 0xfb + 0xef + command + count;4242+ for (i = 0; i < count; ++i)4343+ checksum += params[i];4444+ oxygen_write_uart(chip, checksum);4545+}4646+4747+static void xonar_hdmi_init_commands(struct oxygen *chip,4848+ struct xonar_hdmi *hdmi)4949+{5050+ u8 param;5151+5252+ oxygen_reset_uart(chip);5353+ param = 0;5454+ hdmi_write_command(chip, 0x61, 1, ¶m);5555+ param = 1;5656+ hdmi_write_command(chip, 0x74, 1, ¶m);5757+ hdmi_write_command(chip, 0x54, 5, hdmi->params);5858+}5959+6060+void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *hdmi)6161+{6262+ hdmi->params[1] = IEC958_AES3_CON_FS_48000;6363+ hdmi->params[4] = 1;6464+ xonar_hdmi_init_commands(chip, hdmi);6565+}6666+6767+void xonar_hdmi_cleanup(struct oxygen *chip)6868+{6969+ u8 param = 0;7070+7171+ hdmi_write_command(chip, 0x74, 1, ¶m);7272+}7373+7474+void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi)7575+{7676+ xonar_hdmi_init_commands(chip, hdmi);7777+}7878+7979+void xonar_hdmi_pcm_hardware_filter(unsigned int channel,8080+ struct snd_pcm_hardware *hardware)8181+{8282+ if (channel == PCM_MULTICH) {8383+ hardware->rates = SNDRV_PCM_RATE_44100 |8484+ SNDRV_PCM_RATE_48000 |8585+ SNDRV_PCM_RATE_96000 |8686+ SNDRV_PCM_RATE_192000;8787+ hardware->rate_min = 44100;8888+ }8989+}9090+9191+void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi,9292+ struct snd_pcm_hw_params *params)9393+{9494+ hdmi->params[0] = 0; /* 1 = non-audio */9595+ switch (params_rate(params)) {9696+ case 44100:9797+ hdmi->params[1] = IEC958_AES3_CON_FS_44100;9898+ break;9999+ case 48000:100100+ hdmi->params[1] = IEC958_AES3_CON_FS_48000;101101+ break;102102+ default: /* 96000 */103103+ hdmi->params[1] = IEC958_AES3_CON_FS_96000;104104+ break;105105+ case 192000:106106+ hdmi->params[1] = IEC958_AES3_CON_FS_192000;107107+ break;108108+ }109109+ hdmi->params[2] = params_channels(params) / 2 - 1;110110+ if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)111111+ hdmi->params[3] = 0;112112+ else113113+ hdmi->params[3] = 0xc0;114114+ hdmi->params[4] = 1; /* ? */115115+ hdmi_write_command(chip, 0x54, 5, hdmi->params);116116+}117117+118118+void xonar_hdmi_uart_input(struct oxygen *chip)119119+{120120+ if (chip->uart_input_count >= 2 &&121121+ chip->uart_input[chip->uart_input_count - 2] == 'O' &&122122+ chip->uart_input[chip->uart_input_count - 1] == 'K') {123123+ printk(KERN_DEBUG "message from HDMI chip received:\n");124124+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,125125+ chip->uart_input, chip->uart_input_count);126126+ chip->uart_input_count = 0;127127+ }128128+}
+132
sound/pci/oxygen/xonar_lib.c
···11+/*22+ * helper functions for Asus Xonar cards33+ *44+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>55+ *66+ *77+ * This driver is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License, version 2.99+ *1010+ * This driver is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this driver; if not, see <http://www.gnu.org/licenses/>.1717+ */1818+1919+#include <linux/delay.h>2020+#include <sound/core.h>2121+#include <sound/control.h>2222+#include <sound/pcm.h>2323+#include <sound/pcm_params.h>2424+#include "xonar.h"2525+2626+2727+#define GPIO_CS53x1_M_MASK 0x000c2828+#define GPIO_CS53x1_M_SINGLE 0x00002929+#define GPIO_CS53x1_M_DOUBLE 0x00043030+#define GPIO_CS53x1_M_QUAD 0x00083131+3232+3333+void xonar_enable_output(struct oxygen *chip)3434+{3535+ struct xonar_generic *data = chip->model_data;3636+3737+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);3838+ msleep(data->anti_pop_delay);3939+ oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);4040+}4141+4242+void xonar_disable_output(struct oxygen *chip)4343+{4444+ struct xonar_generic *data = chip->model_data;4545+4646+ oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);4747+}4848+4949+static void xonar_ext_power_gpio_changed(struct oxygen *chip)5050+{5151+ struct xonar_generic *data = chip->model_data;5252+ u8 has_power;5353+5454+ has_power = !!(oxygen_read8(chip, data->ext_power_reg)5555+ & data->ext_power_bit);5656+ if (has_power != data->has_power) {5757+ data->has_power = has_power;5858+ if (has_power) {5959+ snd_printk(KERN_NOTICE "power restored\n");6060+ } else {6161+ snd_printk(KERN_CRIT6262+ "Hey! Don't unplug the power cable!\n");6363+ /* TODO: stop PCMs */6464+ }6565+ }6666+}6767+6868+void xonar_init_ext_power(struct oxygen *chip)6969+{7070+ struct xonar_generic *data = chip->model_data;7171+7272+ oxygen_set_bits8(chip, data->ext_power_int_reg,7373+ data->ext_power_bit);7474+ chip->interrupt_mask |= OXYGEN_INT_GPIO;7575+ chip->model.gpio_changed = xonar_ext_power_gpio_changed;7676+ data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)7777+ & data->ext_power_bit);7878+}7979+8080+void xonar_init_cs53x1(struct oxygen *chip)8181+{8282+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);8383+ oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,8484+ GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);8585+}8686+8787+void xonar_set_cs53x1_params(struct oxygen *chip,8888+ struct snd_pcm_hw_params *params)8989+{9090+ unsigned int value;9191+9292+ if (params_rate(params) <= 54000)9393+ value = GPIO_CS53x1_M_SINGLE;9494+ else if (params_rate(params) <= 108000)9595+ value = GPIO_CS53x1_M_DOUBLE;9696+ else9797+ value = GPIO_CS53x1_M_QUAD;9898+ oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,9999+ value, GPIO_CS53x1_M_MASK);100100+}101101+102102+int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,103103+ struct snd_ctl_elem_value *value)104104+{105105+ struct oxygen *chip = ctl->private_data;106106+ u16 bit = ctl->private_value;107107+108108+ value->value.integer.value[0] =109109+ !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);110110+ return 0;111111+}112112+113113+int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,114114+ struct snd_ctl_elem_value *value)115115+{116116+ struct oxygen *chip = ctl->private_data;117117+ u16 bit = ctl->private_value;118118+ u16 old_bits, new_bits;119119+ int changed;120120+121121+ spin_lock_irq(&chip->reg_lock);122122+ old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);123123+ if (value->value.integer.value[0])124124+ new_bits = old_bits | bit;125125+ else126126+ new_bits = old_bits & ~bit;127127+ changed = new_bits != old_bits;128128+ if (changed)129129+ oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);130130+ spin_unlock_irq(&chip->reg_lock);131131+ return changed;132132+}