Alsa-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
December 2012
- 78 participants
- 222 discussions
The following changes since commit 9489e9dcae718d5fde988e4a684a0f55b5f94d17:
Linux 3.7-rc7 (2012-11-25 17:59:19 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git tags/asoc-3.8
for you to fetch changes up to 854ea639bb6b0b7ec433e0a59405f4f199ffae4f:
Merge remote-tracking branch 'asoc/topic/wm9090' into asoc-next (2012-12-02 13:35:31 +0900)
----------------------------------------------------------------
ASoC: Updates for v3.8
Very quiet release for ASoC really:
- Standardisation of the logging.
- DT and dmaengine support for Atmel.
- Support for Wolfson ADSP cores.
- New drivers for Freescale/iVeia P1022 and Maxim MAX98090.
----------------------------------------------------------------
Andrey Smirnov (1):
Add a codec driver for SI476X MFD
Ashish Chavan (2):
ASoC: da9055: Add support for DSP mode of AIF
ASoC: da9055: DAPMise Headphone and Lineout enable controls
Bill Pemberton (2):
ASoC: remove use of __devinitconst
ASoC: max98088: remove use of __devexit_p
Bo Shen (11):
ASoC: atmel-ssc: use devm_xxx() managed function
ASoC: atmel-ssc: use module_platform_driver macro
ASoC: sam9g20-wm8731: convert to use snd_soc_register_card()
ASoC: sam9g20: using platform device for audio part
ARM: at91: atmel-ssc: add platform device id table
ARM: at91: atmel-ssc: add device tree support
ASoC: atmel-ssc-dai: register dai and pcm directly
ASoC: atmel-ssc-dai: match new method of dai and pcm register
ASoC: at91sam9g20ek-wm8731: convert to dt support
ASoC: atmel-pcm: split into two file
ASoC: atmel-pcm: dma support based on pcm dmaengine
Charles Keepax (4):
ASoC: wm5102: Correct micbias DAPM supplies
ASoC: arizona: Add support for multiplexer with no associated mixer
ASoC: wm5102: Remove mixer widgets on the ASRC
ASoC: wm5110: Remove mixer widgets on the ASRC
Daniel Mack (10):
ASoC: ak4104: handle more sample rates
ASoC: ak4104: add DT bindings
ASoC: cs4271: add support for AMUTEB=BMUTEC feature
ASoC: enable 192KHz support for McASP
ASoC: McASP: add support for clock dividers
ASoC: McASP: make AHCLK direction configurable
ASoC: McASP: set format parameters in dependence of the DAI format
ASoC: McASP: add support for 24 bit samples
ASoC: McASP: treat SNDRV_PCM_FORMAT_U24_* as 32 bit words
ASoC: ak4104: add reset line property to DT bindings
Dimitris Papastamos (3):
ASoC: bells: Up to 512fs
ASoC: wm5102: Register DSP1 Aux widgets
ASoC: wm0010: Up the completion timeout to 20ms instead of 10ms
Eric Millbrandt (2):
ASoC: fsl/pcm030 add unique dai_link names
ASoC: wm8978: Remove remuxing of GPIO1 pin
Javier Martin (2):
ASoC: tlv320aic32x4: Fix problem with first capture.
ASoC: tlv320aic32x4: Add rstn gpio to platform data.
Kees Cook (1):
ASoC: fsl: remove CONFIG_EXPERIMENTAL
Kuninori Morimoto (13):
ASoC: fsi: fixup channels_min/max
ASoC: fsi: use devm_request_irq()
ASoC: fsi: fsi_set_master_clk() was called from fsi_hw_xxx() only
ASoC: fsi: care fsi_hw_start/stop() return value
ASoC: fsi: add master clock control functions
ASoC: fsi: tidyup FSIA/B settings
ASoC: fsi: tidyup sh_fsi_platform_info pointer
ASoC: fsi: SPDIF format become independent from platform flags
ASoC: fsi: master clock selection become independent from platform flags
ASoC: fsi: stream mode become independent from platform flags
ASoC: fsi: add SND_SOC_DAIFMT_INV_xxx support
ASoC: ak4642: cleanup struct ak4642_priv
ASoC: Add max98090 codec driver
Lars-Peter Clausen (3):
ASoC: jz4740-codec: Add dB information
ASoC: jz4740-codec: Use devm_request_and_ioremap
ASoC: jz4740-codec: Use regmap
Lee Jones (1):
ASoC: Ux500: Initialise PCM from MSP probe rather than as a device
Liam Girdwood (5):
ASoC: dapm: Standardise ASoC DAPM messages
ASoC: cache: Standardise ASoC cache messages
ASoC: Jack: Standardise ASoC Jack messages
ASoC: pcm: Standardise ASoC PCM messages
ASoC: core: Standardise ASoC messages
Lothar Waßmann (6):
ASoC: imx: add MODULE_LICENSE("GPL")
ASoC: imx-sgtl5000: prevent module from being unloaded when in use
ASoC: dmaengine_pcm: set MODULE_LICENSE
ASoC: fsl: fix miscompilation of snd-soc-imx-pcm
ASoC: mxs-saif: export mxs_saif_put_mclk,mxs_saif_get_mclk
ASoC: fsl: fix miscompilation of snd-soc-imx-pcm
Mark Brown (117):
ASoC: wm2200: Convert to devm APIs
ASoC: wm2200: Implement AEC loopback support
ASoC: wm2200: Map DSPs into regmap
ASoC: wm2200: Fully plumb the DSPs into the routing map
ASoC: wm2200: Initial DSP support
ASoC: wm2200: Provide initial coefficient loading
regmap: Rename n_ranges to num_ranges
regmap: When we sanity check during range adds say what errors we find
regmap: Allow ranges to be named
regmap: Factor out debugfs register read
regmap: Provide debugfs read of register ranges
regmap: Factor range lookup out of page selection
regmap: Make return code checks consistent
regmap: Split raw writes that cross window boundaries
ASoC: bells: Add WM0010 support
ASoC: bells: Correct typo in sub speaker DAI name for WM5110
ASoC: bells: Provide additional parameterisation
ASoC: bells: Add WM2200 support
ASoC: wm8750: Convert to direct regmap API usage
ASoC: wm8770: Convert to direct regmap API usage
ASoC: wm8770: Remove unneeded bias level manipulation
ASoC: wm8770: Remove regulator allocation to SPI probe
ASoC: wm8770: Conver to table based DAPM and control init
ASoC: wm8971: Convert to direct regmap API usage
ASoC: wm8994: Allow a delay between jack insertion and microphone detect
ASoC: wm8994: Tune VMID power up sequence
ASoC: wm8994: Tune VMID power down sequence
ASoC: wm8958: Load firmwares simultaneously
Merge tag 'regmap/range' of git://git.kernel.org/.../broonie/regmap into asoc-wm2200
ASoC: wm2200: Add names for ranges
ASoC: wm8994: Lower AIFnCLK divisor when dropping to 32kHz
ASoC: adsp: Add ADSP base support
Merge branch 'topic/adsp' of git://git.kernel.org/.../broonie/sound into asoc-arizona
ASoC: arizona: Define standard hookup for ADSP2
ASoC: wm5102: Hook up DSP1
Merge branch 'topic/adsp' of git://git.kernel.org/.../broonie/sound into asoc-wm2200
ASoC: wm2200: Convert over to wm_adsp for ADSP1 support
Merge tag 'v3.7-rc3' into HEAD
ASoC: ab8500: Staticise non-exported ab85000_codec_dai
Merge tag 'v3.7-rc6' into asoc-arizona
Merge tag 'v3.7-rc6' into asoc-wm2200
ASoC: wm5102: Remove output OSR and PGA volume control
ASoC: wm8994: Lower AIFnCLK divisor when dropping to 32kHz
mfd: wm8994: Store platform data in device
ASoC: wm8994: Use pdata cached in MFD driver
ASoC: arizona: Support higher clock rates
ASoC: wm2000: Get the CODEC pointer from the widget
ASoC: wm5102: Add missing routes for ASRC inputs
ASoC: arizona: Suppress noop FLL updates
ASoC: wm0010: Ignore interrupts in power down mode
ASoC: pcm: Report error code when we fail to init platform
Merge tag 'v3.7-rc7' into asoc-ux500
Merge tag 'v3.7-rc7' into asoc-wm2200
ASoC: arizona: Record FLL setting when disabling
mfd: arizona: Allow the CODEC DAPM context to be accessed elsewhere
Input - arizona-haptics: Add driver haptics module on Arizona CODECs
ASoC: wm5102: Implement haptics support
ASoC: wm5110: Implement haptics support
mfd: arizona: Register haptics devices
ASoC: wm8994: Use the same DCS codes for all WM1811 variants
ASoC: wm_adsp: Enable DVFS for ADSP2
Merge branch 'topic/adsp' of git://git.kernel.org/.../broonie/sound into asoc-arizona
ASoC: wm5102: Enable DVFS support for the DSP
ASoC: wm_adsp: Set the core enable as well as start bit for ADSP2
ASoC: arizona: Add parentheses
ASoC: wm5102: Correct base address for Y region
Merge remote-tracking branch 'asoc/topic/ab8500' into asoc-next
Merge remote-tracking branch 'asoc/topic/adsp' into asoc-next
Merge remote-tracking branch 'asoc/topic/ak4104' into asoc-next
Merge remote-tracking branch 'asoc/topic/ak4535' into asoc-next
Merge remote-tracking branch 'asoc/topic/ak4642' into asoc-next
Merge remote-tracking branch 'asoc/topic/arizona' into asoc-next
Merge remote-tracking branch 'asoc/topic/atmel' into asoc-next
Merge remote-tracking branch 'asoc/topic/cs4271' into asoc-next
Merge remote-tracking branch 'asoc/topic/da7210' into asoc-next
Merge remote-tracking branch 'asoc/topic/da9055' into asoc-next
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
Merge remote-tracking branch 'asoc/topic/dmaengine' into asoc-next
Merge remote-tracking branch 'asoc/topic/fsi' into asoc-next
Merge remote-tracking branch 'asoc/topic/fsl' into asoc-next
Merge remote-tracking branch 'asoc/topic/hotplug' into asoc-next
Merge remote-tracking branch 'asoc/topic/jack' into asoc-next
Merge remote-tracking branch 'asoc/topic/jz4740' into asoc-next
Merge remote-tracking branch 'asoc/topic/kirkwood' into asoc-next
Merge remote-tracking branch 'asoc/topic/lm49453' into asoc-next
Merge remote-tracking branch 'asoc/topic/log' into asoc-next
Merge remote-tracking branch 'asoc/topic/max9768' into asoc-next
Merge remote-tracking branch 'asoc/topic/max98090' into asoc-next
Merge remote-tracking branch 'asoc/topic/omap' into asoc-next
Merge remote-tracking branch 'asoc/topic/rt5631' into asoc-next
Merge remote-tracking branch 'asoc/topic/samsung' into asoc-next
Merge remote-tracking branch 'asoc/topic/si476x' into asoc-next
Merge remote-tracking branch 'asoc/topic/tlv320aic32x4' into asoc-next
Merge remote-tracking branch 'asoc/topic/ux500' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm0010' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm2000' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm2200' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8350' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8400' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8510' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8741' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8750' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8753' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8770' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8804' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8955' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8960' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8962' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8971' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8978' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8985' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8988' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8993' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8994' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8995' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm9081' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm9090' into asoc-next
Matt Porter (2):
ASoC: davinci: replace private sram api with genalloc
ARM: davinci: enable SRAM ping ping buffering on DA850
Nicolas Ferre (1):
ASoC: atmel-ssc: add phybase in device structure
Padmavathi Venna (1):
ASoC: Samsung: Get I2S src_clk from clock alias id.
Peter Ujfalusi (1):
ASoC: omap-abe-twl6040: Use "ti,jack-detection" DT property as boolean
Randy Dunlap (1):
ASoC: fix wm2200.c printk format warnings
Russell King (5):
ASoC: kirkwood-i2s: use devm_* APIs
ASoC: kirkwood-i2s: better handling of play/record control registers
ASoC: kirkwood-dma: remove restriction on sample rates
ASoC: kirkwood-i2s: add support for external clock rates
ASoC: kirkwood-dma: remove channel restrictions
Sachin Kamat (16):
ASoC: rt5631: Fix return value
ASoC: wm8350: Use devm_regulator_bulk_get
ASoC: wm8962: Use devm_regulator_bulk_get
ASoC: wm8400: Use devm_regulator_bulk_get
ASoC: wm8993: Use devm_regulator_bulk_get
ASoC: ak4535: Use devm_regmap_init_i2c()
ASoC: da7210: Use devm_regmap_init_i2c()
ASoC: lm49453: Use devm_regmap_init_i2c()
ASoC: wm2200: Remove empty labels
ASoC: wm9090: Use devm_regmap_init_i2c()
ASoC: wm9081: Use devm_regmap_init_i2c()
ASoC: wm8993: Use devm_regmap_init_i2c()
ASoC: wm8962: Use devm_regmap_init_i2c()
ASoC: max9768: Use devm_regmap_init_i2c()
ASoC: wm8955: Use devm_regmap_init_i2c()
ASoC: wm8960: Use devm_regmap_init_i2c()
Scott Ling (4):
ASoC: wm0010: Remove boot_done variable as no longer required.
ASoC: wm0010: Split out the firmware file parsing from the boot
ASoC: wm0010: Split out the stage2 load from the boot function
ASoC: wm0010: Add checking for .dfw info record version.
Thomas Abraham (4):
ASoC: SAMSUNG: ac97: use clk_prepare_enable and clk_disable_unprepare
ASoC: SAMSUNG: i2s: use clk_prepare_enable and clk_disable_unprepare
ASoC: SAMSUNG: pcm: use clk_prepare_enable and clk_disable_unprepare
ASoC: SAMSUNG: spdif: use clk_prepare_enable and clk_disable_unprepare
Timur Tabi (1):
ASoC: add support for the Freescale / iVeia P1022 RDK reference board
Tony Lindgren (1):
ASoC: OMAP: mcbsp fixes for enabling ARM multiplatform support
Tushar Behera (10):
ASoC: wm8510: remove invalid free of devm_ allocated data
ASoC: wm8753: remove invalid free of devm_ allocated data
ASoC: wm8995: Convert to use devm_kzalloc()
ASoC: wm8741: Convert to use devm_regmap_init_{spi,i2c}()
ASoC: wm8753: Convert to use devm_regmap_init_{spi,i2c}()
ASoC: wm8995: Convert to use devm_regmap_init_{spi,i2c}()
ASoC: wm8804: Convert to use devm_regmap_init_{spi,i2c}()
ASoC: wm8985: Convert to use devm_regmap_init_{spi,i2c}()
ASoC: wm8988: Convert to use devm_regmap_init_{spi,i2c}()
ASoC: ak4104: Convert to use devm_regmap_init_spi()
Ulf Hansson (2):
ASoC: Ux500: Fixup use of clocks
ASoC: Ux500: Control apb clock
Wei Yongjun (1):
ASoC: jack: remove unused variable in snd_soc_jack_report()
.../devicetree/bindings/misc/atmel-ssc.txt | 15 +
Documentation/devicetree/bindings/sound/ak4104.txt | 22 +
.../sound/atmel-at91sam9g20ek-wm8731-audio.txt | 26 +
Documentation/devicetree/bindings/sound/cs4271.txt | 2 +
.../devicetree/bindings/sound/omap-abe-twl6040.txt | 4 +-
arch/arm/boot/dts/at91sam9260.dtsi | 8 +
arch/arm/boot/dts/at91sam9263.dtsi | 16 +
arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 32 +-
arch/arm/boot/dts/at91sam9g45.dtsi | 16 +
arch/arm/boot/dts/at91sam9x5.dtsi | 8 +
arch/arm/mach-at91/at91rm9200.c | 9 +-
arch/arm/mach-at91/at91rm9200_devices.c | 6 +-
arch/arm/mach-at91/at91sam9260.c | 3 +-
arch/arm/mach-at91/at91sam9260_devices.c | 2 +-
arch/arm/mach-at91/at91sam9261.c | 9 +-
arch/arm/mach-at91/at91sam9261_devices.c | 6 +-
arch/arm/mach-at91/at91sam9263.c | 6 +-
arch/arm/mach-at91/at91sam9263_devices.c | 4 +-
arch/arm/mach-at91/at91sam9g45.c | 6 +-
arch/arm/mach-at91/at91sam9g45_devices.c | 4 +-
arch/arm/mach-at91/at91sam9rl.c | 6 +-
arch/arm/mach-at91/at91sam9rl_devices.c | 4 +-
arch/arm/mach-at91/at91sam9x5.c | 1 +
arch/arm/mach-at91/board-sam9g20ek.c | 11 +
arch/arm/mach-davinci/board-da850-evm.c | 24 +-
drivers/base/regmap/internal.h | 2 +
drivers/base/regmap/regmap-debugfs.c | 50 +-
drivers/base/regmap/regmap.c | 154 +++--
drivers/input/misc/Kconfig | 10 +
drivers/input/misc/Makefile | 1 +
drivers/input/misc/arizona-haptics.c | 255 ++++++++
drivers/mfd/arizona-core.c | 2 +
drivers/mfd/wm8994-core.c | 35 +-
drivers/misc/atmel-ssc.c | 135 ++--
include/linux/atmel-ssc.h | 6 +
include/linux/mfd/arizona/core.h | 4 +
include/linux/mfd/arizona/pdata.h | 6 +
include/linux/mfd/wm8994/core.h | 4 +
include/linux/mfd/wm8994/pdata.h | 5 +
include/linux/platform_data/asoc-s3c.h | 6 -
include/linux/platform_data/davinci_asp.h | 3 +
include/linux/regmap.h | 6 +-
include/sound/cs4271.h | 1 +
include/sound/sh_fsi.h | 6 +
include/sound/tlv320aic32x4.h | 1 +
sound/soc/atmel/Kconfig | 13 +-
sound/soc/atmel/Makefile | 4 +
sound/soc/atmel/atmel-pcm-dma.c | 240 +++++++
sound/soc/atmel/atmel-pcm-pdc.c | 401 ++++++++++++
sound/soc/atmel/atmel-pcm.c | 401 +-----------
sound/soc/atmel/atmel-pcm.h | 34 +
sound/soc/atmel/atmel_ssc_dai.c | 168 ++---
sound/soc/atmel/atmel_ssc_dai.h | 3 +-
sound/soc/atmel/sam9g20_wm8731.c | 116 +++-
sound/soc/codecs/Kconfig | 16 +
sound/soc/codecs/Makefile | 6 +
sound/soc/codecs/ab8500-codec.c | 2 +-
sound/soc/codecs/ak4104.c | 65 +-
sound/soc/codecs/ak4535.c | 7 +-
sound/soc/codecs/ak4642.c | 23 +-
sound/soc/codecs/arizona.c | 21 +
sound/soc/codecs/arizona.h | 65 +-
sound/soc/codecs/cs4271.c | 21 +-
sound/soc/codecs/da7210.c | 13 +-
sound/soc/codecs/da9055.c | 43 +-
sound/soc/codecs/jz4740.c | 142 ++---
sound/soc/codecs/lm49453.c | 10 +-
sound/soc/codecs/max9768.c | 7 +-
sound/soc/codecs/max98088.c | 14 +-
sound/soc/codecs/max98090.c | 577 +++++++++++++++++
sound/soc/codecs/rt5631.c | 2 +-
sound/soc/codecs/si476x.c | 255 ++++++++
sound/soc/codecs/tlv320aic32x4.c | 24 +
sound/soc/codecs/tlv320aic32x4.h | 3 +
sound/soc/codecs/wm0010.c | 419 +++++++-----
sound/soc/codecs/wm2000.c | 2 +-
sound/soc/codecs/wm2200.c | 269 ++++++--
sound/soc/codecs/wm5100.c | 2 +-
sound/soc/codecs/wm5102.c | 120 ++--
sound/soc/codecs/wm5110.c | 49 +-
sound/soc/codecs/wm8350.c | 4 +-
sound/soc/codecs/wm8400.c | 14 +-
sound/soc/codecs/wm8510.c | 3 -
sound/soc/codecs/wm8741.c | 4 +-
sound/soc/codecs/wm8750.c | 86 ++-
sound/soc/codecs/wm8753.c | 33 +-
sound/soc/codecs/wm8770.c | 217 ++++---
sound/soc/codecs/wm8804.c | 17 +-
sound/soc/codecs/wm8955.c | 11 +-
sound/soc/codecs/wm8958-dsp2.c | 79 +--
sound/soc/codecs/wm8960.c | 2 +-
sound/soc/codecs/wm8962.c | 24 +-
sound/soc/codecs/wm8971.c | 80 ++-
sound/soc/codecs/wm8978.c | 3 -
sound/soc/codecs/wm8985.c | 30 +-
sound/soc/codecs/wm8988.c | 14 +-
sound/soc/codecs/wm8993.c | 14 +-
sound/soc/codecs/wm8994.c | 184 +++---
sound/soc/codecs/wm8994.h | 1 -
sound/soc/codecs/wm8995.c | 40 +-
sound/soc/codecs/wm9081.c | 22 +-
sound/soc/codecs/wm9090.c | 20 +-
sound/soc/codecs/wm_adsp.c | 666 ++++++++++++++++++++
sound/soc/codecs/wm_adsp.h | 59 ++
sound/soc/codecs/wmfw.h | 128 ++++
sound/soc/davinci/davinci-evm.c | 5 +
sound/soc/davinci/davinci-mcasp.c | 93 ++-
sound/soc/davinci/davinci-mcasp.h | 2 +-
sound/soc/davinci/davinci-pcm.c | 53 +-
sound/soc/davinci/davinci-pcm.h | 2 +
sound/soc/fsl/Kconfig | 20 +-
sound/soc/fsl/Makefile | 14 +-
sound/soc/fsl/imx-pcm.c | 4 +
sound/soc/fsl/imx-sgtl5000.c | 1 +
sound/soc/fsl/p1022_rdk.c | 392 ++++++++++++
sound/soc/fsl/pcm030-audio-fabric.c | 4 +-
sound/soc/kirkwood/kirkwood-dma.c | 16 +-
sound/soc/kirkwood/kirkwood-i2s.c | 235 ++++---
sound/soc/kirkwood/kirkwood.h | 11 +-
sound/soc/mxs/mxs-saif.c | 2 +
sound/soc/omap/mcbsp.c | 4 +-
sound/soc/omap/mcbsp.h | 6 +
sound/soc/omap/omap-abe-twl6040.c | 4 +-
sound/soc/omap/omap-mcbsp.c | 5 +-
sound/soc/samsung/ac97.c | 6 +-
sound/soc/samsung/bells.c | 222 +++++--
sound/soc/samsung/i2s.c | 20 +-
sound/soc/samsung/pcm.c | 12 +-
sound/soc/samsung/spdif.c | 12 +-
sound/soc/sh/fsi.c | 550 ++++++++++++++--
sound/soc/soc-cache.c | 10 +-
sound/soc/soc-core.c | 243 +++----
sound/soc/soc-dapm.c | 134 ++--
sound/soc/soc-dmaengine-pcm.c | 2 +
sound/soc/soc-jack.c | 16 +-
sound/soc/soc-pcm.c | 195 +++---
sound/soc/tegra/tegra20_das.c | 2 +-
sound/soc/tegra/tegra20_i2s.c | 4 +-
sound/soc/tegra/tegra20_spdif.c | 2 +-
sound/soc/tegra/tegra30_ahub.c | 6 +-
sound/soc/tegra/tegra30_i2s.c | 4 +-
sound/soc/tegra/tegra_alc5632.c | 2 +-
sound/soc/tegra/tegra_wm8753.c | 2 +-
sound/soc/tegra/tegra_wm8903.c | 2 +-
sound/soc/tegra/trimslice.c | 2 +-
sound/soc/ux500/mop500.c | 4 +-
sound/soc/ux500/ux500_msp_dai.c | 55 +-
sound/soc/ux500/ux500_msp_dai.h | 1 +
sound/soc/ux500/ux500_pcm.c | 19 +-
sound/soc/ux500/ux500_pcm.h | 3 +
150 files changed, 6428 insertions(+), 2229 deletions(-)
create mode 100644 Documentation/devicetree/bindings/misc/atmel-ssc.txt
create mode 100644 Documentation/devicetree/bindings/sound/ak4104.txt
create mode 100644 Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
create mode 100644 drivers/input/misc/arizona-haptics.c
create mode 100644 sound/soc/atmel/atmel-pcm-dma.c
create mode 100644 sound/soc/atmel/atmel-pcm-pdc.c
create mode 100644 sound/soc/codecs/max98090.c
create mode 100644 sound/soc/codecs/si476x.c
create mode 100644 sound/soc/codecs/wm_adsp.c
create mode 100644 sound/soc/codecs/wm_adsp.h
create mode 100644 sound/soc/codecs/wmfw.h
create mode 100644 sound/soc/fsl/p1022_rdk.c
2
1
[alsa-devel] [PATCH] ASoC: zoom2: Remove HS mux GPIO handling to avoid kernel crash due to BUG_ON()
by Peter Ujfalusi 03 Dec '12
by Peter Ujfalusi 03 Dec '12
03 Dec '12
The machine driver try to use GPIO15 of twl4030 for HS MUX which supposed to
select between TWL's HSOL/R and tlv320aic3254's HPL/R.
The TWL's GPIO allocated dynamically so the (OMAP_MAX_GPIO_LINES + 15) is no
longer valid GPIO number causing a kernel crash due to BUG_ON()
Also the current machine driver supports only TWL audio currently: there is
no need to control the GPIO.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
---
Hi Liam, Mark,
I just got one zoom2 board and this patch is needed to get the board booting
when audio is enabled.
For 3.9 I will convert the machine driver to platform device/driver, but to get
3.8 kernel booting this patch is needed.
Regards,
Peter
sound/soc/omap/zoom2.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 1ff6bb9..771bff2 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -37,8 +37,6 @@
#include "omap-mcbsp.h"
#include "omap-pcm.h"
-#define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15)
-
static int zoom2_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -187,9 +185,6 @@ static int __init zoom2_soc_init(void)
if (ret)
goto err1;
- BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
- gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
-
return 0;
err1:
@@ -202,8 +197,6 @@ module_init(zoom2_soc_init);
static void __exit zoom2_soc_exit(void)
{
- gpio_free(ZOOM2_HEADSET_MUX_GPIO);
-
platform_device_unregister(zoom2_snd_device);
}
module_exit(zoom2_soc_exit);
--
1.8.0
2
1
[alsa-devel] [PATCH 1/1] ASoC: da7210: Remove unnecessary regmap_exit call
by Sachin Kamat 03 Dec '12
by Sachin Kamat 03 Dec '12
03 Dec '12
Use of devm_regmap_init_spi does not require an explicit
regmap_exit call.
Signed-off-by: Sachin Kamat <sachin.kamat(a)linaro.org>
---
sound/soc/codecs/da7210.c | 11 +----------
1 files changed, 1 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index ab1ee5b..843c1eb 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -1337,24 +1337,15 @@ static int __devinit da7210_spi_probe(struct spi_device *spi)
if (ret != 0)
dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
- ret = snd_soc_register_codec(&spi->dev,
+ ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_da7210, &da7210_dai, 1);
- if (ret < 0)
- goto err_regmap;
-
- return ret;
-
-err_regmap:
- regmap_exit(da7210->regmap);
return ret;
}
static int __devexit da7210_spi_remove(struct spi_device *spi)
{
- struct da7210_priv *da7210 = spi_get_drvdata(spi);
snd_soc_unregister_codec(&spi->dev);
- regmap_exit(da7210->regmap);
return 0;
}
--
1.7.4.1
2
1
Re: [alsa-devel] [PATCH 2/2] ASoC: Samsung: Do not register samsung audio dma device as pdev
by Mark Brown 02 Dec '12
by Mark Brown 02 Dec '12
02 Dec '12
On Sat, Dec 01, 2012 at 03:37:27PM +0530, Padmavathi Venna wrote:
> sound/soc/samsung/dma.c | 24 ++++++------------------
> sound/soc/samsung/dma.h | 3 +++
> sound/soc/samsung/i2s.c | 3 +++
> sound/soc/samsung/smdk_wm8994.c | 7 +++++--
> 4 files changed, 17 insertions(+), 20 deletions(-)
This is fine in principle but it's going to break every Samsung based
platform except the SMDK with WM8994 as only machine driver updated to
reflect the changed DAI name is that one, the others need updating too.
This includes pretty much all the platforms I actively work on...
1
0
This patch is split original atmel-pcm.c into new atmel-pcm.c and
atmel-pcm-pdc.c two files. The new atmel-pcm.c is the share routine
while will be used for pdc or dma transfer.
Using SND_ATMEL_SOC_PDC to select using PDC for audio transfer
Signed-off-by: Bo Shen <voice.shen(a)atmel.com>
---
sound/soc/atmel/Kconfig | 5 +
sound/soc/atmel/Makefile | 2 +
sound/soc/atmel/atmel-pcm-pdc.c | 401 +++++++++++++++++++++++++++++++++++++++
sound/soc/atmel/atmel-pcm.c | 390 ++-----------------------------------
sound/soc/atmel/atmel-pcm.h | 21 +-
sound/soc/atmel/atmel_ssc_dai.c | 4 +-
6 files changed, 441 insertions(+), 382 deletions(-)
create mode 100644 sound/soc/atmel/atmel-pcm-pdc.c
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 397ec75..6051993 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -6,6 +6,10 @@ config SND_ATMEL_SOC
the ATMEL SSC interface. You will also need
to select the audio interfaces to support below.
+config SND_ATMEL_SOC_PDC
+ tristate
+ depends on SND_ATMEL_SOC
+
config SND_ATMEL_SOC_SSC
tristate
depends on SND_ATMEL_SOC
@@ -17,6 +21,7 @@ config SND_ATMEL_SOC_SSC
config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS
+ select SND_ATMEL_SOC_PDC
select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731
help
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index a5c0bf1..2e37864 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -1,8 +1,10 @@
# AT91 Platform Support
snd-soc-atmel-pcm-objs := atmel-pcm.o
+snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
+obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
# AT91 Machine Support
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
new file mode 100644
index 0000000..1df64ba
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -0,0 +1,401 @@
+/*
+ * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ *
+ * Authors: Sedji Gaouaou <sedji.gaouaou(a)atmel.com>
+ *
+ * Based on at91-pcm. by:
+ * Frank Mandarino <fmandarino(a)endrelia.com>
+ * Copyright 2006 Endrelia Technologies Inc.
+ *
+ * Based on pxa2xx-pcm.c by:
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 30, 2004
+ * Copyright: (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/atmel_pdc.h>
+#include <linux/atmel-ssc.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "atmel-pcm.h"
+
+
+/*--------------------------------------------------------------------------*\
+ * Hardware definition
+\*--------------------------------------------------------------------------*/
+/* TODO: These values were taken from the AT91 platform driver, check
+ * them against real values for AT32
+ */
+static const struct snd_pcm_hardware atmel_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .period_bytes_min = 32,
+ .period_bytes_max = 8192,
+ .periods_min = 2,
+ .periods_max = 1024,
+ .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * Data types
+\*--------------------------------------------------------------------------*/
+struct atmel_runtime_data {
+ struct atmel_pcm_dma_params *params;
+ dma_addr_t dma_buffer; /* physical address of dma buffer */
+ dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
+ size_t period_size;
+
+ dma_addr_t period_ptr; /* physical address of next period */
+
+ /* PDC register save */
+ u32 pdc_xpr_save;
+ u32 pdc_xcr_save;
+ u32 pdc_xnpr_save;
+ u32 pdc_xncr_save;
+};
+
+/*--------------------------------------------------------------------------*\
+ * ISR
+\*--------------------------------------------------------------------------*/
+static void atmel_pcm_dma_irq(u32 ssc_sr,
+ struct snd_pcm_substream *substream)
+{
+ struct atmel_runtime_data *prtd = substream->runtime->private_data;
+ struct atmel_pcm_dma_params *params = prtd->params;
+ static int count;
+
+ count++;
+
+ if (ssc_sr & params->mask->ssc_endbuf) {
+ pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK
+ ? "underrun" : "overrun",
+ params->name, ssc_sr, count);
+
+ /* re-start the PDC */
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+ params->mask->pdc_disable);
+ prtd->period_ptr += prtd->period_size;
+ if (prtd->period_ptr >= prtd->dma_buffer_end)
+ prtd->period_ptr = prtd->dma_buffer;
+
+ ssc_writex(params->ssc->regs, params->pdc->xpr,
+ prtd->period_ptr);
+ ssc_writex(params->ssc->regs, params->pdc->xcr,
+ prtd->period_size / params->pdc_xfer_size);
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+ params->mask->pdc_enable);
+ }
+
+ if (ssc_sr & params->mask->ssc_endx) {
+ /* Load the PDC next pointer and counter registers */
+ prtd->period_ptr += prtd->period_size;
+ if (prtd->period_ptr >= prtd->dma_buffer_end)
+ prtd->period_ptr = prtd->dma_buffer;
+
+ ssc_writex(params->ssc->regs, params->pdc->xnpr,
+ prtd->period_ptr);
+ ssc_writex(params->ssc->regs, params->pdc->xncr,
+ prtd->period_size / params->pdc_xfer_size);
+ }
+
+ snd_pcm_period_elapsed(substream);
+}
+
+
+/*--------------------------------------------------------------------------*\
+ * PCM operations
+\*--------------------------------------------------------------------------*/
+static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct atmel_runtime_data *prtd = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+ /* this may get called several times by oss emulation
+ * with different params */
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ runtime->dma_bytes = params_buffer_bytes(params);
+
+ prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
+
+ prtd->dma_buffer = runtime->dma_addr;
+ prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
+ prtd->period_size = params_period_bytes(params);
+
+ pr_debug("atmel-pcm: "
+ "hw_params: DMA for %s initialized "
+ "(dma_bytes=%u, period_size=%u)\n",
+ prtd->params->name,
+ runtime->dma_bytes,
+ prtd->period_size);
+ return 0;
+}
+
+static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ struct atmel_runtime_data *prtd = substream->runtime->private_data;
+ struct atmel_pcm_dma_params *params = prtd->params;
+
+ if (params != NULL) {
+ ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
+ params->mask->pdc_disable);
+ prtd->params->dma_intr_handler = NULL;
+ }
+
+ return 0;
+}
+
+static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct atmel_runtime_data *prtd = substream->runtime->private_data;
+ struct atmel_pcm_dma_params *params = prtd->params;
+
+ ssc_writex(params->ssc->regs, SSC_IDR,
+ params->mask->ssc_endx | params->mask->ssc_endbuf);
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+ params->mask->pdc_disable);
+ return 0;
+}
+
+static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
+ int cmd)
+{
+ struct snd_pcm_runtime *rtd = substream->runtime;
+ struct atmel_runtime_data *prtd = rtd->private_data;
+ struct atmel_pcm_dma_params *params = prtd->params;
+ int ret = 0;
+
+ pr_debug("atmel-pcm:buffer_size = %ld,"
+ "dma_area = %p, dma_bytes = %u\n",
+ rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ prtd->period_ptr = prtd->dma_buffer;
+
+ ssc_writex(params->ssc->regs, params->pdc->xpr,
+ prtd->period_ptr);
+ ssc_writex(params->ssc->regs, params->pdc->xcr,
+ prtd->period_size / params->pdc_xfer_size);
+
+ prtd->period_ptr += prtd->period_size;
+ ssc_writex(params->ssc->regs, params->pdc->xnpr,
+ prtd->period_ptr);
+ ssc_writex(params->ssc->regs, params->pdc->xncr,
+ prtd->period_size / params->pdc_xfer_size);
+
+ pr_debug("atmel-pcm: trigger: "
+ "period_ptr=%lx, xpr=%u, "
+ "xcr=%u, xnpr=%u, xncr=%u\n",
+ (unsigned long)prtd->period_ptr,
+ ssc_readx(params->ssc->regs, params->pdc->xpr),
+ ssc_readx(params->ssc->regs, params->pdc->xcr),
+ ssc_readx(params->ssc->regs, params->pdc->xnpr),
+ ssc_readx(params->ssc->regs, params->pdc->xncr));
+
+ ssc_writex(params->ssc->regs, SSC_IER,
+ params->mask->ssc_endx | params->mask->ssc_endbuf);
+ ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
+ params->mask->pdc_enable);
+
+ pr_debug("sr=%u imr=%u\n",
+ ssc_readx(params->ssc->regs, SSC_SR),
+ ssc_readx(params->ssc->regs, SSC_IER));
+ break; /* SNDRV_PCM_TRIGGER_START */
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+ params->mask->pdc_disable);
+ break;
+
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+ params->mask->pdc_enable);
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static snd_pcm_uframes_t atmel_pcm_pointer(
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct atmel_runtime_data *prtd = runtime->private_data;
+ struct atmel_pcm_dma_params *params = prtd->params;
+ dma_addr_t ptr;
+ snd_pcm_uframes_t x;
+
+ ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
+ x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
+
+ if (x == runtime->buffer_size)
+ x = 0;
+
+ return x;
+}
+
+static int atmel_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct atmel_runtime_data *prtd;
+ int ret = 0;
+
+ snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
+
+ /* ensure that buffer size is a multiple of period size */
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ goto out;
+
+ prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
+ if (prtd == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ runtime->private_data = prtd;
+
+ out:
+ return ret;
+}
+
+static int atmel_pcm_close(struct snd_pcm_substream *substream)
+{
+ struct atmel_runtime_data *prtd = substream->runtime->private_data;
+
+ kfree(prtd);
+ return 0;
+}
+
+static struct snd_pcm_ops atmel_pcm_ops = {
+ .open = atmel_pcm_open,
+ .close = atmel_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = atmel_pcm_hw_params,
+ .hw_free = atmel_pcm_hw_free,
+ .prepare = atmel_pcm_prepare,
+ .trigger = atmel_pcm_trigger,
+ .pointer = atmel_pcm_pointer,
+ .mmap = atmel_pcm_mmap,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * ASoC platform driver
+\*--------------------------------------------------------------------------*/
+#ifdef CONFIG_PM
+static int atmel_pcm_suspend(struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime *runtime = dai->runtime;
+ struct atmel_runtime_data *prtd;
+ struct atmel_pcm_dma_params *params;
+
+ if (!runtime)
+ return 0;
+
+ prtd = runtime->private_data;
+ params = prtd->params;
+
+ /* disable the PDC and save the PDC registers */
+
+ ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+
+ prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
+ prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
+ prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
+ prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
+
+ return 0;
+}
+
+static int atmel_pcm_resume(struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime *runtime = dai->runtime;
+ struct atmel_runtime_data *prtd;
+ struct atmel_pcm_dma_params *params;
+
+ if (!runtime)
+ return 0;
+
+ prtd = runtime->private_data;
+ params = prtd->params;
+
+ /* restore the PDC registers and enable the PDC */
+ ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
+ ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
+ ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
+ ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
+
+ ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+ return 0;
+}
+#else
+#define atmel_pcm_suspend NULL
+#define atmel_pcm_resume NULL
+#endif
+
+static struct snd_soc_platform_driver atmel_soc_platform = {
+ .ops = &atmel_pcm_ops,
+ .pcm_new = atmel_pcm_new,
+ .pcm_free = atmel_pcm_free,
+ .suspend = atmel_pcm_suspend,
+ .resume = atmel_pcm_resume,
+};
+
+int atmel_pcm_pdc_platform_register(struct device *dev)
+{
+ return snd_soc_register_platform(dev, &atmel_soc_platform);
+}
+EXPORT_SYMBOL(atmel_pcm_pdc_platform_register);
+
+void atmel_pcm_pdc_platform_unregister(struct device *dev)
+{
+ snd_soc_unregister_platform(dev);
+}
+EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister);
+
+MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou(a)atmel.com>");
+MODULE_DESCRIPTION("Atmel PCM module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 40e17d1..e99f181 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -32,80 +32,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <linux/atmel_pdc.h>
-#include <linux/atmel-ssc.h>
-
-#include <sound/core.h>
#include <sound/pcm.h>
-#include <sound/pcm_params.h>
#include <sound/soc.h>
-
#include "atmel-pcm.h"
-
-/*--------------------------------------------------------------------------*\
- * Hardware definition
-\*--------------------------------------------------------------------------*/
-/* TODO: These values were taken from the AT91 platform driver, check
- * them against real values for AT32
- */
-static const struct snd_pcm_hardware atmel_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .period_bytes_min = 32,
- .period_bytes_max = 8192,
- .periods_min = 2,
- .periods_max = 1024,
- .buffer_bytes_max = 32 * 1024,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Data types
-\*--------------------------------------------------------------------------*/
-struct atmel_runtime_data {
- struct atmel_pcm_dma_params *params;
- dma_addr_t dma_buffer; /* physical address of dma buffer */
- dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
- size_t period_size;
-
- dma_addr_t period_ptr; /* physical address of next period */
-
- /* PDC register save */
- u32 pdc_xpr_save;
- u32 pdc_xcr_save;
- u32 pdc_xnpr_save;
- u32 pdc_xncr_save;
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Helper functions
-\*--------------------------------------------------------------------------*/
static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = atmel_pcm_hardware.buffer_bytes_max;
+ size_t size = ATMEL_SSC_DMABUF_SIZE;
buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
buf->private_data = NULL;
buf->area = dma_alloc_coherent(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- pr_debug("atmel-pcm:"
- "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
- (void *) buf->area,
- (void *) buf->addr,
- size);
+ &buf->addr, GFP_KERNEL);
+ pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n",
+ (void *)buf->area, (void *)buf->addr, size);
if (!buf->area)
return -ENOMEM;
@@ -113,258 +58,19 @@ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
buf->bytes = size;
return 0;
}
-/*--------------------------------------------------------------------------*\
- * ISR
-\*--------------------------------------------------------------------------*/
-static void atmel_pcm_dma_irq(u32 ssc_sr,
- struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
- static int count;
-
- count++;
-
- if (ssc_sr & params->mask->ssc_endbuf) {
- pr_warning("atmel-pcm: buffer %s on %s"
- " (SSC_SR=%#x, count=%d)\n",
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK
- ? "underrun" : "overrun",
- params->name, ssc_sr, count);
-
- /* re-start the PDC */
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_disable);
- prtd->period_ptr += prtd->period_size;
- if (prtd->period_ptr >= prtd->dma_buffer_end)
- prtd->period_ptr = prtd->dma_buffer;
-
- ssc_writex(params->ssc->regs, params->pdc->xpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xcr,
- prtd->period_size / params->pdc_xfer_size);
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_enable);
- }
-
- if (ssc_sr & params->mask->ssc_endx) {
- /* Load the PDC next pointer and counter registers */
- prtd->period_ptr += prtd->period_size;
- if (prtd->period_ptr >= prtd->dma_buffer_end)
- prtd->period_ptr = prtd->dma_buffer;
-
- ssc_writex(params->ssc->regs, params->pdc->xnpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xncr,
- prtd->period_size / params->pdc_xfer_size);
- }
-
- snd_pcm_period_elapsed(substream);
-}
-
-
-/*--------------------------------------------------------------------------*\
- * PCM operations
-\*--------------------------------------------------------------------------*/
-static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atmel_runtime_data *prtd = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
- /* this may get called several times by oss emulation
- * with different params */
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
-
- prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
-
- prtd->dma_buffer = runtime->dma_addr;
- prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
- prtd->period_size = params_period_bytes(params);
-
- pr_debug("atmel-pcm: "
- "hw_params: DMA for %s initialized "
- "(dma_bytes=%u, period_size=%u)\n",
- prtd->params->name,
- runtime->dma_bytes,
- prtd->period_size);
- return 0;
-}
-
-static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
-
- if (params != NULL) {
- ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
- params->mask->pdc_disable);
- prtd->params->dma_intr_handler = NULL;
- }
-
- return 0;
-}
-
-static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
-
- ssc_writex(params->ssc->regs, SSC_IDR,
- params->mask->ssc_endx | params->mask->ssc_endbuf);
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_disable);
- return 0;
-}
-
-static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_pcm_runtime *rtd = substream->runtime;
- struct atmel_runtime_data *prtd = rtd->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
- int ret = 0;
-
- pr_debug("atmel-pcm:buffer_size = %ld,"
- "dma_area = %p, dma_bytes = %u\n",
- rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- prtd->period_ptr = prtd->dma_buffer;
-
- ssc_writex(params->ssc->regs, params->pdc->xpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xcr,
- prtd->period_size / params->pdc_xfer_size);
-
- prtd->period_ptr += prtd->period_size;
- ssc_writex(params->ssc->regs, params->pdc->xnpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xncr,
- prtd->period_size / params->pdc_xfer_size);
-
- pr_debug("atmel-pcm: trigger: "
- "period_ptr=%lx, xpr=%u, "
- "xcr=%u, xnpr=%u, xncr=%u\n",
- (unsigned long)prtd->period_ptr,
- ssc_readx(params->ssc->regs, params->pdc->xpr),
- ssc_readx(params->ssc->regs, params->pdc->xcr),
- ssc_readx(params->ssc->regs, params->pdc->xnpr),
- ssc_readx(params->ssc->regs, params->pdc->xncr));
-
- ssc_writex(params->ssc->regs, SSC_IER,
- params->mask->ssc_endx | params->mask->ssc_endbuf);
- ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
- params->mask->pdc_enable);
-
- pr_debug("sr=%u imr=%u\n",
- ssc_readx(params->ssc->regs, SSC_SR),
- ssc_readx(params->ssc->regs, SSC_IER));
- break; /* SNDRV_PCM_TRIGGER_START */
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_disable);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_enable);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static snd_pcm_uframes_t atmel_pcm_pointer(
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atmel_runtime_data *prtd = runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
- dma_addr_t ptr;
- snd_pcm_uframes_t x;
-
- ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
- x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
-
- if (x == runtime->buffer_size)
- x = 0;
-
- return x;
-}
-
-static int atmel_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atmel_runtime_data *prtd;
- int ret = 0;
-
- snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
-
- /* ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
- if (prtd == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- runtime->private_data = prtd;
-
- out:
- return ret;
-}
-
-static int atmel_pcm_close(struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
-
- kfree(prtd);
- return 0;
-}
-
-static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+int atmel_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
return remap_pfn_range(vma, vma->vm_start,
substream->dma_buffer.addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
}
+EXPORT_SYMBOL_GPL(atmel_pcm_mmap);
-static struct snd_pcm_ops atmel_pcm_ops = {
- .open = atmel_pcm_open,
- .close = atmel_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = atmel_pcm_hw_params,
- .hw_free = atmel_pcm_hw_free,
- .prepare = atmel_pcm_prepare,
- .trigger = atmel_pcm_trigger,
- .pointer = atmel_pcm_pointer,
- .mmap = atmel_pcm_mmap,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * ASoC platform driver
-\*--------------------------------------------------------------------------*/
static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
-static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
+int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
@@ -376,6 +82,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+ pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
ret = atmel_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
@@ -383,8 +90,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
}
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- pr_debug("atmel-pcm:"
- "Allocating PCM capture DMA buffer\n");
+ pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
ret = atmel_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -393,8 +99,9 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
out:
return ret;
}
+EXPORT_SYMBOL_GPL(atmel_pcm_new);
-static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
+void atmel_pcm_free(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
@@ -413,78 +120,5 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
buf->area = NULL;
}
}
+EXPORT_SYMBOL_GPL(atmel_pcm_free);
-#ifdef CONFIG_PM
-static int atmel_pcm_suspend(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct atmel_runtime_data *prtd;
- struct atmel_pcm_dma_params *params;
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- params = prtd->params;
-
- /* disable the PDC and save the PDC registers */
-
- ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
-
- prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
- prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
- prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
- prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
-
- return 0;
-}
-
-static int atmel_pcm_resume(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct atmel_runtime_data *prtd;
- struct atmel_pcm_dma_params *params;
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- params = prtd->params;
-
- /* restore the PDC registers and enable the PDC */
- ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
- ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
- ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
- ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
-
- ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
- return 0;
-}
-#else
-#define atmel_pcm_suspend NULL
-#define atmel_pcm_resume NULL
-#endif
-
-static struct snd_soc_platform_driver atmel_soc_platform = {
- .ops = &atmel_pcm_ops,
- .pcm_new = atmel_pcm_new,
- .pcm_free = atmel_pcm_free_dma_buffers,
- .suspend = atmel_pcm_suspend,
- .resume = atmel_pcm_resume,
-};
-
-int atmel_pcm_platform_register(struct device *dev)
-{
- return snd_soc_register_platform(dev, &atmel_soc_platform);
-}
-EXPORT_SYMBOL(atmel_pcm_platform_register);
-
-void atmel_pcm_platform_unregister(struct device *dev)
-{
- snd_soc_unregister_platform(dev);
-}
-EXPORT_SYMBOL(atmel_pcm_platform_unregister);
-
-MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou(a)atmel.com>");
-MODULE_DESCRIPTION("Atmel PCM module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index e6d67b3..6bd63b0 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -36,6 +36,8 @@
#include <linux/atmel-ssc.h>
+#define ATMEL_SSC_DMABUF_SIZE (64 * 1024)
+
/*
* Registers and status bits that are required by the PCM driver.
*/
@@ -80,7 +82,22 @@ struct atmel_pcm_dma_params {
#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
-int atmel_pcm_platform_register(struct device *dev);
-void atmel_pcm_platform_unregister(struct device *dev);
+int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd);
+void atmel_pcm_free(struct snd_pcm *pcm);
+int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma);
+
+#ifdef CONFIG_SND_ATMEL_SOC_PDC
+int atmel_pcm_pdc_platform_register(struct device *dev);
+void atmel_pcm_pdc_platform_unregister(struct device *dev);
+#else
+static inline int atmel_pcm_pdc_platform_register(struct device *dev)
+{
+ return 0;
+}
+static inline void atmel_pcm_pdc_platform_unregister(struct device *dev)
+{
+}
+#endif
#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 7932c05..1705614 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -729,7 +729,7 @@ static int asoc_ssc_init(struct device *dev)
goto err;
}
- ret = atmel_pcm_platform_register(dev);
+ ret = atmel_pcm_pdc_platform_register(dev);
if (ret) {
dev_err(dev, "Could not register PCM: %d\n", ret);
goto err_unregister_dai;
@@ -745,7 +745,7 @@ err:
static void asoc_ssc_exit(struct device *dev)
{
- atmel_pcm_platform_unregister(dev);
+ atmel_pcm_pdc_platform_unregister(dev);
snd_soc_unregister_dai(dev);
}
--
1.7.9.5
2
3
02 Dec '12
This codec driver adds support for Asahi Kasei AK5702.
Signed-off-by: Paolo Doz <paolo.doz(a)gmail.com>
---
include/sound/ak5702.h | 27 +++
sound/soc/codecs/Kconfig | 4 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/ak5702.c | 507 +++++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/ak5702.h | 171 +++++++++++++++
5 files changed, 711 insertions(+)
diff --git a/include/sound/ak5702.h b/include/sound/ak5702.h
new file mode 100644
index 0000000..8c0d4e9
--- /dev/null
+++ b/include/sound/ak5702.h
@@ -0,0 +1,27 @@
+/*
+ * AK5702 ALSA SoC Codec driver
+ *
+ * Author: Paolo Doz <paolo.doz(a)gmail.com>
+ * Copyright: (C) 2012 Soft In S.r.l.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __AK5702_H
+#define __AK5702_H
+
+/**
+ * enum ak5702_clock mode
+ */
+
+enum ak5702_clock_mode {
+ AK5702_CLKPLL_SLAVE,
+ AK5702_CLKPLL_SLAVE2,
+ AK5702_CLKPLL_MASTER,
+ AK5702_CLKEXT_SLAVE,
+ AK5702_CLKEXT_MASTER,
+};
+
+#endif /* __AK5702_H */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3a84782..d8156c7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,6 +26,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AK4641 if I2C
select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C
+ select SND_SOC_AK5702 if I2C
select SND_SOC_ALC5623 if I2C
select SND_SOC_ALC5632 if I2C
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
@@ -202,6 +203,9 @@ config SND_SOC_AK4642
config SND_SOC_AK4671
tristate
+config SND_SOC_AK5702
+ tristate
+
config SND_SOC_ALC5623
tristate
config SND_SOC_ALC5632
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f6e8e36..1f88602 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -14,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o
snd-soc-ak4641-objs := ak4641.o
snd-soc-ak4642-objs := ak4642.o
snd-soc-ak4671-objs := ak4671.o
+snd-soc-ak5702-objs := ak5702.o
snd-soc-arizona-objs := arizona.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs42l51-objs := cs42l51.o
@@ -136,6 +137,7 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
+obj-$(CONFIG_SND_SOC_AK5702) += snd-soc-ak5702.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
diff --git a/sound/soc/codecs/ak5702.c b/sound/soc/codecs/ak5702.c
new file mode 100644
index 0000000..9d35062
--- /dev/null
+++ b/sound/soc/codecs/ak5702.c
@@ -0,0 +1,507 @@
+/*
+ * ak5702.c -- AK5702 Soc Audio driver
+ *
+ * Author: Paolo Doz <paolo.doz(a)gmail.com>
+ * Copyright: (C) 2012 Soft In S.r.l.
+ * 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This code comes from the original Freescale Ak5702 Audio driver
+ */
+
+/* #define DEBUG 1 */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <linux/slab.h>
+#include <sound/tlv.h>
+#include <linux/regmap.h>
+
+#include <sound/ak5702.h>
+#include "ak5702.h"
+
+#define AK5702_VERSION "0.5"
+#define DRV_NAME "ak5702"
+
+/* codec private data */
+struct ak5702_priv {
+ struct regmap *regmap;
+ enum ak5702_clock_mode clock_mode;
+};
+
+/*
+ * ak5702 register cache
+ */
+static const struct reg_default ak5702_reg_defaults[] = {
+ { 0, 0x0000}, /* R0 - Power Management */
+ { 1, 0x0024}, /* R1 - PLL Control */
+ { 2, 0x0000}, /* R2 - Signal Select */
+ { 3, 0x0001}, /* R3 - Mic Gain Control */
+ { 4, 0x0023}, /* R4 - Audio Format Select */
+ { 5, 0x001F}, /* R5 - fs Select */
+ { 6, 0x0000}, /* R6 - Clock Output Select */
+ { 7, 0x0001}, /* R7 - Volume Control */
+ { 8, 0x0091}, /* R8 - Lch Input Volume Control */
+ { 9, 0x0091}, /* R9 - Rch Input Volume Control */
+ { 10, 0x0000}, /* R10 - Timer Select */
+ { 11, 0x00E1}, /* R11 - ALC Mode Control 1 */
+ { 12, 0x0000}, /* R12 - ALC Mode Control 2 */
+ { 13, 0x00A0}, /* R13 - Mode Control 1 */
+ { 14, 0x0000}, /* R14 - Mode Control 2 */
+ { 15, 0x0000}, /* R15 - Mode Control 3 */
+ { 16, 0x0000}, /* R16 - Power Management */
+ { 17, 0x0000}, /* R17 - PLL Control */
+ { 18, 0x0000}, /* R18 - Signal Select */
+ { 19, 0x0001}, /* R19 - Mic Gain Control */
+ { 20, 0x0020}, /* R20 - Audio Format Select */
+ { 21, 0x0000}, /* R21 - fs Select */
+ { 22, 0x0000}, /* R22 - Clock Output Select */
+ { 23, 0x0001}, /* R23 - Volume Control */
+ { 24, 0x0091}, /* R24 - Lch Input Volume Control */
+ { 25, 0x0091}, /* R25 - Rch Input Volume Control */
+ { 26, 0x0000}, /* R26 - Timer Select */
+ { 27, 0x00E1}, /* R27 - ALC Mode Control 1 */
+ { 28, 0x0000}, /* R28 - ALC Mode Control 2 */
+ { 29, 0x0000}, /* R29 - Mode Control 1 */
+ { 30, 0x0000}, /* R30 - Mode Control 2 */
+};
+
+static bool ak5702_writeable(struct device *dev, unsigned int reg)
+{
+ return reg < AK5702_MAX_REGISTER;
+}
+
+static const unsigned int mic_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0, 2, TLV_DB_SCALE_ITEM(0, 1500, 0),
+ 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
+};
+
+static const DECLARE_TLV_DB_SCALE(in_tlv, -5400, 37, 1);
+
+static const char *ak5702_adca_left12_input[] = { "Left1", "Left2" };
+static const char *ak5702_adca_right12_input[] = { "Right1", "Right2" };
+static const char *ak5702_adca_left5_input[] = { "Left1/2", "Left5" };
+static const char *ak5702_adca_right5_input[] = { "Right1/2", "Right5" };
+
+static const char *ak5702_adcb_left12_input[] = { "Left3", "Left4" };
+static const char *ak5702_adcb_right12_input[] = { "Right3", "Right4" };
+static const char *ak5702_adcb_left5_input[] = { "Left3-4", "Left5" };
+static const char *ak5702_adcb_right5_input[] = { "Right3-4", "Right5" };
+
+static const struct soc_enum ak5702_enum[] = {
+ SOC_ENUM_SINGLE(AK5702_SIG1, 0, 2, ak5702_adca_left12_input),
+ SOC_ENUM_SINGLE(AK5702_SIG1, 1, 2, ak5702_adca_right12_input),
+ SOC_ENUM_SINGLE(AK5702_SIG2, 0, 2, ak5702_adcb_left12_input),
+ SOC_ENUM_SINGLE(AK5702_SIG2, 1, 2, ak5702_adcb_right12_input),
+ SOC_ENUM_SINGLE(AK5702_SIG1, 5, 2, ak5702_adca_left5_input),
+ SOC_ENUM_SINGLE(AK5702_SIG1, 6, 2, ak5702_adca_right5_input),
+ SOC_ENUM_SINGLE(AK5702_SIG2, 5, 2, ak5702_adcb_left5_input),
+ SOC_ENUM_SINGLE(AK5702_SIG2, 6, 2, ak5702_adcb_right5_input),
+};
+
+static const struct snd_kcontrol_new ak5702_snd_controls[] = {
+ SOC_ENUM("ADCA Left1/2 Capture Source", ak5702_enum[0]),
+ SOC_ENUM("ADCA Right1/2 Capture Source", ak5702_enum[1]),
+ SOC_ENUM("ADCB Left1/2 Capture Source", ak5702_enum[2]),
+ SOC_ENUM("ADCB Right1/2 Capture Source", ak5702_enum[3]),
+ SOC_ENUM("ADCA Left5 Capture Source", ak5702_enum[4]),
+ SOC_ENUM("ADCA Right5 Capture Source", ak5702_enum[5]),
+ SOC_ENUM("ADCB Left5 Capture Source", ak5702_enum[6]),
+ SOC_ENUM("ADCB Right5 Capture Source", ak5702_enum[7]),
+ SOC_SINGLE_TLV("Mic A Boost Gain", AK5702_MICG1, 0, 3, 0, mic_tlv),
+ SOC_SINGLE_TLV("Mic B Boost Gain", AK5702_MICG2, 0, 3, 0, mic_tlv),
+ SOC_DOUBLE_R_TLV("ADCA Capture Volume", AK5702_LVOL1, AK5702_RVOL1, 0,
+ 241, 0, in_tlv),
+ SOC_DOUBLE_R_TLV("ADCB Capture Volume", AK5702_LVOL2, AK5702_RVOL2, 0,
+ 241, 0, in_tlv),
+};
+
+/* ak5702 dapm widgets */
+static const struct snd_soc_dapm_widget ak5702_dapm_widgets[] = {
+ SND_SOC_DAPM_ADC("ADCA Left", "Capture", AK5702_PM1, 0, 0),
+ SND_SOC_DAPM_ADC("ADCA Right", "Capture", AK5702_PM1, 1, 0),
+ SND_SOC_DAPM_ADC("ADCB Left", "Capture", AK5702_PM2, 0, 0),
+ SND_SOC_DAPM_ADC("ADCB Right", "Capture", AK5702_PM2, 1, 0),
+
+ SND_SOC_DAPM_INPUT("ADCA Left Input"),
+ SND_SOC_DAPM_INPUT("ADCA Right Input"),
+ SND_SOC_DAPM_INPUT("ADCB Left Input"),
+ SND_SOC_DAPM_INPUT("ADCB Right Input"),
+};
+
+static const struct snd_soc_dapm_route ak5702_dapm_routes[] = {
+ {"ADCA Left", NULL, "ADCA Left Input"},
+ {"ADCA Right", NULL, "ADCA Right Input"},
+ {"ADCB Left", NULL, "ADCB Left Input"},
+ {"ADCB Right", NULL, "ADCB Right Input"},
+};
+
+static int ak5702_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct ak5702_priv *ak5702 = snd_soc_codec_get_drvdata(codec);
+ u8 value;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ /* power on ADCA */
+ value = AK5702_PM1_PMADAL |
+ AK5702_PM1_PMADAR |
+ AK5702_PM1_PMVCM;
+ snd_soc_write(codec, AK5702_PM1, value);
+ /* power up ADCB */
+ value = AK5702_PM2_PMADBL | AK5702_PM2_PMADBR;
+ snd_soc_write(codec, AK5702_PM2, value);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+ regcache_sync(ak5702->regmap);
+ /* power down ADCA */
+ value = AK5702_POWERDOWN | AK5702_PM1_PMVCM;
+ snd_soc_write(codec, AK5702_PM1, value);
+ /* power down ADCB */
+ value = AK5702_POWERDOWN;
+ snd_soc_write(codec, AK5702_PM2, value);
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* power down */
+ value = AK5702_POWERDOWN;
+ snd_soc_write(codec, AK5702_PM1, value);
+ value = AK5702_POWERDOWN;
+ snd_soc_write(codec, AK5702_PM2, value);
+ regcache_mark_dirty(ak5702->regmap);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+static int ak5702_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ u8 value;
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak5702_priv *ak5702 = snd_soc_codec_get_drvdata(codec);
+
+ pr_debug("Entered %s\n", __func__);
+
+ switch (params_channels(params)) {
+ case 2:
+ snd_soc_update_bits(codec, AK5702_FMT1, AK5702_FMT1_TDM_MASK,
+ AK5702_FMT1_STEREO);
+ break;
+ case 8:
+ if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
+ value = AK5702_FMT1_TDM128;
+ else if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
+ value = AK5702_FMT1_TDM256;
+ else
+ return -EINVAL;
+ snd_soc_update_bits(codec, AK5702_FMT1, AK5702_FMT1_TDM_MASK,
+ value);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (params_rate(params)) {
+ case 48000:
+ if (ak5702->clock_mode == AK5702_CLKPLL_SLAVE2)
+ value = AK5702_FS1_BCLK_MODE2;
+ else if (ak5702->clock_mode == AK5702_CLKEXT_SLAVE)
+ value = AK5702_FS1_SLAVE_256FS; /* mode 3 256fs*/
+ else
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ snd_soc_update_bits(codec, AK5702_FS1,
+ AK5702_FS1_FS_MASK | AK5702_FS1_BCKO_MASK, value);
+ return 0;
+}
+
+static int ak5702_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct ak5702_priv *ak5702 = snd_soc_codec_get_drvdata(codec);
+ u8 value = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ switch (clk_id) {
+ case AK5702_CLKPLL_MASTER:
+ case AK5702_CLKEXT_MASTER:
+ if (dir != SND_SOC_CLOCK_OUT)
+ return -EINVAL;
+ break;
+ case AK5702_CLKPLL_SLAVE:
+ case AK5702_CLKPLL_SLAVE2:
+ if (dir != SND_SOC_CLOCK_IN)
+ return -EINVAL;
+ value = AK5702_PLL1_POWERUP |
+ AK5702_PLL1_SLAVE |
+ AK5702_PLL1_MODE2;
+ break;
+ case AK5702_CLKEXT_SLAVE:
+ if (dir != SND_SOC_CLOCK_IN)
+ return -EINVAL;
+ value = AK5702_PLL1_POWERDOWN | AK5702_PLL1_SLAVE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ snd_soc_write(codec, AK5702_PLL1, value);
+ ak5702->clock_mode = clk_id;
+ return 0;
+}
+
+static int ak5702_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 value = 0;
+ pr_debug("Entered %s", __func__);
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_I2S:
+ value = AK5702_FMT1_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ value = AK5702_FMT1_MSB;
+ break;
+ default:
+ return -EINVAL;
+ }
+ snd_soc_update_bits(codec, AK5702_FMT1, AK5702_FMT1_FMT_MASK, value);
+ snd_soc_write(codec, AK5702_FMT2, AK5702_FMT2_STEREO);
+ return 0;
+}
+
+static int ak5702_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 reg = 0;
+ pr_debug("Entered %s", __func__);
+ reg = snd_soc_read(codec, AK5702_PLL1);
+ switch (pll_id) {
+ case AK5702_PLL_POWERDOWN:
+ reg &= (~AK5702_PLL1_PM_MASK);
+ reg |= AK5702_PLL1_POWERDOWN;
+ break;
+ case AK5702_PLL_MASTER:
+ reg &= (~AK5702_PLL1_MODE_MASK);
+ reg |= AK5702_PLL1_MASTER | AK5702_PLL1_POWERUP;
+ break;
+ case AK5702_PLL_SLAVE:
+ reg &= (~AK5702_PLL1_MODE_MASK);
+ reg |= AK5702_PLL1_SLAVE | AK5702_PLL1_POWERUP;
+ break;
+ default:
+ return -ENODEV;
+ }
+ reg &= (~AK5702_PLL1_PLL_MASK);
+ switch (freq_in) {
+ case 11289600:
+ reg |= AK5702_PLL1_11289600;
+ break;
+ case 12000000:
+ reg |= AK5702_PLL1_12000000;
+ break;
+ case 12288000:
+ reg |= AK5702_PLL1_12288000;
+ break;
+ case 19200000:
+ reg |= AK5702_PLL1_19200000;
+ break;
+ default:
+ return -ENODEV;
+ }
+ snd_soc_write(codec, AK5702_PLL1, reg);
+ return 0;
+}
+
+static int ak5702_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 value = 0;
+ pr_debug("Entered %s", __func__);
+ if (div_id == AK5702_BCLK_CLKDIV) {
+ switch (div) {
+ case AK5702_BCLK_DIV_32:
+ value = AK5702_FS1_BCKO_32FS;
+ break;
+ case AK5702_BCLK_DIV_64:
+ value = AK5702_FS1_BCKO_64FS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ snd_soc_update_bits(codec, AK5702_FS1, AK5702_FS1_BCKO_MASK, value);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ak5702_suspend(struct snd_soc_codec *codec)
+{
+ ak5702_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int ak5702_resume(struct snd_soc_codec *codec)
+{
+ ak5702_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define ak5702_suspend NULL
+#define ak5702_resume NULL
+#endif
+
+static const struct snd_soc_dai_ops ak5702_ops = {
+ .set_sysclk = ak5702_set_dai_sysclk,
+ .set_pll = ak5702_set_dai_pll,
+ .set_clkdiv = ak5702_set_dai_clkdiv,
+ .set_fmt = ak5702_set_dai_fmt,
+ .hw_params = ak5702_dai_hw_params,
+};
+
+struct snd_soc_dai_driver ak5702_dai = {
+ .name = "ak5702-hifi",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ },
+ .ops = &ak5702_ops,
+};
+
+static int ak5702_probe(struct snd_soc_codec *codec)
+{
+ struct ak5702_priv *ak5702 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ dev_info(codec->dev, "AK5702 Audio Codec %s", AK5702_VERSION);
+
+ codec->control_data = ak5702->regmap;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+ ak5702_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return ret;
+}
+
+static int ak5702_remove(struct snd_soc_codec *codec)
+{
+ ak5702_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static const struct regmap_config ak5702_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK5702_MAX_REGISTER,
+ .writeable_reg = ak5702_writeable,
+
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = ak5702_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(ak5702_reg_defaults),
+};
+
+static __devinit int ak5702_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct ak5702_priv *ak5702;
+ int ret;
+ pr_debug("Entered %s", __func__);
+
+ ak5702 = devm_kzalloc(&i2c->dev, sizeof(struct ak5702_priv),
+ GFP_KERNEL);
+ if (!ak5702)
+ return -ENOMEM;
+
+ ak5702->regmap = devm_regmap_init_i2c(i2c, &ak5702_regmap);
+ if (IS_ERR(ak5702->regmap)) {
+ ret = PTR_ERR(ak5702->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ i2c_set_clientdata(i2c, ak5702);
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak5702, &ak5702_dai, 1);
+ if (ret != 0)
+ dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+
+ return ret;
+}
+
+static __devexit int ak5702_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+static const struct i2c_device_id ak5702_i2c_id[] = {
+ { "ak5702-codec", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, ak5702_i2c_id);
+
+static struct i2c_driver ak5702_i2c_driver = {
+ .driver = {
+ .name = "ak5702-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = ak5702_i2c_probe,
+ .remove = __devexit_p(ak5702_i2c_remove),
+ .id_table = ak5702_i2c_id,
+};
+
+struct snd_soc_codec_driver soc_codec_dev_ak5702 = {
+ .probe = ak5702_probe,
+ .remove = ak5702_remove,
+ .suspend = ak5702_suspend,
+ .resume = ak5702_resume,
+ .set_bias_level = ak5702_set_bias_level,
+ .controls = ak5702_snd_controls,
+ .num_controls = ARRAY_SIZE(ak5702_snd_controls),
+ .dapm_widgets = ak5702_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak5702_dapm_widgets),
+ .dapm_routes = ak5702_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(ak5702_dapm_routes),
+};
+
+module_i2c_driver(ak5702_i2c_driver);
+
+MODULE_DESCRIPTION("Asahi Kasei AK5702 ALSA SoC driver");
+MODULE_AUTHOR("Paolo Doz <paolo.doz(a)gmail.com");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak5702.h b/sound/soc/codecs/ak5702.h
new file mode 100644
index 0000000..a492a61
--- /dev/null
+++ b/sound/soc/codecs/ak5702.h
@@ -0,0 +1,171 @@
+/*
+ * ak5702.h -- AK5702 Soc Audio driver
+ *
+ * Author: Paolo Doz <paolo.doz(a)gmail.com>
+ * Copyright: (C) 2012 Soft In S.r.l.
+ * 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This code comes from the original Freescale Ak5702 Audio driver
+ */
+
+#ifndef _AK5702_H
+#define _AK5702_H
+
+/* AK5702 register space */
+
+#define AK5702_PM1 0x00
+#define AK5702_PLL1 0x01
+#define AK5702_SIG1 0x02
+#define AK5702_MICG1 0x03
+#define AK5702_FMT1 0x04
+#define AK5702_FS1 0x05
+#define AK5702_CLK1 0x06
+#define AK5702_VOLCTRL1 0x07
+#define AK5702_LVOL1 0x08
+#define AK5702_RVOL1 0x09
+#define AK5702_TIMER1 0x0A
+#define AK5702_ALC11 0x0B
+#define AK5702_ALC12 0x0C
+#define AK5702_MODE11 0x0D
+#define AK5702_MODE12 0x0E
+#define AK5702_MODE13 0x0F
+
+#define AK5702_PM2 0x10
+#define AK5702_PLL2 0x11
+#define AK5702_SIG2 0x12
+#define AK5702_MICG2 0x13
+#define AK5702_FMT2 0x14
+#define AK5702_FS2 0x15
+#define AK5702_CLK2 0x16
+#define AK5702_VOLCTRL2 0x17
+#define AK5702_LVOL2 0x18
+#define AK5702_RVOL2 0x19
+#define AK5702_TIMER2 0x1A
+#define AK5702_ALC21 0x1B
+#define AK5702_ALC22 0x1C
+#define AK5702_MODE21 0x1D
+#define AK5702_MODE22 0x1E
+
+#define AK5702_MAX_REGISTER 0x1F
+
+#define AK5702_CACHEREGNUM 0x1F
+
+#define AK5702_POWERDOWN 0x0
+#define AK5702_PM1_PMADAL 0x01
+#define AK5702_PM1_PMADAR 0x02
+#define AK5702_PM1_PMVCM 0x04
+#define AK5702_PM2_PMADBL 0x01
+#define AK5702_PM2_PMADBR 0x02
+
+#define AK5702_PLL1_POWERDOWN 0x0
+#define AK5702_PLL1_POWERUP 0x01
+#define AK5702_PLL1_MASTER 0x02
+#define AK5702_PLL1_SLAVE 0x0
+#define AK5702_PLL1_MODE0 0x0
+#define AK5702_PLL1_MODE2 0x08
+#define AK5702_PLL1_MODE3 0x0C
+#define AK5702_PLL1_MODE4 0x10
+#define AK5702_PLL1_MODE5 0x14
+#define AK5702_PLL1_MODE6 0x18
+#define AK5702_PLL1_MODE7 0x1C
+#define AK5702_PLL1_MODE8 0x20
+#define AK5702_PLL1_MODE9 0x24
+#define AK5702_PLL1_MODE12 0x30
+#define AK5702_PLL1_MODE13 0x34
+#define AK5702_PLL1_MODE14 0x38
+#define AK5702_PLL1_MODE15 0x3C
+#define AK5702_PLL1_11289600 0x10
+#define AK5702_PLL1_12000000 0x24
+#define AK5702_PLL1_12288000 0x14
+#define AK5702_PLL1_19200000 0x20
+
+#define AK5702_FS1_MCKI_MODE0 0x0
+#define AK5702_FS1_MCKI_MODE1 0x01
+#define AK5702_FS1_MCKI_MODE2 0x02
+#define AK5702_FS1_MCKI_MODE3 0x03
+#define AK5702_FS1_MCKI_MODE4 0x04
+#define AK5702_FS1_MCKI_MODE5 0x05
+#define AK5702_FS1_MCKI_MODE6 0x06
+#define AK5702_FS1_MCKI_MODE7 0x07
+#define AK5702_FS1_MCKI_MODE10 0x0A
+#define AK5702_FS1_MCKI_MODE11 0x0B
+#define AK5702_FS1_MCKI_MODE14 0x0E
+#define AK5702_FS1_MCKI_MODE15 0x0F
+
+#define AK5702_FS1_BCLK_MODE0 0x0
+#define AK5702_FS1_BCLK_MODE1 0x04
+#define AK5702_FS1_BCLK_MODE2 0x08
+
+#define AK5702_FS1_SLAVE_1024FS 0x01
+#define AK5702_FS1_SLAVE_512FS 0x02
+#define AK5702_FS1_SLAVE_256FS 0x03
+
+#define AK5702_SIG1_L_LIN1 0x0
+#define AK5702_SIG1_L_LIN2 0x01
+#define AK5702_SIG1_R_RIN1 0x0
+#define AK5702_SIG1_R_RIN2 0x02
+#define AK5702_SIG1_PMMPA 0x10
+#define AK5702_SIG1_L_LIN5 0x20
+#define AK5702_SIG1_R_RIN5 0x40
+#define AK5702_SIG2_L_LIN3 0x0
+#define AK5702_SIG2_L_LIN4 0x01
+#define AK5702_SIG2_R_RIN3 0x0
+#define AK5702_SIG2_R_RIN4 0x02
+#define AK5702_SIG2_PMMPB 0x10
+
+#define AK5702_MICGAIN_0DB 0x0
+
+#define AK5702_FMT1_I2S 0x03
+#define AK5702_FMT1_MSB 0x02
+#define AK5702_FMT1_STEREO 0x00
+#define AK5702_FMT1_TDM128 0x60
+#define AK5702_FMT1_TDM256 0xE0
+#define AK5702_FMT2_STEREO 0x20
+#define AK5702_FS1_BCKO_32FS 0x10
+#define AK5702_FS1_BCKO_64FS 0x20
+#define AK5702_CLK1_PS_256FS 0x0
+#define AK5702_CLK1_PS_128FS 0x01
+#define AK5702_CLK1_PS_64FS 0x02
+#define AK5702_CLK1_PS_32FS 0x03
+#define AK5702_VOLCTRL_INDEP 0x0
+#define AK5702_VOLCTRL_DEP 0x01
+#define AK5702_VOL_INIT 0x91
+
+#define AK5702_PM1_MASK 0x07
+#define AK5702_PM2_MASK 0x03
+#define AK5702_PLL1_PM_MASK 0x01
+#define AK5702_PLL1_MODE_MASK 0x02
+#define AK5702_PLL1_PLL_MASK 0x3C
+#define AK5702_FS1_BCKO_MASK 0x30
+#define AK5702_FS1_FS_MASK 0x0F
+#define AK5702_CLK1_PS_MASK 0x03
+#define AK5702_FMT1_FMT_MASK 0x03
+#define AK5702_FMT1_TDM_MASK 0xC0
+#define AK5702_FMT2_OUT_MASK 0x10
+/* clock divider id */
+#define AK5702_BCLK_CLKDIV 0
+#define AK5702_MCLK_CLKDIV 1
+
+/* bit clock div values */
+#define AK5702_BCLK_DIV_32 0
+#define AK5702_BCLK_DIV_64 1
+
+/* m clock div values */
+#define AK5702_MCLK_DIV_32 0
+#define AK5702_MCLK_DIV_64 1
+#define AK5702_MCLK_DIV_128 2
+#define AK5702_MCLK_DIV_256 3
+
+/* PLL master and slave modes */
+#define AK5702_PLL_POWERDOWN 0
+#define AK5702_PLL_MASTER 1
+#define AK5702_PLL_SLAVE 2
+
+extern struct snd_soc_dai_driver ak5702_dai;
+extern struct snd_soc_codec_driver soc_codec_dev_ak5702;
+
+#endif
2
1
[alsa-devel] [PATCH 1/6] ALSA: PCM: Remove redundant null check before kfree
by Sachin Kamat 02 Dec '12
by Sachin Kamat 02 Dec '12
02 Dec '12
kfree on a null pointer is a no-op.
Signed-off-by: Sachin Kamat <sachin.kamat(a)linaro.org>
---
Build tested and based on linux-next 20121115.
---
sound/core/pcm.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 030102c..61798f8 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -981,8 +981,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
kfree(runtime->hw_constraints.rules);
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
- if (runtime->hwptr_log)
- kfree(runtime->hwptr_log);
+ kfree(runtime->hwptr_log);
#endif
kfree(runtime);
substream->runtime = NULL;
--
1.7.4.1
3
14
02 Dec '12
devm_regmap_init_i2c() is device managed and makes error
handling and code cleanup simpler.
Signed-off-by: Sachin Kamat <sachin.kamat(a)linaro.org>
---
sound/soc/codecs/wm9090.c | 20 ++++++--------------
1 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index c7ddc56..bb55a70 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -628,7 +628,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
}
- wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap);
+ wm9090->regmap = devm_regmap_init_i2c(i2c, &wm9090_regmap);
if (IS_ERR(wm9090->regmap)) {
ret = PTR_ERR(wm9090->regmap);
dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
@@ -637,16 +637,16 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®);
if (ret < 0)
- goto err;
+ return ret;
+
if (reg != 0x9093) {
dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
- ret = -ENODEV;
- goto err;
+ return -ENODEV;
}
ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
if (ret < 0)
- goto err;
+ return ret;
if (i2c->dev.platform_data)
memcpy(&wm9090->pdata, i2c->dev.platform_data,
@@ -658,23 +658,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
&soc_codec_dev_wm9090, NULL, 0);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err;
+ return ret;
}
return 0;
-
-err:
- regmap_exit(wm9090->regmap);
- return ret;
}
static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
{
- struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
-
snd_soc_unregister_codec(&i2c->dev);
- regmap_exit(wm9090->regmap);
-
return 0;
}
--
1.7.4.1
2
1
- changed iobox recognition and firmware loading to mimick XP driver
- added loop to check_for_iobox() to fix timing issues
Signed-off-by: Karl Grill <kgrill(a)chello.at>
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0d6930c..4229b0d 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -155,10 +155,11 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_BIGENDIAN_MODE 0x200
#define HDSP_RD_MULTIPLE 0x400
#define HDSP_9652_ENABLE_MIXER 0x800
+#define HDSP_DUNNO 0x1000
#define HDSP_TDO 0x10000000
-#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
-#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
+#define HDSP_S_PROGRAM (HDSP_DUNNO|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
+#define HDSP_S_LOAD (HDSP_DUNNO|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
/* Control Register bits */
@@ -676,13 +677,20 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
static int hdsp_check_for_iobox (struct hdsp *hdsp)
{
+ int i;
+
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
- if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
- snd_printk("Hammerfall-DSP: no IO box connected!\n");
- hdsp->state &= ~HDSP_FirmwareLoaded;
- return -EIO;
+ for(i=0; i<10000; i++) {
+ if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError)==0) {
+ if(i)
+ snd_printk("Hammerfall-DSP: IO box found after %d ms\n", i);
+ return 0;
+ }
+ msleep(1);
}
- return 0;
+ snd_printk("Hammerfall-DSP: no IO box connected!\n");
+ hdsp->state &= ~HDSP_FirmwareLoaded;
+ return -EIO;
}
static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
@@ -722,6 +730,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
+ hdsp_write (hdsp, HDSP_control2Reg, 0x800);
return -EIO;
}
@@ -731,25 +740,25 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
+ hdsp_write (hdsp, HDSP_control2Reg, 0x800);
return -EIO;
}
}
- ssleep(3);
-
- if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
- snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
- return -EIO;
- }
+ hdsp_fifo_wait (hdsp, 3, HDSP_LONG_WAIT);
+ hdsp_write (hdsp, HDSP_control2Reg, 0x800);
+ ssleep(3);
#ifdef SNDRV_BIG_ENDIAN
hdsp->control2_register = HDSP_BIGENDIAN_MODE;
#else
hdsp->control2_register = 0;
#endif
+
hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
snd_printk ("Hammerfall-DSP: finished firmware loading\n");
+
}
if (hdsp->state & HDSP_InitializationComplete) {
snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
@@ -767,24 +776,46 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
{
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
+ hdsp_write (hdsp, HDSP_control2Reg, 0x10a0);
hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
- return -EIO;
-
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ hdsp_write(hdsp, HDSP_control2Reg, 0x900);
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x820);
hdsp_write (hdsp, HDSP_fifoData, 0);
-
- if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
- hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
- hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
- if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
- hdsp->io_type = RPM;
- else
- hdsp->io_type = Multiface;
- } else {
- hdsp->io_type = Digiface;
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ hdsp->io_type=Multiface;
+ snd_printk("Hammerfall-DSP: Multiface found\n");
+ return 0;
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ hdsp_write (hdsp, HDSP_fifoData, 0);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) == 0) {
+ hdsp->io_type=Digiface;
+ snd_printk("Hammerfall-DSP: Digiface found\n");
+ return 0;
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x900);
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ hdsp_write (hdsp, HDSP_fifoData, 0);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) == 0) {
+ hdsp->io_type=Multiface;
+ snd_printk("Hammerfall-DSP: Multiface found\n");
+ return 0;
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x900);
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ hdsp_write (hdsp, HDSP_fifoData, 0);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ hdsp->io_type=Multiface;
+ snd_printk("Hammerfall-DSP: Multiface found\n");
+ return 0;
}
+ hdsp->io_type=RPM;
+ snd_printk("Hammerfall-DSP: RPM found\n");
+ return 0;
+
} else {
/* firmware was already loaded, get iobox type */
if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
--
1.7.2.5
2
2
Hi!
I've been working on a driver for the new 390 channels RME MADI FX.
For those who are interested, I've made the source available here:
https://github.com/adiknoth/madifx
As mentioned there, I only had remote access, so not all possible
hardware configurations have been tested. This might change next year,
until then, consider everything as "coincidentally working" ;)
Most importantly, the userspace API isn't stable, yet, since we still
have to develop new tools for metering and mixer adjustments. If we
exclude this API (the ioctls) for now, it is moderately safe to go
mainline, though we definitely lack decent test coverage.
ALSA devs: Feel free to demand any changes that are required for
mainline inclusion. The github repo is meant to serve as an incubator
from which we'll eventually derive the final kernel patch.
Cheers
1
0