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
May 2016
- 118 participants
- 261 discussions
The following changes since commit 515511a7920c69aebf7f5fef0cb8e1df6767f34c:
Merge remote-tracking branch 'asoc/topic/hdmi' into asoc-next (2016-05-13 14:27:16 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git tags/asoc-v4.7-2
for you to fetch changes up to bf65921380cd50b87618df550398e06581f4a361:
Merge remote-tracking branch 'asoc/topic/wm8962' into asoc-next (2016-05-27 13:46:02 +0100)
----------------------------------------------------------------
ASoC: Updates for v4.7 part 2
Really sorry about this late pull request. It looks like at the time I
sent my pull request for v4.7 there was some conflict or other issue
which caused my script to stop merging the ASoC branches at some point
after the HDMI changes.
It's all specific driver updates, including:
- New drivers for MAX98371 and TAS5720.
- SPI support for TLV320AIC32x4.
- TDM support for STI Uniperf IPs.
This code should all have been in -next prior to the merge window apart
from some fixes, it dropped out on the 18th.
----------------------------------------------------------------
Akinobu Mita (1):
spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer
Al Viro (6):
do_splice_to(): cap the size before passing to ->splice_read()
fix the copy vs. map logics in blk_rq_map_user_iov()
atomic_open(): fix the handling of create_error
ecryptfs: fix handling of directory opening
get_rock_ridge_filename(): handle malformed NM entries
Merge branch 'ovl-fixes' into for-linus
Alex Deucher (2):
drm/radeon: fix DP mode validation
drm/amdgpu: fix DP mode validation
Alexander Shishkin (2):
perf/x86/intel/pt: Generate PMI in the STOP region as well
perf/core: Disable the event on a truncated AUX record
Andrea Adami (1):
ASoC: pxa: Fix module autoload for platform drivers
Andrea Arcangeli (1):
mm: thp: calculate the mapcount correctly for THP pages during WP faults
Andreas Dannenberg (2):
ASoC: add TA5720 digital amplifier DT bindings
ASoC: add support for TAS5720 digital amplifier
Andrey Ryabinin (1):
perf/x86: Fix undefined shift on 32-bit kernels
Andrey Utkin (1):
kvmconfig: add more virtio drivers
Andrey Vostrikov (1):
spi: spi-fsl-dspi: Fix cs_change handling in message transfer
Andy Lutomirski (1):
perf/core: Change the default paranoia level to 2
Arindam Nath (1):
drm/radeon: fix DP link training issue with second 4K monitor
Arnaldo Carvalho de Melo (9):
perf tools: Use readdir() instead of deprecated readdir_r()
perf script: Use readdir() instead of deprecated readdir_r()
perf thread_map: Use readdir() instead of deprecated readdir_r()
perf tools: Use readdir() instead of deprecated readdir_r()
perf dwarf: Guard !x86_64 definitions under #ifdef else clause
perf probe: Check if dwarf_getlocations() is available
perf evsel: Improve EPERM error handling in open_strerror()
perf evsel: Handle EACCESS + perf_event_paranoid=2 in fallback()
perf stat: Fallback to user only counters when perf_event_paranoid > 1
Arnd Bergmann (6):
regmap: fix documentation to match code
Revert "net/mlx5: Kconfig: Fix MLX5_EN/VXLAN build issue"
net/mlx5e: make VXLAN support conditional
Merge tag 'at91-fixes' of git://git.kernel.org/.../nferre/linux-at91 into fixes
Merge tag 'at91-fixes2' of git://git.kernel.org/.../nferre/linux-at91 into fixes
net: mvneta: bm: fix dependencies again
Axel Lin (2):
ASoC: rt5677: Avoid duplicate the same test in each switch case
ASoC: max98371 Remove duplicate entry in max98371_reg
Bard Liao (2):
ASoC: rt298: reset AD dilter is there is no MCLK
ASoC: rt298: fix capture doesn't work at some cases
Bastien Nocera (1):
ASoC: tlv320aix31xx: Add ACPI match for Lenovo 100S
Ben Hutchings (2):
spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden
spi: spi-ti-qspi: Handle truncated frames properly
Boris Brezillon (1):
ARM: dts: at91: sam9x5: Fix the memory range assigned to the PMC
Chris Diamand (1):
Input: byd - update copyright header
Colin Ian King (1):
tools: bpf_jit_disasm: check for klogctl failure
Dan Carpenter (6):
scsi_dh_alua: uninitialized variable in alua_rtpg()
netxen: fix error handling in netxen_get_flash_block()
netxen: reversed condition in netxen_nic_set_link_parameters()
netxen: netxen_rom_fast_read() doesn't return -1
qede: uninitialized variable in qede_start_xmit()
qlcnic: potential NULL dereference in qlcnic_83xx_get_minidump_template()
Dan Williams (1):
libnvdimm, pfn: fix ARCH=alpha allmodconfig build failure
Daniel Jurgens (1):
net/mlx4_en: Fix endianness bug in IPV6 csum calculation
Daniel Vetter (1):
drm/i915: Bail out of pipe config compute loop on LPT
Dave Airlie (3):
Merge tag 'drm-intel-fixes-2016-05-11' of git://anongit.freedesktop.org/drm-intel into drm-fixes
Merge branch 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
Merge branch 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
David Ahern (1):
net: ipv6: tcp reset, icmp need to consider L3 domain
David Howells (1):
KEYS: Fix ASN.1 indefinite length object parsing
David S. Miller (9):
Merge branch 'master' of git://git.kernel.org/.../klassert/ipsec
Merge branch 'bnxt_en-fixes'
Merge branch 'mlx5-build-fix'
Merge git://git.kernel.org/.../pablo/nf
Merge tag 'wireless-drivers-for-davem-2016-05-09' of git://git.kernel.org/.../kvalo/wireless-drivers
Merge branch 'nps_enet-fixes'
Merge branch 'net-sched-fixes'
Merge branch 'bnxt_en-fixes'
Merge branch 'xgene-fixes'
Dmitry V. Levin (1):
x86: Use compat version for preadv2 and pwritev2
Elad Kanfi (2):
net: nps_enet: Tx handler synchronization
net: nps_enet: bug fix - handle lost tx interrupts
Emmanuel Grumbach (1):
iwlwifi: mvm: don't override the rate with the AMSDU len
Eric Dumazet (2):
macvtap: segmented packet is consumed
tcp: refresh skb timestamp at retransmit time
Fabio Estevam (6):
ASoC: wm8960: Provide a menu selection text
ASoC: wm8962: Disable clock if wm8962_runtime_resume() fails
ASoC: wm8962: Fit error message into a single line
ASoC: wm8962: Adjust clk definitions so that simple card can work
ASoC: hdac_hdmi: Remove the unused 'timeout' variable
spi: spi-ep93xx: Fix the PTR_ERR() argument
Felipe Balbi (1):
cgroup: fix compile warning
Florian Westphal (1):
netfilter: conntrack: init all_locks to avoid debug warning
Geert Uytterhoeven (2):
ravb: Add missing free_irq() call to ravb_close()
regulator: da9063: Correct module alias prefix to fix module autoloading
Guneshwor Singh (1):
ASoC: topology: Set CPU DAI name and enable DPCM by default for FE link
H. Nikolaus Schaller (1):
Input: twl6040-vibra - fix DT node memory management
Hans de Goede (2):
regulator: axp20x: Fix axp22x ldo_io voltage ranges
regulator: axp20x: Fix axp22x ldo_io registration error on cold boot
Herbert Xu (2):
crypto: hash - Fix page length clamping in hash walk
crypto: testmgr - Use kmalloc memory for RSA input
Ian Campbell (1):
VSOCK: do not disconnect socket when peer has shutdown SEND only
Ido Schimmel (2):
mlxsw: spectrum: Fix rollback order in LAG join failure
mlxsw: spectrum: Add missing rollback in flood configuration
Imre Deak (1):
drm/i915/bdw: Add missing delay during L3 SQC credit programming
Ingo Molnar (3):
MAINTAINERS: Add mmiotrace entry
Revert "sched/fair: Fix fairness issue on migration"
Merge tag 'perf-urgent-for-mingo-20160512' of git://git.kernel.org/.../acme/linux into perf/urgent
Iyappan Subramanian (5):
drivers: net: xgene: fix IPv4 forward crash
drivers: net: xgene: fix sharing of irqs
drivers: net: xgene: fix ununiform latency across queues
drivers: net: xgene: fix statistics counters race condition
drivers: net: xgene: fix register offset
Jack Pham (1):
regmap: spmi: Fix regmap_spmi_ext_read in multi-byte case
Jamal Hadi Salim (7):
export tc ife uapi header
net sched: vlan action fix late binding
net sched: ipt action fix late binding
net sched: mirred action fix late binding
net sched: simple action fix late binding
net sched: skbedit action fix late binding
net sched: ife action fix late binding
Jani Nikula (1):
drm/i915/lvds: separate border enable readout from panel fitter
Jarkko Nikula (1):
spi: pxa2xx: Do not detect number of enabled chip selects on Intel SPT
Jarno Rajahalme (2):
udp_tunnel: Remove redundant udp_tunnel_gro_complete().
udp_offload: Set encapsulation before inner completes.
Jeeja KP (1):
ASoC: topology: Fix memory leak in widget creation
Jeremy McDermond (7):
ASoC: tlv320aic32x4: Change name of probe function
ASoC: tlv320aic32x4: Break out I2C support into separate module
ASoC: tlv320aic32x4: Add SPI support
ASoC: tlv320aic32x4: Add 96k sample rate
ASoC: tlv320aic32x4: Implement resistors on input pins
ASoC: tlv320aic32x4: Add additional input pins
ASoC: tlv320aic32x4: Properly implement the positive and negative pins into the mixers
Jim Lodes (1):
ASoC: omap-pcm: Initialize DMA configuration
Jiri Benc (1):
gre: do not keep the GRE header around in collect medata mode
Joe Stringer (1):
openvswitch: Fix cached ct with helper.
Johannes Thumshirn (1):
qla1280: Don't allocate 512kb of host tags
Josh Poimboeuf (2):
compiler-gcc: require gcc 4.8 for powerpc __builtin_bswap16()
x86/kvm: Add stack frame dependency to fastop() inline asm
Junxiao Bi (2):
ocfs2: revert using ocfs2_acl_chmod to avoid inode cluster lock hang
ocfs2: fix posix_acl_create deadlock
Kaho Ng (1):
ALSA: hda - Fix white noise on Asus UX501VW headset
Kalle Valo (1):
Merge tag 'iwlwifi-for-kalle-2016-05-04' of https://git.kernel.org/.../iwlwifi/iwlwifi-fixes
Kangjie Lu (3):
net: fix infoleak in llc
net: fix infoleak in rtnetlink
net: fix a kernel infoleak in x25 module
Koro Chen (1):
ASoC: mediatek: Add HDMI dai-links in the mt8173-rt5650-rt5676 machine driver
Krzysztof Kozlowski (1):
regulator: s2mps11: Fix invalid selector mask and voltages for buck9
Kuninori Morimoto (3):
ASoC: tidyup alphabetical order for SND_SOC_Bxx
ASoC: rsnd: count .probe/.remove for rsnd_mod_call()
ASoC: rsnd: don't use prohibited number to PDMACHCRn.SRS
Linus Lüssing (1):
bridge: fix igmp / mld query parsing
Linus Torvalds (31):
Merge git://git.kernel.org/.../davem/net
Merge branch 'linus' of git://git.kernel.org/.../herbert/crypto-2.6
Merge branch 'akpm' (patches from Andrew)
Merge branch 'libnvdimm-fixes' of git://git.kernel.org/.../nvdimm/nvdimm
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/.../tip/tip
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/.../tip/tip
Merge tag 'pci-v4.6-fixes-3' of git://git.kernel.org/.../helgaas/pci
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Merge tag 'spi-fix-v4.6-rc7' of git://git.kernel.org/.../broonie/spi
Merge git://git.kernel.org/.../davem/net
Merge tag 'scsi-fixes' of git://git.kernel.org/.../jejb/scsi
Merge tag 'pinctrl-v4.6-4' of git://git.kernel.org/.../linusw/linux-pinctrl
Merge branch 'for-linus' of git://git.kernel.org/.../dtor/input
Merge tag 'sound-4.6' of git://git.kernel.org/.../tiwai/sound
Merge tag 'keys-fixes-20160512' of git://git.kernel.org/.../dhowells/linux-fs
Merge branch 'akpm' (patches from Andrew)
Merge branch 'linus' of git://git.kernel.org/.../herbert/crypto-2.6
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Merge tag 'media/v4.6-6' of git://git.kernel.org/.../mchehab/linux-media
Merge tag 'regmap-fix-v4.6-rc7' of git://git.kernel.org/.../broonie/regmap
Merge tag 'regulator-fix-v4.6-rc7' of git://git.kernel.org/.../broonie/regulator
Merge tag 'fixes-for-linus' of git://git.kernel.org/.../arm/arm-soc
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/.../tip/tip
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/.../tip/tip
Merge branch 'for-4.6-fixes' of git://git.kernel.org/.../tj/wq
Merge branch 'for-4.6-fixes' of git://git.kernel.org/.../tj/cgroup
Merge branch 'for-linus' of git://git.kernel.org/.../viro/vfs
nf_conntrack: avoid kernel pointer value leak in slab name
Merge git://git.kernel.org/.../davem/net
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/.../tip/tip
Linux 4.6
Liping Zhang (1):
netfilter: IDLETIMER: fix race condition when destroy the target
Lucas Stach (1):
drm/radeon: fix PLL sharing on DCE6.1 (v2)
Ludovic Desroches (1):
pinctrl: at91-pio4: fix pull-up/down logic
Lukas Wunner (2):
PCI: Fix BUG on device attach failure
PCI: Do not treat EPROBE_DEFER as device attach failure
Lyude (1):
Revert "drm/i915: start adding dp mst audio"
Marek Szyprowski (1):
Input: max8997-haptic - fix NULL pointer dereference
Mark Brown (31):
regmap: mmio: Fix value endianness selection
regmap: Fix implicit inclusion of device.h
regmap: mmio: Parse endianness definitions from DT
ASoC: wm8960: Depends on I2C
regmap: mmio: Explicitly say little endian is the defualt in the bus config
Merge branches 'topic/dai-link' and 'topic/find-dai' of git://git.kernel.org/.../broonie/sound into asoc-topology
Merge remote-tracking branches 'spi/fix/fsl-dspi', 'spi/fix/omap2-mcspi', 'spi/fix/pxa2xx' and 'spi/fix/ti-qspi' into spi-linus
Merge remote-tracking branch 'regmap/fix/mmio' into regmap-linus
Merge remote-tracking branches 'regmap/fix/be', 'regmap/fix/doc' and 'regmap/fix/spmi' into regmap-linus
Merge remote-tracking branches 'regulator/fix/axp20x', 'regulator/fix/da9063', 'regulator/fix/gpio' and 'regulator/fix/s2mps11' into regulator-linus
ASoC: ak4642: Enable cache usage to fix crashes on resume
Merge tag 'asoc-v4.7' into asoc-linus
Merge remote-tracking branches 'asoc/fix/ak4642', 'asoc/fix/ep93xx', 'asoc/fix/kirkwood' and 'asoc/fix/twl6040' into asoc-linus
Merge remote-tracking branch 'asoc/topic/tlv320aic32x4' into asoc-next
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
Merge remote-tracking branch 'asoc/topic/max98371' into asoc-next
Merge remote-tracking branch 'asoc/topic/twl6040' into asoc-next
Merge remote-tracking branch 'asoc/topic/simple' into asoc-next
Merge remote-tracking branch 'asoc/topic/pxa' into asoc-next
Merge remote-tracking branch 'asoc/topic/topology' into asoc-next
Merge remote-tracking branch 'asoc/topic/tas5270' into asoc-next
Merge remote-tracking branch 'asoc/topic/omap' into asoc-next
Merge remote-tracking branch 'asoc/topic/mtk' into asoc-next
Merge remote-tracking branch 'asoc/topic/rt298' into asoc-next
Merge remote-tracking branch 'asoc/topic/kconfig' into asoc-next
Merge remote-tracking branch 'asoc/topic/tlv320aic31xx' into asoc-next
Merge remote-tracking branch 'asoc/topic/sti' into asoc-next
Merge remote-tracking branch 'asoc/topic/qcom' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8960' into asoc-next
Merge remote-tracking branch 'asoc/topic/rt5677' into asoc-next
Merge remote-tracking branch 'asoc/topic/wm8962' into asoc-next
Mathias Krause (1):
x86/extable: ensure entries are swapped completely when sorting
Matthias Brugger (1):
drivers: net: xgene: Fix error handling
Mauro Carvalho Chehab (1):
Revert "[media] videobuf2-v4l2: Verify planes array in buffer dequeueing"
Maxime Ripard (1):
regulator: axp20x: Fix LDO4 linear voltage range
Mengdong Lin (4):
ASoC: topology: ABI - Define types for vendor tuples
ASoC: topology: Set the link ID when creating a FE DAI link
ASoC: topology: Check failure to create a widget
ASoC: topology: Check size mismatch of ABI objects before parsing
Michael Chan (4):
bnxt_en: Need memory barrier when processing the completion ring.
bnxt_en: Setup multicast properly after resetting device.
bnxt_en: Add workaround to detect bad opaque in rx completion (part 1)
bnxt_en: Add workaround to detect bad opaque in rx completion (part 2)
Mihai Mihalache (1):
regulator: gpio: check return value of of_get_named_gpio
Mikko Rapeli (1):
uapi glibc compat: fix compile errors when glibc net/if.h included before linux/if.h
Miklos Szeredi (4):
vfs: add vfs_select_inode() helper
vfs: rename: check backing inode being equal
vfs: add lookup_hash() helper
ovl: ignore permissions on underlying lookup
Moise Gergaud (10):
ASoC: sti: correct typo errors
ASoC: sti: macro for uniperif tdm regs access
ASoC: sti: rename unip player type into common player & reader type
ASoC: sti: define tdm type & default tdm hw config
ASoC: sti: helper functions for unip tdm slots configuration
ASoC: sti: helper functions to fix tdm runtime params
ASoC: sti: unip player tdm mode
ASoC: sti: unip reader tdm mode
ASoC: sti: select player for I2S/TDM TX bus
ASoC: sti-asoc-card: update tdm mode
Namhyung Kim (1):
perf diff: Fix duplicated output column
Nikolay Aleksandrov (1):
net: bridge: fix old ioctl unlocked net device walk
PC Liao (2):
ASoC: mediatek: Add second I2S on mt8173-rt5650 machine driver
ASoC: mediatek: HDMI audio LR channel swapped
Paolo Abeni (1):
net/route: enforce hoplimit max value
Paul Durrant (1):
xen-netback: fix extra_info handling in xenvif_tx_err()
Peter Ujfalusi (4):
ASoC: omap-mcbsp: Enable/disable sidetone block auto clock gating for omap3
ASoC: simple-card: Add pm callbacks to platform driver
ASoC: twl6040: Select LPPLL during standby
ASoC: twl6040: Disconnect AUX output pads on digital mute
Peter Zijlstra (1):
perf/x86/msr: Fix SMI overflow
Petr Kulhavy (5):
ASoC: tas571x: implemented digital mute
ASoC: tas571x: chip type detection via I2C name
ASoC: tas571x: added missing register literals
ASoC: tas571x: added support for TAS5721
ASoC: tas571x: new chip added into TAS571x binding
Phil Turnbull (1):
netfilter: nfnetlink_acct: validate NFACCT_QUOTA parameter
Rafael J. Wysocki (1):
sched/fair: Fix !CONFIG_SMP kernel cpufreq governor breakage
Robin Humble (1):
Revert "proc/base: make prompt shell start from new line after executing "cat /proc/$pid/wchan""
Sabrina Dubroca (1):
macsec: key identifier is 128 bits, not 64
Serge E. Hallyn (2):
cgroup, kernfs: make mountinfo show properly scoped path for cgroup namespaces
kernfs: kernfs_sop_show_path: don't return 0 after seq_dentry call
Serge Hallyn (1):
kernfs_path_from_node_locked: don't overwrite nlen
Sergei Shtylyov (1):
rcar: src: skip disabled-SRC nodes
Sergey Senozhatsky (1):
zsmalloc: fix zs_can_compact() integer overflow
Shaohui Xie (1):
net: phylib: fix interrupts re-enablement in phy_start
Shmulik Ladkani (1):
Documentation/networking: more accurate LCO explanation
Srinivas Kandagatla (2):
ASoC: qcom: Fix uninitialized symbol warning.
ASoC: qcom: remove IS_ERR_VALUE usage on int.
Steffen Klassert (3):
flowcache: Avoid OOM condition under preasure
xfrm: Reset encapsulation field of the skb before transformation
vti: Add pmtu handling to vti_xmit.
Stephen Boyd (1):
ASoC: rsnd: Remove CLK_IS_ROOT
Steven Rostedt (1):
tools lib traceevent: Do not reassign parg after collapse_tree()
Sudarsana Reddy Kalluru (1):
qede: prevent chip hang when increasing channels
Sudip Mukherjee (1):
ASoC: kirkwood: fix build failure
Suzuki K Poulose (1):
arm64/sunxi: 4.6-rc1: Add dependency on generic irq chip
Tadeusz Struk (3):
crypto: qat - fix invalid pf2vf_resp_wq logic
crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq
crypto: rsa - select crypto mgr dependency
Takashi Iwai (4):
ALSA: usb-audio: Quirk for yet another Phoenix Audio devices (v2)
ALSA: hda - Fix broken reconfig
ALSA: hda - Fix regression on ATI HDMI audio
ALSA: usb-audio: Yet another Phoneix Audio device quirk
Thomas Gleixner (2):
x86/topology: Handle CPUID bogosity gracefully
x86/topology: Set x86_max_cores to 1 for CONFIG_SMP=n
Uwe Kleine-König (1):
net: fec: only clear a queue's work bit if the queue was emptied
Ville Syrjälä (1):
drm/i915: Update CDCLK_FREQ register on BDW after changing cdclk frequency
Wanpeng Li (1):
workqueue: fix rebind bound workers warning
Wenyou Yang (1):
ARM: dts: at91: sama5d2: use "atmel,sama5d3-nfc" compatible for nfc
Xunlei Pang (1):
sched/rt, sched/dl: Don't push if task's scheduling class was changed
Yura Pakhuchiy (1):
ALSA: hda - Fix subwoofer pin on ASUS N751 and N551
Zhou Chengming (1):
ksm: fix conflict between mmput and scan_get_next_rmap_item
Zi Shen Lim (1):
arm64: bpf: jit JMP_JSET_{X,K}
anish kumar (1):
ASoC: Add max98371 codec driver
hchrzani (1):
perf/x86/intel/uncore: Fix CHA registers configuration procedure for Knights Landing platform
xypron.glpk(a)gmx.de (1):
net: thunderx: avoid exposing kernel stack
.../devicetree/bindings/regmap/regmap.txt | 59 +-
.../devicetree/bindings/sound/max98371.txt | 17 +
.../bindings/sound/mt8173-rt5650-rt5676.txt | 5 +-
.../devicetree/bindings/sound/mt8173-rt5650.txt | 10 +
.../devicetree/bindings/sound/st,sti-asoc-card.txt | 48 +-
.../devicetree/bindings/sound/tas571x.txt | 10 +-
.../devicetree/bindings/sound/tas5720.txt | 25 +
Documentation/networking/checksum-offloads.txt | 14 +-
Documentation/sysctl/kernel.txt | 2 +-
MAINTAINERS | 14 +
Makefile | 2 +-
arch/arm/boot/dts/at91sam9x5.dtsi | 2 +-
arch/arm/boot/dts/sama5d2.dtsi | 2 +-
arch/arm64/Kconfig.platforms | 1 +
arch/arm64/net/bpf_jit_comp.c | 1 +
arch/x86/configs/kvm_guest.config | 3 +
arch/x86/entry/syscalls/syscall_32.tbl | 4 +-
arch/x86/events/intel/core.c | 2 +-
arch/x86/events/intel/pt.c | 2 +
arch/x86/events/intel/uncore_snbep.c | 7 +
arch/x86/events/msr.c | 2 +-
arch/x86/include/asm/uaccess.h | 8 +
arch/x86/kernel/cpu/intel.c | 2 +-
arch/x86/kernel/smpboot.c | 5 +
arch/x86/kvm/emulate.c | 6 +-
block/blk-map.c | 47 +-
crypto/Kconfig | 1 +
crypto/ahash.c | 3 +-
crypto/testmgr.c | 27 +-
drivers/base/regmap/internal.h | 1 +
drivers/base/regmap/regmap-mmio.c | 5 +-
drivers/base/regmap/regmap-spmi.c | 2 +-
drivers/crypto/qat/qat_common/adf_common_drv.h | 11 +
drivers/crypto/qat/qat_common/adf_ctl_drv.c | 6 +
drivers/crypto/qat/qat_common/adf_sriov.c | 26 +-
drivers/gpu/drm/amd/amdgpu/atombios_dp.c | 4 +-
drivers/gpu/drm/i915/i915_debugfs.c | 16 -
drivers/gpu/drm/i915/i915_reg.h | 2 +
drivers/gpu/drm/i915/intel_audio.c | 9 +-
drivers/gpu/drm/i915/intel_crt.c | 8 +-
drivers/gpu/drm/i915/intel_ddi.c | 24 +-
drivers/gpu/drm/i915/intel_display.c | 5 +-
drivers/gpu/drm/i915/intel_dp_mst.c | 22 -
drivers/gpu/drm/i915/intel_drv.h | 2 -
drivers/gpu/drm/i915/intel_lvds.c | 4 +
drivers/gpu/drm/i915/intel_pm.c | 6 +
drivers/gpu/drm/radeon/atombios_crtc.c | 10 +
drivers/gpu/drm/radeon/atombios_dp.c | 4 +-
drivers/gpu/drm/radeon/radeon_dp_auxch.c | 2 +-
drivers/input/misc/max8997_haptic.c | 6 +-
drivers/input/misc/twl6040-vibra.c | 1 +
drivers/input/mouse/byd.c | 4 +
drivers/media/v4l2-core/videobuf2-v4l2.c | 6 -
drivers/net/ethernet/apm/xgene/xgene_enet_cle.c | 11 +-
drivers/net/ethernet/apm/xgene/xgene_enet_cle.h | 2 +
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 19 +-
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 8 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 82 ++-
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 18 +-
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 86 ++-
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +
drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 4 +
drivers/net/ethernet/ezchip/nps_enet.c | 30 +-
drivers/net/ethernet/ezchip/nps_enet.h | 2 -
drivers/net/ethernet/freescale/fec_main.c | 10 +-
drivers/net/ethernet/marvell/Kconfig | 2 +-
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 8 +-
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 3 +-
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 +
drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | 11 +-
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 +-
.../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 8 +
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 14 +-
.../net/ethernet/qlogic/netxen/netxen_nic_main.c | 3 +-
drivers/net/ethernet/qlogic/qede/qede_main.c | 8 +-
.../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | 8 +-
drivers/net/ethernet/renesas/ravb_main.c | 2 +
drivers/net/geneve.c | 5 +-
drivers/net/macsec.c | 19 +-
drivers/net/macvtap.c | 2 +-
drivers/net/phy/phy.c | 8 +-
drivers/net/vxlan.c | 5 +-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 83 +--
drivers/net/xen-netback/netback.c | 1 +
drivers/nvdimm/pmem.c | 4 +-
drivers/pci/bus.c | 6 +-
drivers/pinctrl/pinctrl-at91-pio4.c | 2 +
drivers/regulator/axp20x-regulator.c | 12 +-
drivers/regulator/da9063-regulator.c | 2 +-
drivers/regulator/gpio-regulator.c | 2 +
drivers/regulator/s2mps11.c | 28 +-
drivers/scsi/device_handler/scsi_dh_alua.c | 1 +
drivers/scsi/qla1280.c | 2 +-
drivers/spi/spi-ep93xx.c | 2 +-
drivers/spi/spi-fsl-dspi.c | 4 +-
drivers/spi/spi-omap2-mcspi.c | 62 ++-
drivers/spi/spi-pxa2xx.c | 2 +-
drivers/spi/spi-ti-qspi.c | 45 +-
fs/ecryptfs/file.c | 71 ++-
fs/isofs/rock.c | 13 +-
fs/kernfs/dir.c | 6 +-
fs/kernfs/mount.c | 15 +
fs/namei.c | 59 +-
fs/ocfs2/acl.c | 87 +++
fs/ocfs2/acl.h | 5 +
fs/ocfs2/file.c | 4 +-
fs/ocfs2/namei.c | 23 +-
fs/ocfs2/refcounttree.c | 17 +-
fs/ocfs2/xattr.c | 14 +-
fs/ocfs2/xattr.h | 4 +-
fs/open.c | 12 +-
fs/overlayfs/super.c | 4 +-
fs/proc/base.c | 2 +-
fs/splice.c | 3 +
include/linux/compiler-gcc.h | 2 +-
include/linux/dcache.h | 12 +
include/linux/kernfs.h | 2 +
include/linux/mfd/samsung/s2mps11.h | 2 +
include/linux/mfd/twl6040.h | 1 +
include/linux/mm.h | 9 +
include/linux/namei.h | 2 +
include/linux/netdevice.h | 3 +
include/linux/swap.h | 6 +-
include/linux/uio.h | 1 +
include/net/netns/xfrm.h | 1 +
include/net/udp_tunnel.h | 9 -
include/uapi/linux/if.h | 28 +
include/uapi/linux/if_macsec.h | 4 +-
include/uapi/linux/libc-compat.h | 44 ++
include/uapi/linux/tc_act/Kbuild | 1 +
include/uapi/sound/asoc.h | 44 +-
kernel/cgroup.c | 63 +++
kernel/events/core.c | 2 +-
kernel/events/ring_buffer.c | 10 +-
kernel/sched/deadline.c | 1 +
kernel/sched/fair.c | 29 +-
kernel/sched/rt.c | 1 +
kernel/workqueue.c | 11 +
lib/asn1_decoder.c | 16 +-
lib/iov_iter.c | 19 +
mm/huge_memory.c | 71 ++-
mm/ksm.c | 15 +-
mm/memory.c | 22 +-
mm/swapfile.c | 13 +-
mm/zsmalloc.c | 7 +-
net/bridge/br_ioctl.c | 5 +-
net/bridge/br_multicast.c | 12 +-
net/core/flow.c | 14 +-
net/core/rtnetlink.c | 18 +-
net/ipv4/fib_semantics.c | 2 +
net/ipv4/fou.c | 6 +-
net/ipv4/ip_gre.c | 7 +-
net/ipv4/ip_vti.c | 18 +
net/ipv4/tcp_output.c | 6 +-
net/ipv4/udp_offload.c | 8 +-
net/ipv6/icmp.c | 5 +-
net/ipv6/route.c | 2 +
net/ipv6/tcp_ipv6.c | 7 +-
net/llc/af_llc.c | 1 +
net/netfilter/nf_conntrack_core.c | 6 +-
net/netfilter/nfnetlink_acct.c | 2 +
net/netfilter/xt_IDLETIMER.c | 1 +
net/openvswitch/conntrack.c | 13 +
net/sched/act_ife.c | 14 +-
net/sched/act_ipt.c | 19 +-
net/sched/act_mirred.c | 19 +-
net/sched/act_simple.c | 18 +-
net/sched/act_skbedit.c | 18 +-
net/sched/act_vlan.c | 22 +-
net/vmw_vsock/af_vsock.c | 21 +-
net/x25/x25_facilities.c | 1 +
net/xfrm/xfrm_output.c | 3 +
sound/pci/hda/hda_sysfs.c | 8 -
sound/pci/hda/patch_hdmi.c | 7 +-
sound/pci/hda/patch_realtek.c | 13 +
sound/soc/codecs/Kconfig | 38 +-
sound/soc/codecs/Makefile | 11 +-
sound/soc/codecs/ak4642.c | 3 +
sound/soc/codecs/hdac_hdmi.c | 1 -
sound/soc/codecs/max98371.c | 441 +++++++++++++++
sound/soc/codecs/max98371.h | 67 +++
sound/soc/codecs/rt298.c | 51 +-
sound/soc/codecs/rt298.h | 2 +
sound/soc/codecs/rt5677.c | 24 +-
sound/soc/codecs/tas571x.c | 141 ++++-
sound/soc/codecs/tas571x.h | 22 +
sound/soc/codecs/tas5720.c | 620 +++++++++++++++++++++
sound/soc/codecs/tas5720.h | 90 +++
sound/soc/codecs/tlv320aic31xx.c | 10 +
sound/soc/codecs/tlv320aic32x4-i2c.c | 74 +++
sound/soc/codecs/tlv320aic32x4-spi.c | 76 +++
sound/soc/codecs/tlv320aic32x4.c | 279 +++++++---
sound/soc/codecs/tlv320aic32x4.h | 7 +
sound/soc/codecs/twl6040.c | 16 +-
sound/soc/codecs/wm8962.c | 9 +-
sound/soc/codecs/wm8962.h | 6 +-
sound/soc/generic/simple-card.c | 1 +
sound/soc/kirkwood/Kconfig | 1 +
sound/soc/mediatek/Kconfig | 1 +
sound/soc/mediatek/mt8173-rt5650-rt5676.c | 27 +
sound/soc/mediatek/mt8173-rt5650.c | 50 +-
sound/soc/mediatek/mtk-afe-pcm.c | 2 +
sound/soc/omap/mcbsp.c | 8 +
sound/soc/omap/omap-pcm.c | 2 +
sound/soc/pxa/brownstone.c | 1 +
sound/soc/pxa/mioa701_wm9713.c | 1 +
sound/soc/pxa/mmp-pcm.c | 1 +
sound/soc/pxa/mmp-sspa.c | 1 +
sound/soc/pxa/palm27x.c | 1 +
sound/soc/pxa/pxa-ssp.c | 1 +
sound/soc/pxa/pxa2xx-ac97.c | 1 +
sound/soc/pxa/pxa2xx-pcm.c | 1 +
sound/soc/qcom/lpass-platform.c | 8 +-
sound/soc/sh/rcar/adg.c | 8 +-
sound/soc/sh/rcar/dma.c | 12 +-
sound/soc/sh/rcar/rsnd.h | 13 +-
sound/soc/sh/rcar/src.c | 4 +
sound/soc/soc-topology.c | 48 +-
sound/soc/sti/sti_uniperif.c | 144 ++++-
sound/soc/sti/uniperif.h | 220 +++++++-
sound/soc/sti/uniperif_player.c | 182 ++++--
sound/soc/sti/uniperif_reader.c | 229 ++++++--
sound/usb/quirks.c | 3 +
tools/build/Makefile.feature | 2 +
tools/build/feature/Makefile | 4 +
tools/build/feature/test-all.c | 5 +
tools/build/feature/test-dwarf_getlocations.c | 12 +
tools/lib/traceevent/parse-filter.c | 4 +-
tools/net/bpf_jit_disasm.c | 3 +
tools/perf/arch/x86/util/dwarf-regs.c | 8 +-
tools/perf/builtin-script.c | 70 ++-
tools/perf/builtin-stat.c | 7 +-
tools/perf/config/Makefile | 6 +
tools/perf/util/dwarf-aux.c | 9 +
tools/perf/util/event.c | 12 +-
tools/perf/util/evsel.c | 23 +-
tools/perf/util/parse-events.c | 60 +-
tools/perf/util/sort.c | 3 +
tools/perf/util/thread_map.c | 8 +-
242 files changed, 4385 insertions(+), 1065 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/max98371.txt
create mode 100644 Documentation/devicetree/bindings/sound/tas5720.txt
create mode 100644 sound/soc/codecs/max98371.c
create mode 100644 sound/soc/codecs/max98371.h
create mode 100644 sound/soc/codecs/tas5720.c
create mode 100644 sound/soc/codecs/tas5720.h
create mode 100644 sound/soc/codecs/tlv320aic32x4-i2c.c
create mode 100644 sound/soc/codecs/tlv320aic32x4-spi.c
create mode 100644 tools/build/feature/test-dwarf_getlocations.c
2
2
[alsa-devel] [PATCH 00/14] clk/mfd/ASoC/ARM: OMAP4/5: McPDM/twl6040 pdmclk support
by Peter Ujfalusi 27 May '16
by Peter Ujfalusi 27 May '16
27 May '16
Hi,
this is something I wanted to do for a long time...
First of all: sorry for the cross domain series. I did tested alone all the
domain patches and they are not causing any regression. When they come together
we will have ability to control the pdmclk needed by McPDM.
CLK patches:
The driver was w/o DT support and needed some cleanup so we can use the driver.
I have also renamed it to twl6040-pdmclk from twl6040-clk to be precise.
MFD patches:
The regmap_sync() was not working since the twl6040 does not support bulk access
and now we are going to create the needed child for the pdmclk.
ARM patches:
Updatding the board DTS files and add the needed lines for the pdmclk.
ASoC patches:
The machine driver needs to select the twl6040-clk driver as it will be used
by the omap-mcpdm.
I needed to do some cleanup and add also suspend/resume support before adding
the code for pdmclk handling since I don't want to keep the twl6040 powered on
when the board is suspended. At the moment it is not possible to do true
dynamic twl6040 power up/down due to pop noises, but I will be looking at that
later.
The driver in the future will fail if it is not able to get the pdmclk to avoid
kernel crash (McPDM registers are not accessible when pdmclk is not available).
I have tested the patches by domain and also in all (I hope) permutation they
could be. I have not experienced any regression.
Regards,
Peter
---
Peter Ujfalusi (14):
clk: twl6040: Correct clk_ops
clk: twl6040: Register the clock as of_clk_provider
clk: twl6040: Rename the driver and use consistent names in the code
mfd: twl6040: The chip does not support bulk access
mfd: twl6040: Register child device for twl6040-pdmclk
ARM: dts: omap5-board-common: Add pdmclk binding for audio
ARM: dts: omap4-panda-common: Add pdmclk binding for audio
ARM: dts: omap4-sdp: Add pdmclk binding for audio
ARM: dts: omap4-var-som-om44: Add pdmclk binding for audio
ARM: dts: omap4-duovero: Add pdmclk binding for audio
ASoC: omap: Kconfig: SND_OMAP_SOC_OMAP_ABE_TWL6040 to select
CLK_TWL6040
ASoC: omap-mcpdm: Move the WD enable write inside
omap_mcpdm_open_streams()
ASoC: omap-mcpdm: Support for suspend resume
ASoC: omap-mcpdm: Add support for pdmclk clock handling
Documentation/devicetree/bindings/mfd/twl6040.txt | 1 +
.../devicetree/bindings/sound/omap-mcpdm.txt | 10 +++
arch/arm/boot/dts/omap4-duovero.dtsi | 5 ++
arch/arm/boot/dts/omap4-panda-common.dtsi | 5 ++
arch/arm/boot/dts/omap4-sdp.dts | 5 ++
arch/arm/boot/dts/omap4-var-som-om44.dtsi | 5 ++
arch/arm/boot/dts/omap5-board-common.dtsi | 5 ++
drivers/clk/clk-twl6040.c | 80 +++++++++++++---------
drivers/mfd/twl6040.c | 6 ++
include/linux/mfd/twl6040.h | 2 +-
sound/soc/omap/Kconfig | 1 +
sound/soc/omap/omap-mcpdm.c | 74 ++++++++++++++++++--
12 files changed, 160 insertions(+), 39 deletions(-)
--
2.8.2
3
17
[alsa-devel] [PATCH v4 0/7] ARM/ASoC: OMAP3: Fix McBSP2/3 sidetone support
by Peter Ujfalusi 27 May '16
by Peter Ujfalusi 27 May '16
27 May '16
Hi,
Changes since v3:
- Rebased on next-20160525 [1] to apply cleanly
- Fixed subject line for patch5
- Added Mark's acked-by to the ASoC patches
[1] "ASoC: omap-mcbsp: Enable/disable sidetone block auto clock
gating for omap3" is gone missing from linux-next - it was in next-20160517 and
I'm not sure when it got dropped.
Tony: since Paul did not replied to the series, I'm sending the v4 now, I hope
he will have time to look at this.
Commit message from v3:
Based on the ongoing discussion on v2 (ARM: OMAP3: Fix McBSP2/3 hwmod setup for
sidetone) I have dropped the removal of the sidetone hwmod and only corrected
it. The series now includes all related changes needed to have correct sidetone
support whenever we boot in legacy or in DT mode.
This time the ASoC part have dependency on earlier patches so they can not be
applied separately.
Regards,
Peter
---
Peter Ujfalusi (7):
ARM: OMAP3: hwmod data: Fix McBSP2/3 sidetone data
ARM: dts: omap3: Add clocks to McBSP nodes
ARM: OMAP3: McBSP: New callback for McBSP2/3 ICLK idle configuration
ARM: OMAP3: pdata-quirks: Add support for McBSP2/3 sidetone handling
ASoC: omap-mcbsp: Rename omap_mcbsp_sysfs_remove() to
omap_mcbsp_cleanup()
ASoC: omap-mcbsp: sidetone: Use the new callback for iclk handling
ARM: OMAP2+: McBSP: Remove the old iclk allow/deny idle code
arch/arm/boot/dts/omap3.dtsi | 10 ++++++++++
arch/arm/mach-omap2/mcbsp.c | 31 ++++++++++++++++-------------
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 24 ++++------------------
arch/arm/mach-omap2/pdata-quirks.c | 18 +++++++++++++++++
include/linux/platform_data/asoc-ti-mcbsp.h | 4 +++-
sound/soc/omap/mcbsp.c | 21 +++++++++++++------
sound/soc/omap/mcbsp.h | 3 ++-
sound/soc/omap/omap-mcbsp.c | 5 ++++-
8 files changed, 73 insertions(+), 43 deletions(-)
--
2.8.2
2
8
[alsa-devel] [PATCH v4 0/7] ARM/ASoC: OMAP3: Fix McBSP2/3 sidetone support
by Peter Ujfalusi 27 May '16
by Peter Ujfalusi 27 May '16
27 May '16
Hi,
Changes since v3:
- Rebased on next-20160525 [1] to apply cleanly
- Fixed subject line for patch5
- Added Mark's acked-by to the ASoC patches
[1] "ASoC: omap-mcbsp: Enable/disable sidetone block auto clock
gating for omap3" is gone missing from linux-next - it was in next-20160517 and
I'm not sure when it got dropped.
Tony: since Paul did not replied to the series, I'm sending the v4 now, I hope
he will have time to look at this.
Commit message from v3:
Based on the ongoing discussion on v2 (ARM: OMAP3: Fix McBSP2/3 hwmod setup for
sidetone) I have dropped the removal of the sidetone hwmod and only corrected
it. The series now includes all related changes needed to have correct sidetone
support whenever we boot in legacy or in DT mode.
This time the ASoC part have dependency on earlier patches so they can not be
applied separately.
Regards,
Peter
---
Peter Ujfalusi (7):
ARM: OMAP3: hwmod data: Fix McBSP2/3 sidetone data
ARM: dts: omap3: Add clocks to McBSP nodes
ARM: OMAP3: McBSP: New callback for McBSP2/3 ICLK idle configuration
ARM: OMAP3: pdata-quirks: Add support for McBSP2/3 sidetone handling
ASoC: omap-mcbsp: Rename omap_mcbsp_sysfs_remove() to
omap_mcbsp_cleanup()
ASoC: omap-mcbsp: sidetone: Use the new callback for iclk handling
ARM: OMAP2+: McBSP: Remove the old iclk allow/deny idle code
arch/arm/boot/dts/omap3.dtsi | 10 ++++++++++
arch/arm/mach-omap2/mcbsp.c | 31 ++++++++++++++++-------------
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 24 ++++------------------
arch/arm/mach-omap2/pdata-quirks.c | 18 +++++++++++++++++
include/linux/platform_data/asoc-ti-mcbsp.h | 4 +++-
sound/soc/omap/mcbsp.c | 21 +++++++++++++------
sound/soc/omap/mcbsp.h | 3 ++-
sound/soc/omap/omap-mcbsp.c | 5 ++++-
8 files changed, 73 insertions(+), 43 deletions(-)
--
2.8.2
2
5
[alsa-devel] [PATCH v2] ASoC: mediatek: Change the order of MCLK clock configuration
by PC Liao 27 May '16
by PC Liao 27 May '16
27 May '16
Because MCLK turns on later and turns off earlier than codec, this patch
changes the order of MCLK clock configuration.
Signed-off-by: PC Liao <pc.liao(a)mediatek.com>
---
Changes since v1:
update commit message
---
sound/soc/mediatek/mtk-afe-pcm.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index f1c58a2..440ae06 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -360,8 +360,6 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream,
if (dai->active)
return 0;
- mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
- mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
return 0;
@@ -380,8 +378,6 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream,
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
- mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
- mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
}
static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
@@ -1132,6 +1128,8 @@ static int mtk_afe_runtime_suspend(struct device *dev)
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
+ clk_disable_unprepare(afe->clocks[MTK_CLK_I2S1_M]);
+ clk_disable_unprepare(afe->clocks[MTK_CLK_I2S2_M]);
clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]);
clk_disable_unprepare(afe->clocks[MTK_CLK_BCK1]);
clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]);
@@ -1164,6 +1162,12 @@ static int mtk_afe_runtime_resume(struct device *dev)
ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK1]);
if (ret)
goto err_bck0;
+ ret = clk_prepare_enable(afe->clocks[MTK_CLK_I2S1_M]);
+ if (ret)
+ goto err_i2s1_m;
+ ret = clk_prepare_enable(afe->clocks[MTK_CLK_I2S2_M]);
+ if (ret)
+ goto err_i2s2_m;
/* enable AFE clk */
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, 0);
@@ -1179,6 +1183,10 @@ static int mtk_afe_runtime_resume(struct device *dev)
regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
return 0;
+err_i2s1_m:
+ clk_disable_unprepare(afe->clocks[MTK_CLK_I2S1_M]);
+err_i2s2_m:
+ clk_disable_unprepare(afe->clocks[MTK_CLK_I2S2_M]);
err_bck0:
clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]);
err_top_aud:
--
1.7.9.5
1
0
27 May '16
Hi all
This series patch is for rockchip Type-C phy and DisplayPort controller
driver.
The USB Type-C PHY is designed to support the USB3 and DP applications.
The PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and HBR2
data rates. The Type-C cable orientation detection and Power Delivery
(PD) is accomplished using a PD PHY or a exernal PD chip.
The DP controller is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work, please
put the firmware file to /lib/firmware/cdn/dptx.bin. The uCPU in charge
of aux communication and link training, the host use mailbox to
communicate with the ucpu.
The PHY driver has register a notification, to get the alt mode from PD,
the PD driver need call the tcphy_notifier_call_chain to notify PHY and
DP controller.
This series is based on Mark Yao's branch:
https://github.com/markyzq/kernel-drm-rockchip/tree/drm-rockchip-next-2016-…
I test this patches on the rk3399-evb board, with a fusb302 driver,
this branch has no rk3399.dtsi, so the patch about dts is not included
in this series.
Chris Zhong (6):
phy: Add USB Type-C PHY driver for rk3399
Documentation: bindings: add dt doc for Rockchip USB Type-C PHY
drm/rockchip: vop: add cdn DP support for rk3399
Documentation: bindings: add dt documentation for cdn DP controller
ASoC: cdn-dp: Add cdn DP codec driver
ASoC: rockchip: Add machine driver for cdn dp codec
.../bindings/display/rockchip/cdn-dp-rockchip.txt | 57 ++
.../devicetree/bindings/phy/phy-rockchip-typec.txt | 55 ++
.../bindings/sound/rockchip-cdn-dp-audio.txt | 12 +
drivers/gpu/drm/rockchip/Kconfig | 9 +
drivers/gpu/drm/rockchip/Makefile | 1 +
drivers/gpu/drm/rockchip/cdn-dp-core.c | 620 ++++++++++++++++
drivers/gpu/drm/rockchip/cdn-dp-core.h | 95 +++
drivers/gpu/drm/rockchip/cdn-dp-reg.c | 730 ++++++++++++++++++
drivers/gpu/drm/rockchip/cdn-dp-reg.h | 404 ++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 9 +-
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 +
drivers/phy/Kconfig | 7 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-rockchip-typec.c | 823 +++++++++++++++++++++
include/sound/cdn-dp-audio.h | 51 ++
sound/soc/codecs/Kconfig | 3 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/cdn-dp-audio.c | 246 ++++++
sound/soc/rockchip/Kconfig | 9 +
sound/soc/rockchip/Makefile | 2 +
sound/soc/rockchip/rockchip-cdn-dp-audio.c | 167 +++++
22 files changed, 3306 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
create mode 100644 Documentation/devicetree/bindings/sound/rockchip-cdn-dp-audio.txt
create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h
create mode 100644 drivers/phy/phy-rockchip-typec.c
create mode 100644 include/sound/cdn-dp-audio.h
create mode 100644 sound/soc/codecs/cdn-dp-audio.c
create mode 100644 sound/soc/rockchip/rockchip-cdn-dp-audio.c
--
2.6.3
2
4
27 May '16
Hi Mark
Cc Laurent
This is graph base DT support with simple-card.
Because it is still [RFC], I don't post full-patch-set yet,
but now we can use simple-card with graph style :)
(If my previous simple-card cleanup patches are accepted :)
Because it is based on simple-card, simple-graph-card can use similar
feature. But unfortunately not full feature are tested well, because
I don't have some of them. Thesea are not well tested feature.
Maybe no big problem, but I don't know
simple-audio-card,widgets
simple-audio-card,routing
simple-audio-card,mclk-fs
simple-audio-card,hp-det-gpio
simple-audio-card,mic-det-gpio
simple-audio-card,dai-tdm-slot-num
simple-audio-card,dai-tdm-slot-width
Big difference between simple-card <-> simple-graph-card is that
simple-graph-card doesn't support "platform" endpoint.
I don't know how to handle it under graph.
To support graph base DT, CPU/Codec driver might need to adjust.
And, as Jean-Francois mentioned before, CPU/Platform driver
need to register simple-graph-card card.
1 big concern is that it doesn't care about video port at this point.
So, if device has both video/sound ports, simple-graph-card
can't probe card correctly.
We need to have .type or similar property to know it was "video port"
or "sound port" ?
(ASoC need to know dai name, and it is based on total sound port number)
Below are simple-card <-> simple-graph-card DT style
=====================
simple-card
=====================
sound_card {
compatible = "simple-audio-card";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&sndcodec>;
simple-audio-card,frame-master = <&sndcodec>;
sndcpu: simple-audio-card,cpu {
sound-dai = <&soc_port>;
};
sndcodec: simple-audio-card,codec {
sound-dai = <&codec_port>;
clocks = <&xxx>;
};
};
codec_port: codec {
#sound-dai-cells = <0>;
...
};
soc_port: SoC {
#sound-dai-cells = <0>;
...
soc-port-specific-property
};
=====================
simple-graph-card
=====================
codec {
...
port {
codec_port: endpoint {
remote-endpoint = <&soc_port>;
clocks = <&xxx>;
};
};
};
SoC {
...
port {
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&codec_port>;
simple-audio-card,frame-master = <&codec_port>;
soc_port: endpoint {
remote-endpoint = <&codec_port>;
soc-port-specific-property
};
};
};
Best regards
---
Kuninori Morimoto
1
2
[alsa-devel] [PATCH v3 1/2] ASoC: cs35l33: Initial commit of the cs35l33 CODEC driver.
by Paul.Handrigan@cirrus.com 27 May '16
by Paul.Handrigan@cirrus.com 27 May '16
27 May '16
From: Paul Handrigan <Paul.Handrigan(a)cirrus.com>
Initial commit of the Cirrus Logic cs35l33 8V boosted class D
amplifier.
Signed-off-by: Paul Handrigan <Paul.Handrigan(a)cirrus.com>
---
include/sound/cs35l33.h | 54 ++
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/cs35l33.c | 1304 ++++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/cs35l33.h | 221 ++++++++
5 files changed, 1586 insertions(+)
create mode 100644 include/sound/cs35l33.h
create mode 100644 sound/soc/codecs/cs35l33.c
create mode 100644 sound/soc/codecs/cs35l33.h
diff --git a/include/sound/cs35l33.h b/include/sound/cs35l33.h
new file mode 100644
index 0000000..d18181c
--- /dev/null
+++ b/include/sound/cs35l33.h
@@ -0,0 +1,54 @@
+/*
+ * linux/sound/cs35l33.h -- Platform data for CS35l33
+ *
+ * Copyright (c) 2015 Cirrus Logic Inc.
+ *
+ * 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 __CS35L33_H
+#define __CS35L33_H
+
+struct cs35l33_hg {
+ bool enable_hg_algo;
+ unsigned int mem_depth;
+ unsigned int release_rate;
+ unsigned int hd_rm;
+ unsigned int ldo_thld;
+ unsigned int ldo_path_disable;
+ unsigned int ldo_entry_delay;
+ bool vp_hg_auto;
+ unsigned int vp_hg;
+ unsigned int vp_hg_rate;
+ unsigned int vp_hg_va;
+};
+
+struct cs35l33_pdata {
+ /* GPIO for IRQ */
+ int gpio_irq;
+
+ /* irq line */
+ int irq;
+
+ /* Boost Controller Voltage Setting */
+ unsigned int boost_ctl;
+
+ /* Boost Controller Peak Current */
+ unsigned int boost_ipk;
+
+ /* Amplifier Drive Select */
+ unsigned int amp_drv_sel;
+
+ /* soft volume ramp */
+ unsigned int ramp_rate;
+
+ /* IMON adc scale */
+ unsigned int imon_adc_scale;
+
+ /* H/G algo configuration */
+ struct cs35l33_hg hg_config;
+};
+
+#endif /* __CS35L33_H */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index c6f86ef..6ba6f8f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -46,6 +46,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_BT_SCO
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
select SND_SOC_CS35L32 if I2C
+ select SND_SOC_CS35L33 if I2C
select SND_SOC_CS42L51_I2C if I2C
select SND_SOC_CS42L52 if I2C && INPUT
select SND_SOC_CS42L56 if I2C && INPUT
@@ -379,6 +380,10 @@ config SND_SOC_CS35L32
tristate "Cirrus Logic CS35L32 CODEC"
depends on I2C
+config SND_SOC_CS35L33
+ tristate "Cirrus Logic CS35L33 CODEC"
+ depends on I2C
+
config SND_SOC_CS42L51
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 94873ee..22e7474 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -35,6 +35,7 @@ snd-soc-arizona-objs := arizona.o
snd-soc-bt-sco-objs := bt-sco.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs35l32-objs := cs35l32.o
+snd-soc-cs35l33-objs := cs35l33.o
snd-soc-cs42l51-objs := cs42l51.o
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
snd-soc-cs42l52-objs := cs42l52.o
@@ -249,6 +250,7 @@ obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o
+obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c
new file mode 100644
index 0000000..7713627
--- /dev/null
+++ b/sound/soc/codecs/cs35l33.c
@@ -0,0 +1,1304 @@
+/*
+ * cs35l33.c -- CS35L33 ALSA SoC audio driver
+ *
+ * Copyright 2016 Cirrus Logic, Inc.
+ *
+ * Author: Paul Handrigan <paul.handrigan(a)cirrus.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <sound/cs35l33.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#include "cs35l33.h"
+
+#define CS35L33_BOOT_DELAY 50
+#define CS35L33_INT_ATTEMPTS 20
+
+struct cs35l33_private {
+ struct snd_soc_codec *codec;
+ struct cs35l33_pdata pdata;
+ struct regmap *regmap;
+ struct gpio_desc *reset_gpio;
+ bool amp_cal;
+ int mclk_int;
+ struct regulator_bulk_data core_supplies[2];
+ int num_core_supplies;
+ bool is_tdm_mode;
+ bool enable_soft_ramp;
+};
+
+static const struct reg_default cs35l33_reg[] = {
+ {CS35L33_PWRCTL1, 0x85},
+ {CS35L33_PWRCTL2, 0xFE},
+ {CS35L33_CLK_CTL, 0x0C},
+ {CS35L33_BST_PEAK_CTL, 0x90},
+ {CS35L33_PROTECT_CTL, 0x55},
+ {CS35L33_BST_CTL1, 0x00},
+ {CS35L33_BST_CTL2, 0x01},
+ {CS35L33_ADSP_CTL, 0x00},
+ {CS35L33_ADC_CTL, 0xC8},
+ {CS35L33_DAC_CTL, 0x14},
+ {CS35L33_DIG_VOL_CTL, 0x00},
+ {CS35L33_CLASSD_CTL, 0x04},
+ {CS35L33_AMP_CTL, 0x90},
+ {CS35L33_INT_MASK_1, 0xFF},
+ {CS35L33_INT_MASK_2, 0xFF},
+ {CS35L33_DIAG_LOCK, 0x00},
+ {CS35L33_DIAG_CTRL_1, 0x40},
+ {CS35L33_DIAG_CTRL_2, 0x00},
+ {CS35L33_HG_MEMLDO_CTL, 0x62},
+ {CS35L33_HG_REL_RATE, 0x03},
+ {CS35L33_LDO_DEL, 0x12},
+ {CS35L33_HG_HEAD, 0x0A},
+ {CS35L33_HG_EN, 0x05},
+ {CS35L33_TX_VMON, 0x00},
+ {CS35L33_TX_IMON, 0x03},
+ {CS35L33_TX_VPMON, 0x02},
+ {CS35L33_TX_VBSTMON, 0x05},
+ {CS35L33_TX_FLAG, 0x06},
+ {CS35L33_TX_EN1, 0x00},
+ {CS35L33_TX_EN2, 0x00},
+ {CS35L33_TX_EN3, 0x00},
+ {CS35L33_TX_EN4, 0x00},
+ {CS35L33_RX_AUD, 0x40},
+ {CS35L33_RX_SPLY, 0x03},
+ {CS35L33_RX_ALIVE, 0x04},
+ {CS35L33_BST_CTL4, 0x63},
+};
+
+static const struct reg_sequence cs35l33_patch[] = {
+ { 0x00, 0x99, 0 },
+ { 0x59, 0x02, 0 },
+ { 0x52, 0x30, 0 },
+ { 0x39, 0x45, 0 },
+ { 0x57, 0x30, 0 },
+ { 0x2C, 0x68, 0 },
+ { 0x00, 0x00, 0 },
+};
+
+static bool cs35l33_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS35L33_DEVID_AB:
+ case CS35L33_DEVID_CD:
+ case CS35L33_DEVID_E:
+ case CS35L33_REV_ID:
+ case CS35L33_INT_STATUS_1:
+ case CS35L33_INT_STATUS_2:
+ case CS35L33_HG_STATUS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs35l33_writeable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ /* these are read only registers */
+ case CS35L33_DEVID_AB:
+ case CS35L33_DEVID_CD:
+ case CS35L33_DEVID_E:
+ case CS35L33_REV_ID:
+ case CS35L33_INT_STATUS_1:
+ case CS35L33_INT_STATUS_2:
+ case CS35L33_HG_STATUS:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static bool cs35l33_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS35L33_DEVID_AB:
+ case CS35L33_DEVID_CD:
+ case CS35L33_DEVID_E:
+ case CS35L33_REV_ID:
+ case CS35L33_PWRCTL1:
+ case CS35L33_PWRCTL2:
+ case CS35L33_CLK_CTL:
+ case CS35L33_BST_PEAK_CTL:
+ case CS35L33_PROTECT_CTL:
+ case CS35L33_BST_CTL1:
+ case CS35L33_BST_CTL2:
+ case CS35L33_ADSP_CTL:
+ case CS35L33_ADC_CTL:
+ case CS35L33_DAC_CTL:
+ case CS35L33_DIG_VOL_CTL:
+ case CS35L33_CLASSD_CTL:
+ case CS35L33_AMP_CTL:
+ case CS35L33_INT_MASK_1:
+ case CS35L33_INT_MASK_2:
+ case CS35L33_INT_STATUS_1:
+ case CS35L33_INT_STATUS_2:
+ case CS35L33_DIAG_LOCK:
+ case CS35L33_DIAG_CTRL_1:
+ case CS35L33_DIAG_CTRL_2:
+ case CS35L33_HG_MEMLDO_CTL:
+ case CS35L33_HG_REL_RATE:
+ case CS35L33_LDO_DEL:
+ case CS35L33_HG_HEAD:
+ case CS35L33_HG_EN:
+ case CS35L33_TX_VMON:
+ case CS35L33_TX_IMON:
+ case CS35L33_TX_VPMON:
+ case CS35L33_TX_VBSTMON:
+ case CS35L33_TX_FLAG:
+ case CS35L33_TX_EN1:
+ case CS35L33_TX_EN2:
+ case CS35L33_TX_EN3:
+ case CS35L33_TX_EN4:
+ case CS35L33_RX_AUD:
+ case CS35L33_RX_SPLY:
+ case CS35L33_RX_ALIVE:
+ case CS35L33_BST_CTL4:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static DECLARE_TLV_DB_SCALE(classd_ctl_tlv, 900, 100, 0);
+static DECLARE_TLV_DB_SCALE(dac_tlv, -10200, 50, 0);
+
+static const struct snd_kcontrol_new cs35l33_snd_controls[] = {
+
+ SOC_SINGLE_TLV("SPK Amp Volume", CS35L33_AMP_CTL,
+ 4, 0x09, 0, classd_ctl_tlv),
+ SOC_SINGLE_SX_TLV("DAC Volume", CS35L33_DIG_VOL_CTL,
+ 0, 0x34, 0xE4, dac_tlv),
+};
+
+static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ if (!priv->amp_cal) {
+ usleep_range(8000, 9000);
+ priv->amp_cal = true;
+ regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
+ CS35L33_AMP_CAL, 0);
+ dev_dbg(codec->dev, "Amp calibration done\n");
+ }
+ dev_dbg(codec->dev, "Amp turned on\n");
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ dev_dbg(codec->dev, "Amp turned off\n");
+ break;
+ default:
+ dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+ break;
+ }
+
+ return 0;
+}
+
+static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+ unsigned int val;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
+ CS35L33_PDN_BST, 0);
+ val = priv->is_tdm_mode ? 0 : CS35L33_PDN_TDM;
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
+ CS35L33_PDN_TDM, val);
+ dev_dbg(codec->dev, "BST turned on\n");
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ dev_dbg(codec->dev, "SDIN turned on\n");
+ if (!priv->amp_cal) {
+ regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
+ CS35L33_AMP_CAL, CS35L33_AMP_CAL);
+ dev_dbg(codec->dev, "Amp calibration started\n");
+ usleep_range(10000, 11000);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
+ CS35L33_PDN_TDM, CS35L33_PDN_TDM);
+ usleep_range(4000, 4100);
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
+ CS35L33_PDN_BST, CS35L33_PDN_BST);
+ dev_dbg(codec->dev, "BST and SDIN turned off\n");
+ break;
+ default:
+ dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+
+ }
+
+ return 0;
+}
+
+static int cs35l33_sdout_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+ unsigned int mask = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
+ unsigned int mask2 = CS35L33_SDOUT_3ST_TDM;
+ unsigned int val, val2;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (priv->is_tdm_mode) {
+ /* set sdout_3st_i2s and reset pdn_tdm */
+ val = CS35L33_SDOUT_3ST_I2S;
+ /* reset sdout_3st_tdm */
+ val2 = 0;
+ } else {
+ /* reset sdout_3st_i2s and set pdn_tdm */
+ val = CS35L33_PDN_TDM;
+ /* set sdout_3st_tdm */
+ val2 = CS35L33_SDOUT_3ST_TDM;
+ }
+ dev_dbg(codec->dev, "SDOUT turned on\n");
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ val = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
+ val2 = CS35L33_SDOUT_3ST_TDM;
+ dev_dbg(codec->dev, "SDOUT turned off\n");
+ break;
+ default:
+ dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+ return 0;
+ }
+
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
+ mask, val);
+ regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
+ mask2, val2);
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget cs35l33_dapm_widgets[] = {
+
+ SND_SOC_DAPM_OUTPUT("SPK"),
+ SND_SOC_DAPM_OUT_DRV_E("SPKDRV", CS35L33_PWRCTL1, 7, 1, NULL, 0,
+ cs35l33_spkrdrv_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L33_PWRCTL2,
+ 2, 1, cs35l33_sdin_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_INPUT("MON"),
+
+ SND_SOC_DAPM_ADC("VMON", NULL,
+ CS35L33_PWRCTL2, CS35L33_PDN_VMON_SHIFT, 1),
+ SND_SOC_DAPM_ADC("IMON", NULL,
+ CS35L33_PWRCTL2, CS35L33_PDN_IMON_SHIFT, 1),
+ SND_SOC_DAPM_ADC("VPMON", NULL,
+ CS35L33_PWRCTL2, CS35L33_PDN_VPMON_SHIFT, 1),
+ SND_SOC_DAPM_ADC("VBSTMON", NULL,
+ CS35L33_PWRCTL2, CS35L33_PDN_VBSTMON_SHIFT, 1),
+
+ SND_SOC_DAPM_AIF_OUT_E("SDOUT", NULL, 0, SND_SOC_NOPM, 0, 0,
+ cs35l33_sdout_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_PRE_PMD),
+};
+
+static const struct snd_soc_dapm_route cs35l33_audio_map[] = {
+ {"SDIN", NULL, "CS35L33 Playback"},
+ {"SPKDRV", NULL, "SDIN"},
+ {"SPK", NULL, "SPKDRV"},
+
+ {"VMON", NULL, "MON"},
+ {"IMON", NULL, "MON"},
+
+ {"SDOUT", NULL, "VMON"},
+ {"SDOUT", NULL, "IMON"},
+ {"CS35L33 Capture", NULL, "SDOUT"},
+};
+
+static const struct snd_soc_dapm_route cs35l33_vphg_auto_route[] = {
+ {"SPKDRV", NULL, "VPMON"},
+ {"VPMON", NULL, "CS35L33 Playback"},
+};
+
+static const struct snd_soc_dapm_route cs35l33_vp_vbst_mon_route[] = {
+ {"SDOUT", NULL, "VPMON"},
+ {"VPMON", NULL, "MON"},
+ {"SDOUT", NULL, "VBSTMON"},
+ {"VBSTMON", NULL, "MON"},
+};
+
+static int cs35l33_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ unsigned int val;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
+ CS35L33_PDN_ALL, 0);
+ regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
+ CS35L33_MCLKDIS, 0);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
+ CS35L33_PDN_ALL, CS35L33_PDN_ALL);
+ regmap_read(priv->regmap, CS35L33_INT_STATUS_2, &val);
+ usleep_range(1000, 1100);
+ if (val & CS35L33_PDN_DONE)
+ regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
+ CS35L33_MCLKDIS, CS35L33_MCLKDIS);
+ break;
+ case SND_SOC_BIAS_OFF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dapm->bias_level = level;
+
+ return 0;
+}
+
+struct cs35l33_mclk_div {
+ int mclk;
+ int srate;
+ u8 adsp_rate;
+ u8 int_fs_ratio;
+};
+
+static const struct cs35l33_mclk_div cs35l33_mclk_coeffs[] = {
+ /* MCLK, Sample Rate, adsp_rate, int_fs_ratio */
+ {5644800, 11025, 0x4, CS35L33_INT_FS_RATE},
+ {5644800, 22050, 0x8, CS35L33_INT_FS_RATE},
+ {5644800, 44100, 0xC, CS35L33_INT_FS_RATE},
+
+ {6000000, 8000, 0x1, 0},
+ {6000000, 11025, 0x2, 0},
+ {6000000, 11029, 0x3, 0},
+ {6000000, 12000, 0x4, 0},
+ {6000000, 16000, 0x5, 0},
+ {6000000, 22050, 0x6, 0},
+ {6000000, 22059, 0x7, 0},
+ {6000000, 24000, 0x8, 0},
+ {6000000, 32000, 0x9, 0},
+ {6000000, 44100, 0xA, 0},
+ {6000000, 44118, 0xB, 0},
+ {6000000, 48000, 0xC, 0},
+
+ {6144000, 8000, 0x1, CS35L33_INT_FS_RATE},
+ {6144000, 12000, 0x4, CS35L33_INT_FS_RATE},
+ {6144000, 16000, 0x5, CS35L33_INT_FS_RATE},
+ {6144000, 24000, 0x8, CS35L33_INT_FS_RATE},
+ {6144000, 32000, 0x9, CS35L33_INT_FS_RATE},
+ {6144000, 48000, 0xC, CS35L33_INT_FS_RATE},
+};
+
+static int cs35l33_get_mclk_coeff(int mclk, int srate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cs35l33_mclk_coeffs); i++) {
+ if (cs35l33_mclk_coeffs[i].mclk == mclk &&
+ cs35l33_mclk_coeffs[i].srate == srate)
+ return i;
+ }
+ return -EINVAL;
+}
+
+static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
+ CS35L33_MS_MASK, CS35L33_MS_MASK);
+ dev_dbg(codec->dev, "Audio port in master mode\n");
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
+ CS35L33_MS_MASK, 0);
+ dev_dbg(codec->dev, "Audio port in slave mode\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ /*
+ * tdm mode in cs35l33 resembles dsp-a mode very
+ * closely, it is dsp-a with fsync shifted left by half bclk
+ */
+ priv->is_tdm_mode = true;
+ dev_dbg(codec->dev, "Audio port in TDM mode\n");
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ priv->is_tdm_mode = false;
+ dev_dbg(codec->dev, "Audio port in I2S mode\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+ int sample_size = params_width(params);
+ int coeff = cs35l33_get_mclk_coeff(priv->mclk_int, params_rate(params));
+
+ if (coeff < 0)
+ return coeff;
+
+ regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
+ CS35L33_ADSP_FS | CS35L33_INT_FS_RATE,
+ cs35l33_mclk_coeffs[coeff].int_fs_ratio
+ | cs35l33_mclk_coeffs[coeff].adsp_rate);
+
+ if (priv->is_tdm_mode) {
+ sample_size = (sample_size / 8) - 1;
+ if (sample_size > 2)
+ sample_size = 2;
+ regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
+ CS35L33_AUDIN_RX_DEPTH,
+ sample_size << CS35L33_AUDIN_RX_DEPTH_SHIFT);
+ }
+
+ dev_dbg(codec->dev, "sample rate=%d, bits per sample=%d\n",
+ params_rate(params), params_width(params));
+
+ return 0;
+}
+
+static const unsigned int cs35l33_src_rates[] = {
+ 8000, 11025, 11029, 12000, 16000, 22050,
+ 22059, 24000, 32000, 44100, 44118, 48000
+};
+
+static const struct snd_pcm_hw_constraint_list cs35l33_constraints = {
+ .count = ARRAY_SIZE(cs35l33_src_rates),
+ .list = cs35l33_src_rates,
+};
+
+static int cs35l33_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &cs35l33_constraints);
+ return 0;
+}
+
+static int cs35l33_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ if (tristate) {
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
+ CS35L33_SDOUT_3ST_I2S, CS35L33_SDOUT_3ST_I2S);
+ regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
+ CS35L33_SDOUT_3ST_TDM, CS35L33_SDOUT_3ST_TDM);
+ } else {
+ regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
+ CS35L33_SDOUT_3ST_I2S, 0);
+ regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
+ CS35L33_SDOUT_3ST_TDM, 0);
+ }
+
+ return 0;
+}
+
+static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+ unsigned int reg, bit_pos, i;
+ int slot, slot_num;
+
+ if (slot_width != 8)
+ return -EINVAL;
+
+ /* scan rx_mask for aud slot */
+ slot = ffs(rx_mask) - 1;
+ if (slot >= 0) {
+ regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
+ CS35L33_X_LOC, slot);
+ dev_dbg(codec->dev, "Audio starts from slots %d", slot);
+ }
+
+ /*
+ * scan tx_mask: vmon(2 slots); imon (2 slots);
+ * vpmon (1 slot) vbstmon (1 slot)
+ */
+ slot = ffs(tx_mask) - 1;
+ slot_num = 0;
+
+ for (i = 0; i < 2 ; i++) {
+ /* disable vpmon/vbstmon: enable later if set in tx_mask */
+ regmap_update_bits(priv->regmap, CS35L33_TX_VPMON + i,
+ CS35L33_X_STATE | CS35L33_X_LOC, CS35L33_X_STATE
+ | CS35L33_X_LOC);
+ }
+
+ /* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/
+ snd_soc_dapm_del_routes(dapm, cs35l33_vp_vbst_mon_route,
+ ARRAY_SIZE(cs35l33_vp_vbst_mon_route));
+
+ while (slot >= 0) {
+ /* configure VMON_TX_LOC */
+ if (slot_num == 0) {
+ regmap_update_bits(priv->regmap, CS35L33_TX_VMON,
+ CS35L33_X_STATE | CS35L33_X_LOC, slot);
+ dev_dbg(codec->dev, "VMON enabled in slots %d-%d",
+ slot, slot + 1);
+ }
+
+ /* configure IMON_TX_LOC */
+ if (slot_num == 3) {
+ regmap_update_bits(priv->regmap, CS35L33_TX_IMON,
+ CS35L33_X_STATE | CS35L33_X_LOC, slot);
+ dev_dbg(codec->dev, "IMON enabled in slots %d-%d",
+ slot, slot + 1);
+ }
+
+ /* configure VPMON_TX_LOC */
+ if (slot_num == 4) {
+ regmap_update_bits(priv->regmap, CS35L33_TX_VPMON,
+ CS35L33_X_STATE | CS35L33_X_LOC, slot);
+ snd_soc_dapm_add_routes(dapm,
+ &cs35l33_vp_vbst_mon_route[0], 2);
+ dev_dbg(codec->dev, "VPMON enabled in slots %d", slot);
+ }
+
+ /* configure VBSTMON_TX_LOC */
+ if (slot_num == 5) {
+ regmap_update_bits(priv->regmap, CS35L33_TX_VBSTMON,
+ CS35L33_X_STATE | CS35L33_X_LOC, slot);
+ snd_soc_dapm_add_routes(dapm,
+ &cs35l33_vp_vbst_mon_route[2], 2);
+ dev_dbg(codec->dev,
+ "VBSTMON enabled in slots %d", slot);
+ }
+
+ /* Enable the relevant tx slot */
+ reg = CS35L33_TX_EN4 - (slot/8);
+ bit_pos = slot - ((slot / 8) * (8));
+ regmap_update_bits(priv->regmap, reg,
+ 1 << bit_pos, 1 << bit_pos);
+
+ tx_mask &= ~(1 << slot);
+ slot = ffs(tx_mask) - 1;
+ slot_num++;
+ }
+
+ return 0;
+}
+
+static int cs35l33_codec_set_sysclk(struct snd_soc_codec *codec,
+ int clk_id, int source, unsigned int freq, int dir)
+{
+ struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+
+ switch (freq) {
+ case CS35L33_MCLK_5644:
+ case CS35L33_MCLK_6:
+ case CS35L33_MCLK_6144:
+ regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
+ CS35L33_MCLKDIV2, 0);
+ cs35l33->mclk_int = freq;
+ break;
+ case CS35L33_MCLK_11289:
+ case CS35L33_MCLK_12:
+ case CS35L33_MCLK_12288:
+ regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
+ CS35L33_MCLKDIV2, CS35L33_MCLKDIV2);
+ cs35l33->mclk_int = freq/2;
+ break;
+ default:
+ cs35l33->mclk_int = 0;
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "external mclk freq=%d, internal mclk freq=%d\n",
+ freq, cs35l33->mclk_int);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops cs35l33_ops = {
+ .startup = cs35l33_pcm_startup,
+ .set_tristate = cs35l33_set_tristate,
+ .set_fmt = cs35l33_set_dai_fmt,
+ .hw_params = cs35l33_pcm_hw_params,
+ .set_tdm_slot = cs35l33_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver cs35l33_dai = {
+ .name = "cs35l33-dai",
+ .id = 0,
+ .playback = {
+ .stream_name = "CS35L33 Playback",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = CS35L33_RATES,
+ .formats = CS35L33_FORMATS,
+ },
+ .capture = {
+ .stream_name = "CS35L33 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = CS35L33_RATES,
+ .formats = CS35L33_FORMATS,
+ },
+ .ops = &cs35l33_ops,
+ .symmetric_rates = 1,
+};
+
+static int cs35l33_set_hg_data(struct snd_soc_codec *codec,
+ struct cs35l33_pdata *pdata)
+{
+ struct cs35l33_hg *hg_config = &pdata->hg_config;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ if (hg_config->enable_hg_algo) {
+ regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
+ CS35L33_MEM_DEPTH_MASK,
+ hg_config->mem_depth << CS35L33_MEM_DEPTH_SHIFT);
+ regmap_write(priv->regmap, CS35L33_HG_REL_RATE,
+ hg_config->release_rate);
+ regmap_update_bits(priv->regmap, CS35L33_HG_HEAD,
+ CS35L33_HD_RM_MASK,
+ hg_config->hd_rm << CS35L33_HD_RM_SHIFT);
+ regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
+ CS35L33_LDO_THLD_MASK,
+ hg_config->ldo_thld << CS35L33_LDO_THLD_SHIFT);
+ regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
+ CS35L33_LDO_DISABLE_MASK,
+ hg_config->ldo_path_disable <<
+ CS35L33_LDO_DISABLE_SHIFT);
+ regmap_update_bits(priv->regmap, CS35L33_LDO_DEL,
+ CS35L33_LDO_ENTRY_DELAY_MASK,
+ hg_config->ldo_entry_delay <<
+ CS35L33_LDO_ENTRY_DELAY_SHIFT);
+ if (hg_config->vp_hg_auto) {
+ regmap_update_bits(priv->regmap, CS35L33_HG_EN,
+ CS35L33_VP_HG_AUTO_MASK,
+ CS35L33_VP_HG_AUTO_MASK);
+ snd_soc_dapm_add_routes(dapm, cs35l33_vphg_auto_route,
+ ARRAY_SIZE(cs35l33_vphg_auto_route));
+ }
+ regmap_update_bits(priv->regmap, CS35L33_HG_EN,
+ CS35L33_VP_HG_MASK,
+ hg_config->vp_hg << CS35L33_VP_HG_SHIFT);
+ regmap_update_bits(priv->regmap, CS35L33_LDO_DEL,
+ CS35L33_VP_HG_RATE_MASK,
+ hg_config->vp_hg_rate << CS35L33_VP_HG_RATE_SHIFT);
+ regmap_update_bits(priv->regmap, CS35L33_LDO_DEL,
+ CS35L33_VP_HG_VA_MASK,
+ hg_config->vp_hg_va << CS35L33_VP_HG_VA_SHIFT);
+ regmap_update_bits(priv->regmap, CS35L33_HG_EN,
+ CS35L33_CLASS_HG_EN_MASK, CS35L33_CLASS_HG_EN_MASK);
+ }
+ return 0;
+}
+
+static int cs35l33_probe(struct snd_soc_codec *codec)
+{
+ struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+
+ cs35l33->codec = codec;
+ pm_runtime_get_sync(codec->dev);
+
+ regmap_update_bits(cs35l33->regmap, CS35L33_PROTECT_CTL,
+ CS35L33_ALIVE_WD_DIS, 0x8);
+ regmap_update_bits(cs35l33->regmap, CS35L33_BST_CTL2,
+ CS35L33_ALIVE_WD_DIS2,
+ CS35L33_ALIVE_WD_DIS2);
+
+ /* Set Platform Data */
+ regmap_update_bits(cs35l33->regmap, CS35L33_BST_CTL1,
+ CS35L33_BST_CTL_MASK, cs35l33->pdata.boost_ctl);
+ regmap_update_bits(cs35l33->regmap, CS35L33_CLASSD_CTL,
+ CS35L33_AMP_DRV_SEL_MASK,
+ cs35l33->pdata.amp_drv_sel << CS35L33_AMP_DRV_SEL_SHIFT);
+
+ if (cs35l33->pdata.boost_ipk)
+ regmap_write(cs35l33->regmap, CS35L33_BST_PEAK_CTL,
+ cs35l33->pdata.boost_ipk);
+
+ if (cs35l33->enable_soft_ramp) {
+ snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+ CS35L33_DIGSFT, CS35L33_DIGSFT);
+ snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+ CS35L33_DSR_RATE, cs35l33->pdata.ramp_rate);
+ } else {
+ snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+ CS35L33_DIGSFT, 0);
+ }
+
+ /* update IMON scaling rate if different from default of 0x8 */
+ if (cs35l33->pdata.imon_adc_scale != 0x8)
+ snd_soc_update_bits(codec, CS35L33_ADC_CTL,
+ CS35L33_IMON_SCALE, cs35l33->pdata.imon_adc_scale);
+
+ cs35l33_set_hg_data(codec, &(cs35l33->pdata));
+
+ /*
+ * unmask important interrupts that causes the chip to enter
+ * speaker safe mode and hence deserves user attention
+ */
+ regmap_update_bits(cs35l33->regmap, CS35L33_INT_MASK_1,
+ CS35L33_M_OTE | CS35L33_M_OTW | CS35L33_M_AMP_SHORT |
+ CS35L33_M_CAL_ERR, 0);
+
+ pm_runtime_put_sync(codec->dev);
+
+ return 0;
+}
+
+static struct regmap *cs35l33_get_regmap(struct device *dev)
+{
+ struct cs35l33_private *cs35l33 = dev_get_drvdata(dev);
+
+ return cs35l33->regmap;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
+ .probe = cs35l33_probe,
+
+ .get_regmap = cs35l33_get_regmap,
+ .set_bias_level = cs35l33_set_bias_level,
+ .set_sysclk = cs35l33_codec_set_sysclk,
+
+ .dapm_widgets = cs35l33_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets),
+ .dapm_routes = cs35l33_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map),
+ .controls = cs35l33_snd_controls,
+ .num_controls = ARRAY_SIZE(cs35l33_snd_controls),
+
+ .idle_bias_off = true,
+};
+
+static const struct regmap_config cs35l33_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CS35L33_MAX_REGISTER,
+ .reg_defaults = cs35l33_reg,
+ .num_reg_defaults = ARRAY_SIZE(cs35l33_reg),
+ .volatile_reg = cs35l33_volatile_register,
+ .readable_reg = cs35l33_readable_register,
+ .writeable_reg = cs35l33_writeable_register,
+ .cache_type = REGCACHE_RBTREE,
+ .use_single_rw = true,
+};
+
+static int cs35l33_runtime_resume(struct device *dev)
+{
+ struct cs35l33_private *cs35l33 = dev_get_drvdata(dev);
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (cs35l33->reset_gpio)
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
+
+ ret = regulator_bulk_enable(cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable core supplies: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(cs35l33->regmap, false);
+
+ if (cs35l33->reset_gpio)
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
+
+ msleep(CS35L33_BOOT_DELAY);
+
+ ret = regcache_sync(cs35l33->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to restore register cache\n");
+ goto err;
+ }
+
+ return 0;
+
+err:
+ regcache_cache_only(cs35l33->regmap, true);
+ regulator_bulk_disable(cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+
+ return ret;
+}
+
+static int cs35l33_runtime_suspend(struct device *dev)
+{
+ struct cs35l33_private *cs35l33 = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ /* redo the calibration in next power up */
+ cs35l33->amp_cal = false;
+
+ regcache_cache_only(cs35l33->regmap, true);
+ regcache_mark_dirty(cs35l33->regmap);
+ regulator_bulk_disable(cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cs35l33_pm_ops = {
+ SET_RUNTIME_PM_OPS(cs35l33_runtime_suspend,
+ cs35l33_runtime_resume,
+ NULL)
+};
+
+static int cs35l33_get_hg_data(const struct device_node *np,
+ struct cs35l33_pdata *pdata)
+{
+ struct device_node *hg;
+ struct cs35l33_hg *hg_config = &pdata->hg_config;
+ u32 val32;
+
+ hg = of_get_child_by_name(np, "hg-algo");
+ hg_config->enable_hg_algo = hg ? true : false;
+
+ if (hg_config->enable_hg_algo) {
+ if (of_property_read_u32(hg, "mem-depth", &val32) >= 0)
+ hg_config->mem_depth = val32;
+ if (of_property_read_u32(hg, "release-rate", &val32) >= 0)
+ hg_config->release_rate = val32;
+ if (of_property_read_u32(hg, "hd-rm", &val32) >= 0)
+ hg_config->hd_rm = val32;
+ if (of_property_read_u32(hg, "ldo-thld", &val32) >= 0)
+ hg_config->ldo_thld = val32;
+ if (of_property_read_u32(hg, "ldo-path-disable", &val32) >= 0)
+ hg_config->ldo_path_disable = val32;
+ if (of_property_read_u32(hg, "ldo-entry-delay", &val32) >= 0)
+ hg_config->ldo_entry_delay = val32;
+ hg_config->vp_hg_auto = of_property_read_bool(hg, "vp-hg-auto");
+ if (of_property_read_u32(hg, "vp-hg", &val32) >= 0)
+ hg_config->vp_hg = val32;
+ if (of_property_read_u32(hg, "vp-hg-rate", &val32) >= 0)
+ hg_config->vp_hg_rate = val32;
+ if (of_property_read_u32(hg, "vp-hg-va", &val32) >= 0)
+ hg_config->vp_hg_va = val32;
+ }
+
+ of_node_put(hg);
+
+ return 0;
+}
+
+static irqreturn_t cs35l33_irq_thread(int irq, void *data)
+{
+ struct cs35l33_private *cs35l33 = data;
+ struct snd_soc_codec *codec = cs35l33->codec;
+ unsigned int sticky_val1, sticky_val2, current_val, mask1, mask2;
+ int i;
+
+ for (i = 0; i < CS35L33_INT_ATTEMPTS; i++) {
+ /* ack the irq by reading both status registers */
+ regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_2,
+ &sticky_val2);
+ regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_1,
+ &sticky_val1);
+ regmap_read(cs35l33->regmap, CS35L33_INT_MASK_2, &mask2);
+ regmap_read(cs35l33->regmap, CS35L33_INT_MASK_1, &mask1);
+
+ /* Check to see if the unmasked bits are active,
+ * if not then exit at the exit.
+ */
+ if (!(sticky_val1 & ~mask1) && !(sticky_val2 & ~mask2))
+ break;
+
+
+ regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_1,
+ ¤t_val);
+
+ /* handle the interrupts */
+
+ if (sticky_val1 & CS35L33_AMP_SHORT) {
+ dev_err(codec->dev, "Amp short error\n");
+ if (!(current_val & CS35L33_AMP_SHORT)) {
+ dev_dbg(codec->dev,
+ "Amp short error release\n");
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL,
+ CS35L33_AMP_SHORT_RLS, 0);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL,
+ CS35L33_AMP_SHORT_RLS,
+ CS35L33_AMP_SHORT_RLS);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_AMP_SHORT_RLS,
+ 0);
+ }
+ }
+
+ if (sticky_val1 & CS35L33_CAL_ERR) {
+ dev_err(codec->dev, "Cal error\n");
+
+ /* redo the calibration in next power up */
+ cs35l33->amp_cal = false;
+
+ if (!(current_val & CS35L33_CAL_ERR)) {
+ dev_dbg(codec->dev, "Cal error release\n");
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
+ 0);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
+ CS35L33_CAL_ERR_RLS);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
+ 0);
+ }
+ }
+
+ if (sticky_val1 & CS35L33_OTE) {
+ dev_err(codec->dev, "Over temperature error\n");
+ if (!(current_val & CS35L33_OTE)) {
+ dev_dbg(codec->dev,
+ "Over temperature error release\n");
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_OTE_RLS, 0);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_OTE_RLS,
+ CS35L33_OTE_RLS);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_OTE_RLS, 0);
+ }
+ }
+
+ if (sticky_val1 & CS35L33_OTW) {
+ dev_err(codec->dev, "Over temperature warning\n");
+ if (!(current_val & CS35L33_OTW)) {
+ dev_dbg(codec->dev,
+ "Over temperature warning release\n");
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_OTW_RLS, 0);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_OTW_RLS,
+ CS35L33_OTW_RLS);
+ regmap_update_bits(cs35l33->regmap,
+ CS35L33_AMP_CTL, CS35L33_OTW_RLS, 0);
+ }
+ }
+ if (CS35L33_ALIVE_ERR & sticky_val1)
+ dev_err(codec->dev, "ERROR: ADSPCLK Interrupt\n");
+
+ if (CS35L33_MCLK_ERR & sticky_val1)
+ dev_err(codec->dev, "ERROR: MCLK Interrupt\n");
+
+ if (CS35L33_VMON_OVFL & sticky_val2)
+ dev_err(codec->dev,
+ "ERROR: VMON Overflow Interrupt\n");
+
+ if (CS35L33_IMON_OVFL & sticky_val2)
+ dev_err(codec->dev,
+ "ERROR: IMON Overflow Interrupt\n");
+
+ if (CS35L33_VPMON_OVFL & sticky_val2)
+ dev_err(codec->dev,
+ "ERROR: VPMON Overflow Interrupt\n");
+
+ if (CS35L33_VBSTMON_OVFL & sticky_val2)
+ dev_err(codec->dev,
+ "ERROR: VPMON Overflow Interrupt\n");
+ }
+
+ if (i == CS35L33_INT_ATTEMPTS) {
+ dev_err(codec->dev,
+ "ERROR: Interrupt handler exceeded max attpmpts\n");
+ return -EINVAL;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static const char * const cs35l33_core_supplies[] = {
+ "VA",
+ "VP",
+};
+
+static int cs35l33_of_get_pdata(struct device *dev,
+ struct cs35l33_private *cs35l33)
+{
+ struct device_node *np = dev->of_node;
+ struct cs35l33_pdata *pdata = &cs35l33->pdata;
+ u32 val32;
+
+ if (!np)
+ return 0;
+
+ if (of_property_read_u32(np, "boost-ctl", &val32) >= 0) {
+ pdata->boost_ctl = val32;
+ pdata->amp_drv_sel = 1;
+ }
+
+ if (of_property_read_u32(np, "ramp-rate", &val32) >= 0) {
+ pdata->ramp_rate = val32;
+ cs35l33->enable_soft_ramp = true;
+ }
+
+ if (of_property_read_u32(np, "boost-ipk", &val32) >= 0)
+ pdata->boost_ipk = val32;
+
+ if (of_property_read_u32(np, "imon-adc-scale", &val32) >= 0) {
+ if ((val32 == 0x0) || (val32 == 0x7) || (val32 == 0x6))
+ pdata->imon_adc_scale = val32;
+ else
+ /* use default value */
+ pdata->imon_adc_scale = 0x8;
+ } else {
+ /* use default value */
+ pdata->imon_adc_scale = 0x8;
+ }
+
+ cs35l33_get_hg_data(np, pdata);
+
+ return 0;
+}
+
+static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
+{
+ struct cs35l33_private *cs35l33;
+ struct cs35l33_pdata *pdata = dev_get_platdata(&i2c_client->dev);
+ int ret, devid, i;
+ unsigned int reg;
+
+ cs35l33 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l33_private),
+ GFP_KERNEL);
+ if (!cs35l33)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c_client, cs35l33);
+ cs35l33->regmap = devm_regmap_init_i2c(i2c_client, &cs35l33_regmap);
+ if (IS_ERR(cs35l33->regmap)) {
+ ret = PTR_ERR(cs35l33->regmap);
+ dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(cs35l33->regmap, true);
+
+ for (i = 0; i < ARRAY_SIZE(cs35l33_core_supplies); i++)
+ cs35l33->core_supplies[i].supply
+ = cs35l33_core_supplies[i];
+ cs35l33->num_core_supplies = ARRAY_SIZE(cs35l33_core_supplies);
+
+ ret = devm_regulator_bulk_get(&i2c_client->dev,
+ cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+ if (ret != 0) {
+ dev_err(&i2c_client->dev,
+ "Failed to request core supplies: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (pdata) {
+ cs35l33->pdata = *pdata;
+ } else {
+ cs35l33_of_get_pdata(&i2c_client->dev, cs35l33);
+ pdata = &cs35l33->pdata;
+ }
+
+ ret = request_threaded_irq(i2c_client->irq, NULL, cs35l33_irq_thread,
+ IRQF_ONESHOT | IRQF_TRIGGER_LOW, "cs35l33", cs35l33);
+ if (ret != 0)
+ dev_err(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);
+
+ /* We could issue !RST or skip it based on AMP topology */
+ cs35l33->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
+ "reset-gpios", GPIOD_OUT_HIGH);
+
+ if (PTR_ERR(cs35l33->reset_gpio) == -ENOENT) {
+ dev_warn(&i2c_client->dev,
+ "%s WARNING: No reset gpio assigned\n", __func__);
+ } else if (IS_ERR(cs35l33->reset_gpio)) {
+ dev_err(&i2c_client->dev, "%s ERROR: Can't get reset GPIO\n",
+ __func__);
+ return PTR_ERR(cs35l33->reset_gpio);
+ }
+
+ ret = regulator_bulk_enable(cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+ if (ret != 0) {
+ dev_err(&i2c_client->dev,
+ "Failed to enable core supplies: %d\n",
+ ret);
+ goto err_irq;
+ }
+
+ if (cs35l33->reset_gpio)
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
+
+ msleep(CS35L33_BOOT_DELAY);
+ regcache_cache_only(cs35l33->regmap, false);
+
+ /* initialize codec */
+ ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_AB, ®);
+ devid = (reg & 0xFF) << 12;
+ ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_CD, ®);
+ devid |= (reg & 0xFF) << 4;
+ ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_E, ®);
+ devid |= (reg & 0xF0) >> 4;
+
+ if (devid != CS35L33_CHIP_ID) {
+ dev_err(&i2c_client->dev,
+ "CS35L33 Device ID (%X). Expected ID %X\n",
+ devid, CS35L33_CHIP_ID);
+ goto err_enable;
+ }
+
+ ret = regmap_read(cs35l33->regmap, CS35L33_REV_ID, ®);
+ if (ret < 0) {
+ dev_err(&i2c_client->dev, "Get Revision ID failed\n");
+ goto err_enable;
+ }
+
+ dev_info(&i2c_client->dev,
+ "Cirrus Logic CS35L33, Revision: %02X\n", ret & 0xFF);
+
+ ret = regmap_register_patch(cs35l33->regmap,
+ cs35l33_patch, ARRAY_SIZE(cs35l33_patch));
+ if (ret < 0) {
+ dev_err(&i2c_client->dev,
+ "Error in applying regmap patch: %d\n", ret);
+ goto err_enable;
+ }
+
+ /* disable mclk and tdm */
+ regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
+ CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM,
+ CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM);
+
+ pm_runtime_set_autosuspend_delay(&i2c_client->dev, 100);
+ pm_runtime_use_autosuspend(&i2c_client->dev);
+ pm_runtime_set_active(&i2c_client->dev);
+ pm_runtime_enable(&i2c_client->dev);
+
+ ret = snd_soc_register_codec(&i2c_client->dev,
+ &soc_codec_dev_cs35l33, &cs35l33_dai, 1);
+ if (ret < 0) {
+ dev_err(&i2c_client->dev, "%s: Register codec failed\n",
+ __func__);
+ goto err_irq;
+ }
+
+ return 0;
+
+err_enable:
+ regulator_bulk_disable(cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+err_irq:
+ free_irq(i2c_client->irq, cs35l33);
+
+ return ret;
+}
+
+static int cs35l33_i2c_remove(struct i2c_client *client)
+{
+ struct cs35l33_private *cs35l33 = i2c_get_clientdata(client);
+
+ snd_soc_unregister_codec(&client->dev);
+
+ if (cs35l33->reset_gpio)
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
+
+ pm_runtime_disable(&client->dev);
+ regulator_bulk_disable(cs35l33->num_core_supplies,
+ cs35l33->core_supplies);
+ free_irq(client->irq, cs35l33);
+
+ return 0;
+}
+
+static const struct of_device_id cs35l33_of_match[] = {
+ { .compatible = "cirrus,cs35l33", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, cs35l33_of_match);
+
+static const struct i2c_device_id cs35l33_id[] = {
+ {"cs35l33", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, cs35l33_id);
+
+static struct i2c_driver cs35l33_i2c_driver = {
+ .driver = {
+ .name = "cs35l33",
+ .owner = THIS_MODULE,
+ .pm = &cs35l33_pm_ops,
+ .of_match_table = cs35l33_of_match,
+
+ },
+ .id_table = cs35l33_id,
+ .probe = cs35l33_i2c_probe,
+ .remove = cs35l33_i2c_remove,
+
+};
+module_i2c_driver(cs35l33_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC CS35L33 driver");
+MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <paul.handrigan(a)cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l33.h b/sound/soc/codecs/cs35l33.h
new file mode 100644
index 0000000..c045737
--- /dev/null
+++ b/sound/soc/codecs/cs35l33.h
@@ -0,0 +1,221 @@
+/*
+ * cs35l33.h -- CS35L33 ALSA SoC audio driver
+ *
+ * Copyright 2016 Cirrus Logic, Inc.
+ *
+ * Author: Paul Handrigan <paul.handrigan(a)cirrus.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __CS35L33_H__
+#define __CS35L33_H__
+
+#define CS35L33_CHIP_ID 0x00035A33
+#define CS35L33_DEVID_AB 0x01 /* Device ID A & B [RO] */
+#define CS35L33_DEVID_CD 0x02 /* Device ID C & D [RO] */
+#define CS35L33_DEVID_E 0x03 /* Device ID E [RO] */
+#define CS35L33_FAB_ID 0x04 /* Fab ID [RO] */
+#define CS35L33_REV_ID 0x05 /* Revision ID [RO] */
+#define CS35L33_PWRCTL1 0x06 /* Power Ctl 1 */
+#define CS35L33_PWRCTL2 0x07 /* Power Ctl 2 */
+#define CS35L33_CLK_CTL 0x08 /* Clock Ctl */
+#define CS35L33_BST_PEAK_CTL 0x09 /* Max Current for Boost */
+#define CS35L33_PROTECT_CTL 0x0A /* Amp Protection Parameters */
+#define CS35L33_BST_CTL1 0x0B /* Boost Converter CTL1 */
+#define CS35L33_BST_CTL2 0x0C /* Boost Converter CTL2 */
+#define CS35L33_ADSP_CTL 0x0D /* Serial Port Control */
+#define CS35L33_ADC_CTL 0x0E /* ADC Control */
+#define CS35L33_DAC_CTL 0x0F /* DAC Control */
+#define CS35L33_DIG_VOL_CTL 0x10 /* Digital Volume CTL */
+#define CS35L33_CLASSD_CTL 0x11 /* Class D Amp CTL */
+#define CS35L33_AMP_CTL 0x12 /* Amp Gain/Protecton Release CTL */
+#define CS35L33_INT_MASK_1 0x13 /* Interrupt Mask 1 */
+#define CS35L33_INT_MASK_2 0x14 /* Interrupt Mask 2 */
+#define CS35L33_INT_STATUS_1 0x15 /* Interrupt Status 1 [RO] */
+#define CS35L33_INT_STATUS_2 0x16 /* Interrupt Status 2 [RO] */
+#define CS35L33_DIAG_LOCK 0x17 /* Diagnostic Mode Register Lock */
+#define CS35L33_DIAG_CTRL_1 0x18 /* Diagnostic Mode Register Control */
+#define CS35L33_DIAG_CTRL_2 0x19 /* Diagnostic Mode Register Control 2 */
+#define CS35L33_HG_MEMLDO_CTL 0x23 /* H/G Memory/LDO CTL */
+#define CS35L33_HG_REL_RATE 0x24 /* H/G Release Rate */
+#define CS35L33_LDO_DEL 0x25 /* LDO Entry Delay/VPhg Control 1 */
+#define CS35L33_HG_HEAD 0x29 /* H/G Headroom */
+#define CS35L33_HG_EN 0x2A /* H/G Enable/VPhg CNT2 */
+#define CS35L33_TX_VMON 0x2D /* TDM TX Control 1 (VMON) */
+#define CS35L33_TX_IMON 0x2E /* TDM TX Control 2 (IMON) */
+#define CS35L33_TX_VPMON 0x2F /* TDM TX Control 3 (VPMON) */
+#define CS35L33_TX_VBSTMON 0x30 /* TDM TX Control 4 (VBSTMON) */
+#define CS35L33_TX_FLAG 0x31 /* TDM TX Control 5 (FLAG) */
+#define CS35L33_TX_EN1 0x32 /* TDM TX Enable 1 */
+#define CS35L33_TX_EN2 0x33 /* TDM TX Enable 2 */
+#define CS35L33_TX_EN3 0x34 /* TDM TX Enable 3 */
+#define CS35L33_TX_EN4 0x35 /* TDM TX Enable 4 */
+#define CS35L33_RX_AUD 0x36 /* TDM RX Control 1 */
+#define CS35L33_RX_SPLY 0x37 /* TDM RX Control 2 */
+#define CS35L33_RX_ALIVE 0x38 /* TDM RX Control 3 */
+#define CS35L33_BST_CTL4 0x39 /* Boost Converter Control 4 */
+#define CS35L33_HG_STATUS 0x3F /* H/G Status */
+#define CS35L33_MAX_REGISTER 0x59
+
+#define CS35L33_MCLK_5644 5644800
+#define CS35L33_MCLK_6144 6144000
+#define CS35L33_MCLK_6 6000000
+#define CS35L33_MCLK_11289 11289600
+#define CS35L33_MCLK_12 12000000
+#define CS35L33_MCLK_12288 12288000
+
+/* CS35L33_PWRCTL1 */
+#define CS35L33_PDN_AMP (1 << 7)
+#define CS35L33_PDN_BST (1 << 2)
+#define CS35L33_PDN_ALL 1
+
+/* CS35L33_PWRCTL2 */
+#define CS35L33_PDN_VMON_SHIFT 7
+#define CS35L33_PDN_VMON (1 << CS35L33_PDN_VMON_SHIFT)
+#define CS35L33_PDN_IMON_SHIFT 6
+#define CS35L33_PDN_IMON (1 << CS35L33_PDN_IMON_SHIFT)
+#define CS35L33_PDN_VPMON_SHIFT 5
+#define CS35L33_PDN_VPMON (1 << CS35L33_PDN_VPMON_SHIFT)
+#define CS35L33_PDN_VBSTMON_SHIFT 4
+#define CS35L33_PDN_VBSTMON (1 << CS35L33_PDN_VBSTMON_SHIFT)
+#define CS35L33_SDOUT_3ST_I2S_SHIFT 3
+#define CS35L33_SDOUT_3ST_I2S (1 << CS35L33_SDOUT_3ST_I2S_SHIFT)
+#define CS35L33_PDN_SDIN_SHIFT 2
+#define CS35L33_PDN_SDIN (1 << CS35L33_PDN_SDIN_SHIFT)
+#define CS35L33_PDN_TDM_SHIFT 1
+#define CS35L33_PDN_TDM (1 << CS35L33_PDN_TDM_SHIFT)
+
+/* CS35L33_CLK_CTL */
+#define CS35L33_MCLKDIS (1 << 7)
+#define CS35L33_MCLKDIV2 (1 << 6)
+#define CS35L33_SDOUT_3ST_TDM (1 << 5)
+#define CS35L33_INT_FS_RATE (1 << 4)
+#define CS35L33_ADSP_FS 0xF
+
+/* CS35L33_PROTECT_CTL */
+#define CS35L33_ALIVE_WD_DIS (3 << 2)
+
+/* CS35L33_BST_CTL1 */
+#define CS35L33_BST_CTL_SRC (1 << 6)
+#define CS35L33_BST_CTL_SHIFT (1 << 5)
+#define CS35L33_BST_CTL_MASK 0x3F
+
+/* CS35L33_BST_CTL2 */
+#define CS35L33_TDM_WD_SEL (1 << 4)
+#define CS35L33_ALIVE_WD_DIS2 (1 << 3)
+#define CS35L33_VBST_SR_STEP 0x3
+
+/* CS35L33_ADSP_CTL */
+#define CS35L33_ADSP_DRIVE (1 << 7)
+#define CS35L33_MS_MASK (1 << 6)
+#define CS35L33_SDIN_LOC (3 << 4)
+#define CS35L33_ALIVE_RATE 0x3
+
+/* CS35L33_ADC_CTL */
+#define CS35L33_INV_VMON (1 << 7)
+#define CS35L33_INV_IMON (1 << 6)
+#define CS35L33_ADC_NOTCH_DIS (1 << 5)
+#define CS35L33_IMON_SCALE 0xF
+
+/* CS35L33_DAC_CTL */
+#define CS35L33_INV_DAC (1 << 7)
+#define CS35L33_DAC_NOTCH_DIS (1 << 5)
+#define CS35L33_DIGSFT (1 << 4)
+#define CS35L33_DSR_RATE 0xF
+
+/* CS35L33_CLASSD_CTL */
+#define CS35L33_AMP_SD (1 << 6)
+#define CS35L33_AMP_DRV_SEL_SRC (1 << 5)
+#define CS35L33_AMP_DRV_SEL_MASK 0x10
+#define CS35L33_AMP_DRV_SEL_SHIFT 4
+#define CS35L33_AMP_CAL (1 << 3)
+#define CS35L33_GAIN_CHG_ZC_MASK 0x04
+#define CS35L33_GAIN_CHG_ZC_SHIFT 2
+#define CS35L33_CLASS_D_CTL_MASK 0x3F
+
+/* CS35L33_AMP_CTL */
+#define CS35L33_AMP_GAIN 0xF0
+#define CS35L33_CAL_ERR_RLS (1 << 3)
+#define CS35L33_AMP_SHORT_RLS (1 << 2)
+#define CS35L33_OTW_RLS (1 << 1)
+#define CS35L33_OTE_RLS 1
+
+/* CS35L33_INT_MASK_1 */
+#define CS35L33_M_CAL_ERR_SHIFT 6
+#define CS35L33_M_CAL_ERR (1 << CS35L33_M_CAL_ERR_SHIFT)
+#define CS35L33_M_ALIVE_ERR_SHIFT 5
+#define CS35L33_M_ALIVE_ERR (1 << CS35L33_M_ALIVE_ERR_SHIFT)
+#define CS35L33_M_AMP_SHORT_SHIFT 2
+#define CS35L33_M_AMP_SHORT (1 << CS35L33_M_AMP_SHORT_SHIFT)
+#define CS35L33_M_OTW_SHIFT 1
+#define CS35L33_M_OTW (1 << CS35L33_M_OTW_SHIFT)
+#define CS35L33_M_OTE_SHIFT 0
+#define CS35L33_M_OTE (1 << CS35L33_M_OTE_SHIFT)
+
+/* CS35L33_INT_STATUS_1 */
+#define CS35L33_CAL_ERR (1 << 6)
+#define CS35L33_ALIVE_ERR (1 << 5)
+#define CS35L33_ADSPCLK_ERR (1 << 4)
+#define CS35L33_MCLK_ERR (1 << 3)
+#define CS35L33_AMP_SHORT (1 << 2)
+#define CS35L33_OTW (1 << 1)
+#define CS35L33_OTE (1 << 0)
+
+/* CS35L33_INT_STATUS_2 */
+#define CS35L33_VMON_OVFL (1 << 7)
+#define CS35L33_IMON_OVFL (1 << 6)
+#define CS35L33_VPMON_OVFL (1 << 5)
+#define CS35L33_VBSTMON_OVFL (1 << 4)
+#define CS35L33_PDN_DONE 1
+
+/* CS35L33_BST_CTL4 */
+#define CS35L33_BST_RGS 0x70
+#define CS35L33_BST_COEFF3 0xF
+
+/* CS35L33_HG_MEMLDO_CTL */
+#define CS35L33_MEM_DEPTH_SHIFT 5
+#define CS35L33_MEM_DEPTH_MASK (0x3 << CS35L33_MEM_DEPTH_SHIFT)
+#define CS35L33_LDO_THLD_SHIFT 1
+#define CS35L33_LDO_THLD_MASK (0xF << CS35L33_LDO_THLD_SHIFT)
+#define CS35L33_LDO_DISABLE_SHIFT 0
+#define CS35L33_LDO_DISABLE_MASK (0x1 << CS35L33_LDO_DISABLE_SHIFT)
+
+/* CS35L33_LDO_DEL */
+#define CS35L33_VP_HG_VA_SHIFT 5
+#define CS35L33_VP_HG_VA_MASK (0x7 << CS35L33_VP_HG_VA_SHIFT)
+#define CS35L33_LDO_ENTRY_DELAY_SHIFT 2
+#define CS35L33_LDO_ENTRY_DELAY_MASK (0x7 << CS35L33_LDO_ENTRY_DELAY_SHIFT)
+#define CS35L33_VP_HG_RATE_SHIFT 0
+#define CS35L33_VP_HG_RATE_MASK (0x3 << CS35L33_VP_HG_RATE_SHIFT)
+
+/* CS35L33_HG_HEAD */
+#define CS35L33_HD_RM_SHIFT 0
+#define CS35L33_HD_RM_MASK (0x7F << CS35L33_HD_RM_SHIFT)
+
+/* CS35L33_HG_EN */
+#define CS35L33_CLASS_HG_ENA_SHIFT 7
+#define CS35L33_CLASS_HG_EN_MASK (0x1 << CS35L33_CLASS_HG_ENA_SHIFT)
+#define CS35L33_VP_HG_AUTO_SHIFT 6
+#define CS35L33_VP_HG_AUTO_MASK (0x1 << 6)
+#define CS35L33_VP_HG_SHIFT 0
+#define CS35L33_VP_HG_MASK (0x1F << CS35L33_VP_HG_SHIFT)
+
+#define CS35L33_RATES (SNDRV_PCM_RATE_8000_48000)
+#define CS35L33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+/* CS35L33_{RX,TX}_X */
+#define CS35L33_X_STATE_SHIFT 7
+#define CS35L33_X_STATE (1 << CS35L33_X_STATE_SHIFT)
+#define CS35L33_X_LOC_SHIFT 0
+#define CS35L33_X_LOC (0x1F << CS35L33_X_LOC_SHIFT)
+
+/* CS35L33_RX_AUD */
+#define CS35L33_AUDIN_RX_DEPTH_SHIFT 5
+#define CS35L33_AUDIN_RX_DEPTH (0x7 << CS35L33_AUDIN_RX_DEPTH_SHIFT)
+
+#endif
--
1.9.1
3
5
From: Petr Kulhavy <petr(a)barix.com>
The WM8758 chip is almost identical to WM8985 with the difference that it
doesn't feature the AUX input. This patch adds the WM8758 support into the
WM8985 driver.
The chip selection is done by the I2C name. The SPI probe supports only
the WM8985.
Signed-off-by: Petr Kulhavy <petr(a)barix.com>
Reviewed-by: Charles Keepax <ckeepax(a)opensource.wolfsonmicro.com>
---
v1: initial
v2: use chip type enum instead of chip structure
do not copy the complete controls, widget, routes but only the differences and
add widgets dynamically using add_widgets()
v3: merge the wm8985_xxx_snd_controls into wm8985_common_snd_controls and wm8985_specific_snd_controls
in order to reduce the number of structures
use the static initialization in snd_soc_codec_driver for the common part
v4: avoid duplicating left/right_out_mixer and left/right_boost_mixer by moving the aux controls
at the end and providing shorter size for wm8758
do not move the high pass filter controls
v5: reapplied to git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git branch topics/wm8985
sound/soc/codecs/Kconfig | 2 +-
sound/soc/codecs/wm8985.c | 143 ++++++++++++++++++++++++++++++++++------------
2 files changed, 109 insertions(+), 36 deletions(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index b3afae9..5c635f7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -944,7 +944,7 @@ config SND_SOC_WM8983
tristate
config SND_SOC_WM8985
- tristate
+ tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver"
config SND_SOC_WM8988
tristate
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index 6ac76fe..7347abf 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -1,10 +1,13 @@
/*
- * wm8985.c -- WM8985 ALSA SoC Audio driver
+ * wm8985.c -- WM8985 / WM8758 ALSA SoC Audio driver
*
* Copyright 2010 Wolfson Microelectronics plc
- *
* Author: Dimitris Papastamos <dp(a)opensource.wolfsonmicro.com>
*
+ * WM8758 support:
+ * Copyright: 2016 Barix AG
+ * Author: Petr Kulhavy <petr(a)barix.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -40,6 +43,11 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
"AVDD2"
};
+enum wm8985_type {
+ WM8985,
+ WM8758,
+};
+
static const struct reg_default wm8985_reg_defaults[] = {
{ 1, 0x0000 }, /* R1 - Power management 1 */
{ 2, 0x0000 }, /* R2 - Power management 2 */
@@ -181,6 +189,7 @@ static const int volume_update_regs[] = {
struct wm8985_priv {
struct regmap *regmap;
struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES];
+ enum wm8985_type dev_type;
unsigned int sysclk;
unsigned int bclk;
};
@@ -289,7 +298,7 @@ static const char *depth_3d_text[] = {
};
static SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, depth_3d_text);
-static const struct snd_kcontrol_new wm8985_snd_controls[] = {
+static const struct snd_kcontrol_new wm8985_common_snd_controls[] = {
SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL,
0, 1, 0),
@@ -355,10 +364,6 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
SOC_ENUM("High Pass Filter Mode", filter_mode),
SOC_SINGLE("High Pass Filter Cutoff", WM8985_ADC_CONTROL, 4, 7, 0),
- SOC_DOUBLE_R_TLV("Aux Bypass Volume",
- WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0,
- aux_tlv),
-
SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",
WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 2, 7, 0,
bypass_tlv),
@@ -379,20 +384,30 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
SOC_SINGLE_TLV("EQ5 Volume", WM8985_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
SOC_ENUM("3D Depth", depth_3d),
+};
+
+static const struct snd_kcontrol_new wm8985_specific_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("Aux Bypass Volume",
+ WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0,
+ aux_tlv),
SOC_ENUM("Speaker Mode", speaker_mode)
};
static const struct snd_kcontrol_new left_out_mixer[] = {
SOC_DAPM_SINGLE("Line Switch", WM8985_LEFT_MIXER_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0),
SOC_DAPM_SINGLE("PCM Switch", WM8985_LEFT_MIXER_CTRL, 0, 1, 0),
+
+ /* --- WM8985 only --- */
+ SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0),
};
static const struct snd_kcontrol_new right_out_mixer[] = {
SOC_DAPM_SINGLE("Line Switch", WM8985_RIGHT_MIXER_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0),
SOC_DAPM_SINGLE("PCM Switch", WM8985_RIGHT_MIXER_CTRL, 0, 1, 0),
+
+ /* --- WM8985 only --- */
+ SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0),
};
static const struct snd_kcontrol_new left_input_mixer[] = {
@@ -410,6 +425,8 @@ static const struct snd_kcontrol_new right_input_mixer[] = {
static const struct snd_kcontrol_new left_boost_mixer[] = {
SOC_DAPM_SINGLE_TLV("L2 Volume", WM8985_LEFT_ADC_BOOST_CTRL,
4, 7, 0, boost_tlv),
+
+ /* --- WM8985 only --- */
SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8985_LEFT_ADC_BOOST_CTRL,
0, 7, 0, boost_tlv)
};
@@ -417,11 +434,13 @@ static const struct snd_kcontrol_new left_boost_mixer[] = {
static const struct snd_kcontrol_new right_boost_mixer[] = {
SOC_DAPM_SINGLE_TLV("R2 Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
4, 7, 0, boost_tlv),
+
+ /* --- WM8985 only --- */
SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
0, 7, 0, boost_tlv)
};
-static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
+static const struct snd_soc_dapm_widget wm8985_common_dapm_widgets[] = {
SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8985_POWER_MANAGEMENT_3,
0, 0),
SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8985_POWER_MANAGEMENT_3,
@@ -431,21 +450,11 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8985_POWER_MANAGEMENT_2,
1, 0),
- SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
- 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
- SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
- 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
-
SND_SOC_DAPM_MIXER("Left Input Mixer", WM8985_POWER_MANAGEMENT_2,
2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),
SND_SOC_DAPM_MIXER("Right Input Mixer", WM8985_POWER_MANAGEMENT_2,
3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),
- SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
- 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
- SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
- 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
-
SND_SOC_DAPM_PGA("Left Capture PGA", WM8985_LEFT_INP_PGA_GAIN_CTRL,
6, 1, NULL, 0),
SND_SOC_DAPM_PGA("Right Capture PGA", WM8985_RIGHT_INP_PGA_GAIN_CTRL,
@@ -468,8 +477,6 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("LIP"),
SND_SOC_DAPM_INPUT("RIN"),
SND_SOC_DAPM_INPUT("RIP"),
- SND_SOC_DAPM_INPUT("AUXL"),
- SND_SOC_DAPM_INPUT("AUXR"),
SND_SOC_DAPM_INPUT("L2"),
SND_SOC_DAPM_INPUT("R2"),
SND_SOC_DAPM_OUTPUT("HPL"),
@@ -478,13 +485,42 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("SPKR")
};
-static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
+static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
+ SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
+ 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
+ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
+ 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
+
+ SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
+ 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
+ SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
+ 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
+
+ SND_SOC_DAPM_INPUT("AUXL"),
+ SND_SOC_DAPM_INPUT("AUXR"),
+};
+
+static const struct snd_soc_dapm_widget wm8758_dapm_widgets[] = {
+ SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
+ 2, 0, left_out_mixer,
+ ARRAY_SIZE(left_out_mixer) - 1),
+ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
+ 3, 0, right_out_mixer,
+ ARRAY_SIZE(right_out_mixer) - 1),
+
+ SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
+ 4, 0, left_boost_mixer,
+ ARRAY_SIZE(left_boost_mixer) - 1),
+ SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
+ 5, 0, right_boost_mixer,
+ ARRAY_SIZE(right_boost_mixer) - 1),
+};
+
+static const struct snd_soc_dapm_route wm8985_common_dapm_routes[] = {
{ "Right Output Mixer", "PCM Switch", "Right DAC" },
- { "Right Output Mixer", "Aux Switch", "AUXR" },
{ "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
{ "Left Output Mixer", "PCM Switch", "Left DAC" },
- { "Left Output Mixer", "Aux Switch", "AUXL" },
{ "Left Output Mixer", "Line Switch", "Left Boost Mixer" },
{ "Right Headphone Out", NULL, "Right Output Mixer" },
@@ -501,13 +537,11 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
{ "Right ADC", NULL, "Right Boost Mixer" },
- { "Right Boost Mixer", "AUXR Volume", "AUXR" },
{ "Right Boost Mixer", NULL, "Right Capture PGA" },
{ "Right Boost Mixer", "R2 Volume", "R2" },
{ "Left ADC", NULL, "Left Boost Mixer" },
- { "Left Boost Mixer", "AUXL Volume", "AUXL" },
{ "Left Boost Mixer", NULL, "Left Capture PGA" },
{ "Left Boost Mixer", "L2 Volume", "L2" },
@@ -522,6 +556,38 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
{ "Left Input Mixer", "MicN Switch", "LIN" },
{ "Left Input Mixer", "MicP Switch", "LIP" },
};
+static const struct snd_soc_dapm_route wm8985_aux_dapm_routes[] = {
+ { "Right Output Mixer", "Aux Switch", "AUXR" },
+ { "Left Output Mixer", "Aux Switch", "AUXL" },
+
+ { "Right Boost Mixer", "AUXR Volume", "AUXR" },
+ { "Left Boost Mixer", "AUXL Volume", "AUXL" },
+};
+
+static int wm8985_add_widgets(struct snd_soc_codec *codec)
+{
+ struct wm8985_priv *wm8985 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+
+ switch (wm8985->dev_type) {
+ case WM8758:
+ snd_soc_dapm_new_controls(dapm, wm8758_dapm_widgets,
+ ARRAY_SIZE(wm8758_dapm_widgets));
+ break;
+
+ case WM8985:
+ snd_soc_add_codec_controls(codec, wm8985_specific_snd_controls,
+ ARRAY_SIZE(wm8985_specific_snd_controls));
+
+ snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
+ ARRAY_SIZE(wm8985_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, wm8985_aux_dapm_routes,
+ ARRAY_SIZE(wm8985_aux_dapm_routes));
+ break;
+ }
+
+ return 0;
+}
static int eqmode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -999,6 +1065,8 @@ static int wm8985_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT,
WM8985_BIASCUT);
+ wm8985_add_widgets(codec);
+
return 0;
err_reg_enable:
@@ -1042,12 +1110,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
.set_bias_level = wm8985_set_bias_level,
.suspend_bias_off = true,
- .controls = wm8985_snd_controls,
- .num_controls = ARRAY_SIZE(wm8985_snd_controls),
- .dapm_widgets = wm8985_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets),
- .dapm_routes = wm8985_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes),
+ .controls = wm8985_common_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8985_common_snd_controls),
+ .dapm_widgets = wm8985_common_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets),
+ .dapm_routes = wm8985_common_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes),
};
static const struct regmap_config wm8985_regmap = {
@@ -1074,6 +1142,8 @@ static int wm8985_spi_probe(struct spi_device *spi)
spi_set_drvdata(spi, wm8985);
+ wm8985->dev_type = WM8985;
+
wm8985->regmap = devm_regmap_init_spi(spi, &wm8985_regmap);
if (IS_ERR(wm8985->regmap)) {
ret = PTR_ERR(wm8985->regmap);
@@ -1115,6 +1185,8 @@ static int wm8985_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm8985);
+ wm8985->dev_type = id->driver_data;
+
wm8985->regmap = devm_regmap_init_i2c(i2c, &wm8985_regmap);
if (IS_ERR(wm8985->regmap)) {
ret = PTR_ERR(wm8985->regmap);
@@ -1135,7 +1207,8 @@ static int wm8985_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id wm8985_i2c_id[] = {
- { "wm8985", 0 },
+ { "wm8985", WM8985 },
+ { "wm8758", WM8758 },
{ }
};
MODULE_DEVICE_TABLE(i2c, wm8985_i2c_id);
@@ -1183,6 +1256,6 @@ static void __exit wm8985_exit(void)
}
module_exit(wm8985_exit);
-MODULE_DESCRIPTION("ASoC WM8985 driver");
+MODULE_DESCRIPTION("ASoC WM8985 / WM8758 driver");
MODULE_AUTHOR("Dimitris Papastamos <dp(a)opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
--
2.5.0
1
0
[alsa-devel] [PATCH 1/2] ASoC: tas571x: add biquad registers for TAS5717/19
by Petr Kulhavy 26 May '16
by Petr Kulhavy 26 May '16
26 May '16
Add biquad register definitions for TAS5717/19.
Signed-off-by: Petr Kulhavy <brain(a)jikos.cz>
---
sound/soc/codecs/tas571x.h | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/sound/soc/codecs/tas571x.h b/sound/soc/codecs/tas571x.h
index cf800c3..bf4d436 100644
--- a/sound/soc/codecs/tas571x.h
+++ b/sound/soc/codecs/tas571x.h
@@ -52,4 +52,39 @@
#define TAS571X_CH4_SRC_SELECT_REG 0x21
#define TAS571X_PWM_MUX_REG 0x25
+/* 20-byte biquad registers */
+#define TAS5717_CH1_BQ0_REG 0x26
+#define TAS5717_CH1_BQ1_REG 0x27
+#define TAS5717_CH1_BQ2_REG 0x28
+#define TAS5717_CH1_BQ3_REG 0x29
+#define TAS5717_CH1_BQ4_REG 0x2a
+#define TAS5717_CH1_BQ5_REG 0x2b
+#define TAS5717_CH1_BQ6_REG 0x2c
+#define TAS5717_CH1_BQ7_REG 0x2d
+#define TAS5717_CH1_BQ8_REG 0x2e
+#define TAS5717_CH1_BQ9_REG 0x2f
+
+#define TAS5717_CH2_BQ0_REG 0x30
+#define TAS5717_CH2_BQ1_REG 0x31
+#define TAS5717_CH2_BQ2_REG 0x32
+#define TAS5717_CH2_BQ3_REG 0x33
+#define TAS5717_CH2_BQ4_REG 0x34
+#define TAS5717_CH2_BQ5_REG 0x35
+#define TAS5717_CH2_BQ6_REG 0x36
+#define TAS5717_CH2_BQ7_REG 0x37
+#define TAS5717_CH2_BQ8_REG 0x38
+#define TAS5717_CH2_BQ9_REG 0x39
+
+#define TAS5717_CH1_BQ10_REG 0x58
+#define TAS5717_CH1_BQ11_REG 0x59
+
+#define TAS5717_CH4_BQ0_REG 0x5a
+#define TAS5717_CH4_BQ1_REG 0x5b
+
+#define TAS5717_CH2_BQ10_REG 0x5c
+#define TAS5717_CH2_BQ11_REG 0x5d
+
+#define TAS5717_CH3_BQ0_REG 0x5e
+#define TAS5717_CH3_BQ1_REG 0x5f
+
#endif /* _TAS571X_H */
--
2.5.0
1
1