brintos

brintos / linux-shallow public Read only

0
0
Text · 33.9 KiB · 252b4a6 Raw
1112 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * wm8983.c  --  WM8983 ALSA SoC Audio driver4 *5 * Copyright 2011 Wolfson Microelectronics plc6 *7 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>8 */9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/init.h>13#include <linux/delay.h>14#include <linux/pm.h>15#include <linux/i2c.h>16#include <linux/regmap.h>17#include <linux/spi/spi.h>18#include <linux/slab.h>19#include <sound/core.h>20#include <sound/pcm.h>21#include <sound/pcm_params.h>22#include <sound/soc.h>23#include <sound/initval.h>24#include <sound/tlv.h>25 26#include "wm8983.h"27 28static const struct reg_default wm8983_defaults[] = {29	{ 0x01, 0x0000 },     /* R1  - Power management 1 */30	{ 0x02, 0x0000 },     /* R2  - Power management 2 */31	{ 0x03, 0x0000 },     /* R3  - Power management 3 */32	{ 0x04, 0x0050 },     /* R4  - Audio Interface */33	{ 0x05, 0x0000 },     /* R5  - Companding control */34	{ 0x06, 0x0140 },     /* R6  - Clock Gen control */35	{ 0x07, 0x0000 },     /* R7  - Additional control */36	{ 0x08, 0x0000 },     /* R8  - GPIO Control */37	{ 0x09, 0x0000 },     /* R9  - Jack Detect Control 1 */38	{ 0x0A, 0x0000 },     /* R10 - DAC Control */39	{ 0x0B, 0x00FF },     /* R11 - Left DAC digital Vol */40	{ 0x0C, 0x00FF },     /* R12 - Right DAC digital vol */41	{ 0x0D, 0x0000 },     /* R13 - Jack Detect Control 2 */42	{ 0x0E, 0x0100 },     /* R14 - ADC Control */43	{ 0x0F, 0x00FF },     /* R15 - Left ADC Digital Vol */44	{ 0x10, 0x00FF },     /* R16 - Right ADC Digital Vol */45	{ 0x12, 0x012C },     /* R18 - EQ1 - low shelf */46	{ 0x13, 0x002C },     /* R19 - EQ2 - peak 1 */47	{ 0x14, 0x002C },     /* R20 - EQ3 - peak 2 */48	{ 0x15, 0x002C },     /* R21 - EQ4 - peak 3 */49	{ 0x16, 0x002C },     /* R22 - EQ5 - high shelf */50	{ 0x18, 0x0032 },     /* R24 - DAC Limiter 1 */51	{ 0x19, 0x0000 },     /* R25 - DAC Limiter 2 */52	{ 0x1B, 0x0000 },     /* R27 - Notch Filter 1 */53	{ 0x1C, 0x0000 },     /* R28 - Notch Filter 2 */54	{ 0x1D, 0x0000 },     /* R29 - Notch Filter 3 */55	{ 0x1E, 0x0000 },     /* R30 - Notch Filter 4 */56	{ 0x20, 0x0038 },     /* R32 - ALC control 1 */57	{ 0x21, 0x000B },     /* R33 - ALC control 2 */58	{ 0x22, 0x0032 },     /* R34 - ALC control 3 */59	{ 0x23, 0x0000 },     /* R35 - Noise Gate */60	{ 0x24, 0x0008 },     /* R36 - PLL N */61	{ 0x25, 0x000C },     /* R37 - PLL K 1 */62	{ 0x26, 0x0093 },     /* R38 - PLL K 2 */63	{ 0x27, 0x00E9 },     /* R39 - PLL K 3 */64	{ 0x29, 0x0000 },     /* R41 - 3D control */65	{ 0x2A, 0x0000 },     /* R42 - OUT4 to ADC */66	{ 0x2B, 0x0000 },     /* R43 - Beep control */67	{ 0x2C, 0x0033 },     /* R44 - Input ctrl */68	{ 0x2D, 0x0010 },     /* R45 - Left INP PGA gain ctrl */69	{ 0x2E, 0x0010 },     /* R46 - Right INP PGA gain ctrl */70	{ 0x2F, 0x0100 },     /* R47 - Left ADC BOOST ctrl */71	{ 0x30, 0x0100 },     /* R48 - Right ADC BOOST ctrl */72	{ 0x31, 0x0002 },     /* R49 - Output ctrl */73	{ 0x32, 0x0001 },     /* R50 - Left mixer ctrl */74	{ 0x33, 0x0001 },     /* R51 - Right mixer ctrl */75	{ 0x34, 0x0039 },     /* R52 - LOUT1 (HP) volume ctrl */76	{ 0x35, 0x0039 },     /* R53 - ROUT1 (HP) volume ctrl */77	{ 0x36, 0x0039 },     /* R54 - LOUT2 (SPK) volume ctrl */78	{ 0x37, 0x0039 },     /* R55 - ROUT2 (SPK) volume ctrl */79	{ 0x38, 0x0001 },     /* R56 - OUT3 mixer ctrl */80	{ 0x39, 0x0001 },     /* R57 - OUT4 (MONO) mix ctrl */81	{ 0x3D, 0x0000 },      /* R61 - BIAS CTRL */82};83 84/* vol/gain update regs */85static const int vol_update_regs[] = {86	WM8983_LEFT_DAC_DIGITAL_VOL,87	WM8983_RIGHT_DAC_DIGITAL_VOL,88	WM8983_LEFT_ADC_DIGITAL_VOL,89	WM8983_RIGHT_ADC_DIGITAL_VOL,90	WM8983_LOUT1_HP_VOLUME_CTRL,91	WM8983_ROUT1_HP_VOLUME_CTRL,92	WM8983_LOUT2_SPK_VOLUME_CTRL,93	WM8983_ROUT2_SPK_VOLUME_CTRL,94	WM8983_LEFT_INP_PGA_GAIN_CTRL,95	WM8983_RIGHT_INP_PGA_GAIN_CTRL96};97 98struct wm8983_priv {99	struct regmap *regmap;100	u32 sysclk;101	u32 bclk;102};103 104static const struct {105	int div;106	int ratio;107} fs_ratios[] = {108	{ 10, 128 },109	{ 15, 192 },110	{ 20, 256 },111	{ 30, 384 },112	{ 40, 512 },113	{ 60, 768 },114	{ 80, 1024 },115	{ 120, 1536 }116};117 118static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 };119 120static const int bclk_divs[] = {121	1, 2, 4, 8, 16, 32122};123 124static int eqmode_get(struct snd_kcontrol *kcontrol,125		      struct snd_ctl_elem_value *ucontrol);126static int eqmode_put(struct snd_kcontrol *kcontrol,127		      struct snd_ctl_elem_value *ucontrol);128 129static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);130static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1);131static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);132static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0);133static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0);134static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0);135static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0);136static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0);137static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0);138static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1);139static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);140static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0);141static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);142static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);143 144static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };145static SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, alc_sel_text);146 147static const char *alc_mode_text[] = { "ALC", "Limiter" };148static SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, alc_mode_text);149 150static const char *filter_mode_text[] = { "Audio", "Application" };151static SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7,152			    filter_mode_text);153 154static const char *eq_bw_text[] = { "Narrow", "Wide" };155static const char *eqmode_text[] = { "Capture", "Playback" };156static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);157 158static const char *eq1_cutoff_text[] = {159	"80Hz", "105Hz", "135Hz", "175Hz"160};161static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5,162			    eq1_cutoff_text);163static const char *eq2_cutoff_text[] = {164	"230Hz", "300Hz", "385Hz", "500Hz"165};166static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text);167static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, eq2_cutoff_text);168static const char *eq3_cutoff_text[] = {169	"650Hz", "850Hz", "1.1kHz", "1.4kHz"170};171static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text);172static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, eq3_cutoff_text);173static const char *eq4_cutoff_text[] = {174	"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"175};176static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text);177static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, eq4_cutoff_text);178static const char *eq5_cutoff_text[] = {179	"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"180};181static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5,182			    eq5_cutoff_text);183 184static const char *depth_3d_text[] = {185	"Off",186	"6.67%",187	"13.3%",188	"20%",189	"26.7%",190	"33.3%",191	"40%",192	"46.6%",193	"53.3%",194	"60%",195	"66.7%",196	"73.3%",197	"80%",198	"86.7%",199	"93.3%",200	"100%"201};202static SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0,203			    depth_3d_text);204 205static const struct snd_kcontrol_new wm8983_snd_controls[] = {206	SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL,207		   0, 1, 0),208 209	SOC_ENUM("ALC Capture Function", alc_sel),210	SOC_SINGLE_TLV("ALC Capture Max Volume", WM8983_ALC_CONTROL_1,211		       3, 7, 0, alc_max_tlv),212	SOC_SINGLE_TLV("ALC Capture Min Volume", WM8983_ALC_CONTROL_1,213		       0, 7, 0, alc_min_tlv),214	SOC_SINGLE_TLV("ALC Capture Target Volume", WM8983_ALC_CONTROL_2,215		       0, 15, 0, alc_tar_tlv),216	SOC_SINGLE("ALC Capture Attack", WM8983_ALC_CONTROL_3, 0, 10, 0),217	SOC_SINGLE("ALC Capture Hold", WM8983_ALC_CONTROL_2, 4, 10, 0),218	SOC_SINGLE("ALC Capture Decay", WM8983_ALC_CONTROL_3, 4, 10, 0),219	SOC_ENUM("ALC Mode", alc_mode),220	SOC_SINGLE("ALC Capture NG Switch", WM8983_NOISE_GATE,221		   3, 1, 0),222	SOC_SINGLE("ALC Capture NG Threshold", WM8983_NOISE_GATE,223		   0, 7, 1),224 225	SOC_DOUBLE_R_TLV("Capture Volume", WM8983_LEFT_ADC_DIGITAL_VOL,226			 WM8983_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv),227	SOC_DOUBLE_R("Capture PGA ZC Switch", WM8983_LEFT_INP_PGA_GAIN_CTRL,228		     WM8983_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0),229	SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8983_LEFT_INP_PGA_GAIN_CTRL,230			 WM8983_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv),231 232	SOC_DOUBLE_R_TLV("Capture PGA Boost Volume",233			 WM8983_LEFT_ADC_BOOST_CTRL, WM8983_RIGHT_ADC_BOOST_CTRL,234			 8, 1, 0, pga_boost_tlv),235 236	SOC_DOUBLE("ADC Inversion Switch", WM8983_ADC_CONTROL, 0, 1, 1, 0),237	SOC_SINGLE("ADC 128x Oversampling Switch", WM8983_ADC_CONTROL, 8, 1, 0),238 239	SOC_DOUBLE_R_TLV("Playback Volume", WM8983_LEFT_DAC_DIGITAL_VOL,240			 WM8983_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv),241 242	SOC_SINGLE("DAC Playback Limiter Switch", WM8983_DAC_LIMITER_1, 8, 1, 0),243	SOC_SINGLE("DAC Playback Limiter Decay", WM8983_DAC_LIMITER_1, 4, 10, 0),244	SOC_SINGLE("DAC Playback Limiter Attack", WM8983_DAC_LIMITER_1, 0, 11, 0),245	SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8983_DAC_LIMITER_2,246		       4, 7, 1, lim_thresh_tlv),247	SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8983_DAC_LIMITER_2,248		       0, 12, 0, lim_boost_tlv),249	SOC_DOUBLE("DAC Inversion Switch", WM8983_DAC_CONTROL, 0, 1, 1, 0),250	SOC_SINGLE("DAC Auto Mute Switch", WM8983_DAC_CONTROL, 2, 1, 0),251	SOC_SINGLE("DAC 128x Oversampling Switch", WM8983_DAC_CONTROL, 3, 1, 0),252 253	SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8983_LOUT1_HP_VOLUME_CTRL,254			 WM8983_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv),255	SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8983_LOUT1_HP_VOLUME_CTRL,256		     WM8983_ROUT1_HP_VOLUME_CTRL, 7, 1, 0),257	SOC_DOUBLE_R("Headphone Switch", WM8983_LOUT1_HP_VOLUME_CTRL,258		     WM8983_ROUT1_HP_VOLUME_CTRL, 6, 1, 1),259 260	SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8983_LOUT2_SPK_VOLUME_CTRL,261			 WM8983_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv),262	SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8983_LOUT2_SPK_VOLUME_CTRL,263		     WM8983_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0),264	SOC_DOUBLE_R("Speaker Switch", WM8983_LOUT2_SPK_VOLUME_CTRL,265		     WM8983_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1),266 267	SOC_SINGLE("OUT3 Switch", WM8983_OUT3_MIXER_CTRL,268		   6, 1, 1),269 270	SOC_SINGLE("OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,271		   6, 1, 1),272 273	SOC_SINGLE("High Pass Filter Switch", WM8983_ADC_CONTROL, 8, 1, 0),274	SOC_ENUM("High Pass Filter Mode", filter_mode),275	SOC_SINGLE("High Pass Filter Cutoff", WM8983_ADC_CONTROL, 4, 7, 0),276 277	SOC_DOUBLE_R_TLV("Aux Bypass Volume",278			 WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 6, 7, 0,279			 aux_tlv),280 281	SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",282			 WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 2, 7, 0,283			 bypass_tlv),284 285	SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),286	SOC_ENUM("EQ1 Cutoff", eq1_cutoff),287	SOC_SINGLE_TLV("EQ1 Volume", WM8983_EQ1_LOW_SHELF,  0, 24, 1, eq_tlv),288	SOC_ENUM("EQ2 Bandwidth", eq2_bw),289	SOC_ENUM("EQ2 Cutoff", eq2_cutoff),290	SOC_SINGLE_TLV("EQ2 Volume", WM8983_EQ2_PEAK_1, 0, 24, 1, eq_tlv),291	SOC_ENUM("EQ3 Bandwidth", eq3_bw),292	SOC_ENUM("EQ3 Cutoff", eq3_cutoff),293	SOC_SINGLE_TLV("EQ3 Volume", WM8983_EQ3_PEAK_2, 0, 24, 1, eq_tlv),294	SOC_ENUM("EQ4 Bandwidth", eq4_bw),295	SOC_ENUM("EQ4 Cutoff", eq4_cutoff),296	SOC_SINGLE_TLV("EQ4 Volume", WM8983_EQ4_PEAK_3, 0, 24, 1, eq_tlv),297	SOC_ENUM("EQ5 Cutoff", eq5_cutoff),298	SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),299 300	SOC_ENUM("3D Depth", depth_3d),301};302 303static const struct snd_kcontrol_new left_out_mixer[] = {304	SOC_DAPM_SINGLE("Line Switch", WM8983_LEFT_MIXER_CTRL, 1, 1, 0),305	SOC_DAPM_SINGLE("Aux Switch", WM8983_LEFT_MIXER_CTRL, 5, 1, 0),306	SOC_DAPM_SINGLE("PCM Switch", WM8983_LEFT_MIXER_CTRL, 0, 1, 0),307};308 309static const struct snd_kcontrol_new right_out_mixer[] = {310	SOC_DAPM_SINGLE("Line Switch", WM8983_RIGHT_MIXER_CTRL, 1, 1, 0),311	SOC_DAPM_SINGLE("Aux Switch", WM8983_RIGHT_MIXER_CTRL, 5, 1, 0),312	SOC_DAPM_SINGLE("PCM Switch", WM8983_RIGHT_MIXER_CTRL, 0, 1, 0),313};314 315static const struct snd_kcontrol_new left_input_mixer[] = {316	SOC_DAPM_SINGLE("L2 Switch", WM8983_INPUT_CTRL, 2, 1, 0),317	SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 1, 1, 0),318	SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 0, 1, 0),319};320 321static const struct snd_kcontrol_new right_input_mixer[] = {322	SOC_DAPM_SINGLE("R2 Switch", WM8983_INPUT_CTRL, 6, 1, 0),323	SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 5, 1, 0),324	SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 4, 1, 0),325};326 327static const struct snd_kcontrol_new left_boost_mixer[] = {328	SOC_DAPM_SINGLE_TLV("L2 Volume", WM8983_LEFT_ADC_BOOST_CTRL,329			    4, 7, 0, boost_tlv),330	SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8983_LEFT_ADC_BOOST_CTRL,331			    0, 7, 0, boost_tlv)332};333 334static const struct snd_kcontrol_new out3_mixer[] = {335	SOC_DAPM_SINGLE("LMIX2OUT3 Switch", WM8983_OUT3_MIXER_CTRL,336			1, 1, 0),337	SOC_DAPM_SINGLE("LDAC2OUT3 Switch", WM8983_OUT3_MIXER_CTRL,338			0, 1, 0),339};340 341static const struct snd_kcontrol_new out4_mixer[] = {342	SOC_DAPM_SINGLE("LMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,343			4, 1, 0),344	SOC_DAPM_SINGLE("RMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,345			1, 1, 0),346	SOC_DAPM_SINGLE("LDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,347			3, 1, 0),348	SOC_DAPM_SINGLE("RDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,349			0, 1, 0),350};351 352static const struct snd_kcontrol_new right_boost_mixer[] = {353	SOC_DAPM_SINGLE_TLV("R2 Volume", WM8983_RIGHT_ADC_BOOST_CTRL,354			    4, 7, 0, boost_tlv),355	SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8983_RIGHT_ADC_BOOST_CTRL,356			    0, 7, 0, boost_tlv)357};358 359static const struct snd_soc_dapm_widget wm8983_dapm_widgets[] = {360	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8983_POWER_MANAGEMENT_3,361			 0, 0),362	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8983_POWER_MANAGEMENT_3,363			 1, 0),364	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8983_POWER_MANAGEMENT_2,365			 0, 0),366	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8983_POWER_MANAGEMENT_2,367			 1, 0),368 369	SND_SOC_DAPM_MIXER("Left Output Mixer", WM8983_POWER_MANAGEMENT_3,370			   2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),371	SND_SOC_DAPM_MIXER("Right Output Mixer", WM8983_POWER_MANAGEMENT_3,372			   3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),373 374	SND_SOC_DAPM_MIXER("Left Input Mixer", WM8983_POWER_MANAGEMENT_2,375			   2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),376	SND_SOC_DAPM_MIXER("Right Input Mixer", WM8983_POWER_MANAGEMENT_2,377			   3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),378 379	SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8983_POWER_MANAGEMENT_2,380			   4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),381	SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8983_POWER_MANAGEMENT_2,382			   5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),383 384	SND_SOC_DAPM_MIXER("OUT3 Mixer", WM8983_POWER_MANAGEMENT_1,385			   6, 0, out3_mixer, ARRAY_SIZE(out3_mixer)),386 387	SND_SOC_DAPM_MIXER("OUT4 Mixer", WM8983_POWER_MANAGEMENT_1,388			   7, 0, out4_mixer, ARRAY_SIZE(out4_mixer)),389 390	SND_SOC_DAPM_PGA("Left Capture PGA", WM8983_LEFT_INP_PGA_GAIN_CTRL,391			 6, 1, NULL, 0),392	SND_SOC_DAPM_PGA("Right Capture PGA", WM8983_RIGHT_INP_PGA_GAIN_CTRL,393			 6, 1, NULL, 0),394 395	SND_SOC_DAPM_PGA("Left Headphone Out", WM8983_POWER_MANAGEMENT_2,396			 7, 0, NULL, 0),397	SND_SOC_DAPM_PGA("Right Headphone Out", WM8983_POWER_MANAGEMENT_2,398			 8, 0, NULL, 0),399 400	SND_SOC_DAPM_PGA("Left Speaker Out", WM8983_POWER_MANAGEMENT_3,401			 5, 0, NULL, 0),402	SND_SOC_DAPM_PGA("Right Speaker Out", WM8983_POWER_MANAGEMENT_3,403			 6, 0, NULL, 0),404 405	SND_SOC_DAPM_PGA("OUT3 Out", WM8983_POWER_MANAGEMENT_3,406			 7, 0, NULL, 0),407 408	SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3,409			 8, 0, NULL, 0),410 411	SND_SOC_DAPM_SUPPLY("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0,412			    NULL, 0),413 414	SND_SOC_DAPM_INPUT("LIN"),415	SND_SOC_DAPM_INPUT("LIP"),416	SND_SOC_DAPM_INPUT("RIN"),417	SND_SOC_DAPM_INPUT("RIP"),418	SND_SOC_DAPM_INPUT("AUXL"),419	SND_SOC_DAPM_INPUT("AUXR"),420	SND_SOC_DAPM_INPUT("L2"),421	SND_SOC_DAPM_INPUT("R2"),422	SND_SOC_DAPM_OUTPUT("HPL"),423	SND_SOC_DAPM_OUTPUT("HPR"),424	SND_SOC_DAPM_OUTPUT("SPKL"),425	SND_SOC_DAPM_OUTPUT("SPKR"),426	SND_SOC_DAPM_OUTPUT("OUT3"),427	SND_SOC_DAPM_OUTPUT("OUT4")428};429 430static const struct snd_soc_dapm_route wm8983_audio_map[] = {431	{ "OUT3 Mixer", "LMIX2OUT3 Switch", "Left Output Mixer" },432	{ "OUT3 Mixer", "LDAC2OUT3 Switch", "Left DAC" },433 434	{ "OUT3 Out", NULL, "OUT3 Mixer" },435	{ "OUT3", NULL, "OUT3 Out" },436 437	{ "OUT4 Mixer", "LMIX2OUT4 Switch", "Left Output Mixer" },438	{ "OUT4 Mixer", "RMIX2OUT4 Switch", "Right Output Mixer" },439	{ "OUT4 Mixer", "LDAC2OUT4 Switch", "Left DAC" },440	{ "OUT4 Mixer", "RDAC2OUT4 Switch", "Right DAC" },441 442	{ "OUT4 Out", NULL, "OUT4 Mixer" },443	{ "OUT4", NULL, "OUT4 Out" },444 445	{ "Right Output Mixer", "PCM Switch", "Right DAC" },446	{ "Right Output Mixer", "Aux Switch", "AUXR" },447	{ "Right Output Mixer", "Line Switch", "Right Boost Mixer" },448 449	{ "Left Output Mixer", "PCM Switch", "Left DAC" },450	{ "Left Output Mixer", "Aux Switch", "AUXL" },451	{ "Left Output Mixer", "Line Switch", "Left Boost Mixer" },452 453	{ "Right Headphone Out", NULL, "Right Output Mixer" },454	{ "HPR", NULL, "Right Headphone Out" },455 456	{ "Left Headphone Out", NULL, "Left Output Mixer" },457	{ "HPL", NULL, "Left Headphone Out" },458 459	{ "Right Speaker Out", NULL, "Right Output Mixer" },460	{ "SPKR", NULL, "Right Speaker Out" },461 462	{ "Left Speaker Out", NULL, "Left Output Mixer" },463	{ "SPKL", NULL, "Left Speaker Out" },464 465	{ "Right ADC", NULL, "Right Boost Mixer" },466 467	{ "Right Boost Mixer", "AUXR Volume", "AUXR" },468	{ "Right Boost Mixer", NULL, "Right Capture PGA" },469	{ "Right Boost Mixer", "R2 Volume", "R2" },470 471	{ "Left ADC", NULL, "Left Boost Mixer" },472 473	{ "Left Boost Mixer", "AUXL Volume", "AUXL" },474	{ "Left Boost Mixer", NULL, "Left Capture PGA" },475	{ "Left Boost Mixer", "L2 Volume", "L2" },476 477	{ "Right Capture PGA", NULL, "Right Input Mixer" },478	{ "Left Capture PGA", NULL, "Left Input Mixer" },479 480	{ "Right Input Mixer", "R2 Switch", "R2" },481	{ "Right Input Mixer", "MicN Switch", "RIN" },482	{ "Right Input Mixer", "MicP Switch", "RIP" },483 484	{ "Left Input Mixer", "L2 Switch", "L2" },485	{ "Left Input Mixer", "MicN Switch", "LIN" },486	{ "Left Input Mixer", "MicP Switch", "LIP" },487};488 489static int eqmode_get(struct snd_kcontrol *kcontrol,490		      struct snd_ctl_elem_value *ucontrol)491{492	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);493	unsigned int reg;494 495	reg = snd_soc_component_read(component, WM8983_EQ1_LOW_SHELF);496	if (reg & WM8983_EQ3DMODE)497		ucontrol->value.enumerated.item[0] = 1;498	else499		ucontrol->value.enumerated.item[0] = 0;500 501	return 0;502}503 504static int eqmode_put(struct snd_kcontrol *kcontrol,505		      struct snd_ctl_elem_value *ucontrol)506{507	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);508	unsigned int regpwr2, regpwr3;509	unsigned int reg_eq;510 511	if (ucontrol->value.enumerated.item[0] != 0512	    && ucontrol->value.enumerated.item[0] != 1)513		return -EINVAL;514 515	reg_eq = snd_soc_component_read(component, WM8983_EQ1_LOW_SHELF);516	switch ((reg_eq & WM8983_EQ3DMODE) >> WM8983_EQ3DMODE_SHIFT) {517	case 0:518		if (!ucontrol->value.enumerated.item[0])519			return 0;520		break;521	case 1:522		if (ucontrol->value.enumerated.item[0])523			return 0;524		break;525	}526 527	regpwr2 = snd_soc_component_read(component, WM8983_POWER_MANAGEMENT_2);528	regpwr3 = snd_soc_component_read(component, WM8983_POWER_MANAGEMENT_3);529	/* disable the DACs and ADCs */530	snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_2,531			    WM8983_ADCENR_MASK | WM8983_ADCENL_MASK, 0);532	snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_3,533			    WM8983_DACENR_MASK | WM8983_DACENL_MASK, 0);534	/* set the desired eqmode */535	snd_soc_component_update_bits(component, WM8983_EQ1_LOW_SHELF,536			    WM8983_EQ3DMODE_MASK,537			    ucontrol->value.enumerated.item[0]538			    << WM8983_EQ3DMODE_SHIFT);539	/* restore DAC/ADC configuration */540	snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_2, regpwr2);541	snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_3, regpwr3);542	return 0;543}544 545static bool wm8983_writeable(struct device *dev, unsigned int reg)546{547	switch (reg) {548	case WM8983_SOFTWARE_RESET ... WM8983_RIGHT_ADC_DIGITAL_VOL:549	case WM8983_EQ1_LOW_SHELF ... WM8983_DAC_LIMITER_2:550	case WM8983_NOTCH_FILTER_1 ... WM8983_NOTCH_FILTER_4:551	case WM8983_ALC_CONTROL_1 ... WM8983_PLL_K_3:552	case WM8983_3D_CONTROL ... WM8983_OUT4_MONO_MIX_CTRL:553	case WM8983_BIAS_CTRL:554		return true;555	default:556		return false;557	}558}559 560static int wm8983_dac_mute(struct snd_soc_dai *dai, int mute, int direction)561{562	struct snd_soc_component *component = dai->component;563 564	return snd_soc_component_update_bits(component, WM8983_DAC_CONTROL,565				   WM8983_SOFTMUTE_MASK,566				   !!mute << WM8983_SOFTMUTE_SHIFT);567}568 569static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)570{571	struct snd_soc_component *component = dai->component;572	u16 format, master, bcp, lrp;573 574	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {575	case SND_SOC_DAIFMT_I2S:576		format = 0x2;577		break;578	case SND_SOC_DAIFMT_RIGHT_J:579		format = 0x0;580		break;581	case SND_SOC_DAIFMT_LEFT_J:582		format = 0x1;583		break;584	case SND_SOC_DAIFMT_DSP_A:585	case SND_SOC_DAIFMT_DSP_B:586		format = 0x3;587		break;588	default:589		dev_err(dai->dev, "Unknown dai format\n");590		return -EINVAL;591	}592 593	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,594			    WM8983_FMT_MASK, format << WM8983_FMT_SHIFT);595 596	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {597	case SND_SOC_DAIFMT_CBM_CFM:598		master = 1;599		break;600	case SND_SOC_DAIFMT_CBS_CFS:601		master = 0;602		break;603	default:604		dev_err(dai->dev, "Unknown master/slave configuration\n");605		return -EINVAL;606	}607 608	snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,609			    WM8983_MS_MASK, master << WM8983_MS_SHIFT);610 611	/* FIXME: We don't currently support DSP A/B modes */612	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {613	case SND_SOC_DAIFMT_DSP_A:614	case SND_SOC_DAIFMT_DSP_B:615		dev_err(dai->dev, "DSP A/B modes are not supported\n");616		return -EINVAL;617	default:618		break;619	}620 621	bcp = lrp = 0;622	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {623	case SND_SOC_DAIFMT_NB_NF:624		break;625	case SND_SOC_DAIFMT_IB_IF:626		bcp = lrp = 1;627		break;628	case SND_SOC_DAIFMT_IB_NF:629		bcp = 1;630		break;631	case SND_SOC_DAIFMT_NB_IF:632		lrp = 1;633		break;634	default:635		dev_err(dai->dev, "Unknown polarity configuration\n");636		return -EINVAL;637	}638 639	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,640			    WM8983_LRCP_MASK, lrp << WM8983_LRCP_SHIFT);641	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,642			    WM8983_BCP_MASK, bcp << WM8983_BCP_SHIFT);643	return 0;644}645 646static int wm8983_hw_params(struct snd_pcm_substream *substream,647			    struct snd_pcm_hw_params *params,648			    struct snd_soc_dai *dai)649{650	int i;651	struct snd_soc_component *component = dai->component;652	struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component);653	u16 blen, srate_idx;654	u32 tmp;655	int srate_best;656	int ret;657 658	ret = snd_soc_params_to_bclk(params);659	if (ret < 0) {660		dev_err(component->dev, "Failed to convert params to bclk: %d\n", ret);661		return ret;662	}663 664	wm8983->bclk = ret;665 666	switch (params_width(params)) {667	case 16:668		blen = 0x0;669		break;670	case 20:671		blen = 0x1;672		break;673	case 24:674		blen = 0x2;675		break;676	case 32:677		blen = 0x3;678		break;679	default:680		dev_err(dai->dev, "Unsupported word length %u\n",681			params_width(params));682		return -EINVAL;683	}684 685	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,686			    WM8983_WL_MASK, blen << WM8983_WL_SHIFT);687 688	/*689	 * match to the nearest possible sample rate and rely690	 * on the array index to configure the SR register691	 */692	srate_idx = 0;693	srate_best = abs(srates[0] - params_rate(params));694	for (i = 1; i < ARRAY_SIZE(srates); ++i) {695		if (abs(srates[i] - params_rate(params)) >= srate_best)696			continue;697		srate_idx = i;698		srate_best = abs(srates[i] - params_rate(params));699	}700 701	dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);702	snd_soc_component_update_bits(component, WM8983_ADDITIONAL_CONTROL,703			    WM8983_SR_MASK, srate_idx << WM8983_SR_SHIFT);704 705	dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8983->bclk);706	dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8983->sysclk);707 708	for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) {709		if (wm8983->sysclk / params_rate(params)710		    == fs_ratios[i].ratio)711			break;712	}713 714	if (i == ARRAY_SIZE(fs_ratios)) {715		dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n",716			wm8983->sysclk, params_rate(params));717		return -EINVAL;718	}719 720	dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);721	snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,722			    WM8983_MCLKDIV_MASK, i << WM8983_MCLKDIV_SHIFT);723 724	/* select the appropriate bclk divider */725	tmp = (wm8983->sysclk / fs_ratios[i].div) * 10;726	for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) {727		if (wm8983->bclk == tmp / bclk_divs[i])728			break;729	}730 731	if (i == ARRAY_SIZE(bclk_divs)) {732		dev_err(dai->dev, "No matching BCLK divider found\n");733		return -EINVAL;734	}735 736	dev_dbg(dai->dev, "BCLK div = %d\n", i);737	snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,738			    WM8983_BCLKDIV_MASK, i << WM8983_BCLKDIV_SHIFT);739 740	return 0;741}742 743struct pll_div {744	u32 div2:1;745	u32 n:4;746	u32 k:24;747};748 749#define FIXED_PLL_SIZE ((1ULL << 24) * 10)750static int pll_factors(struct pll_div *pll_div, unsigned int target,751		       unsigned int source)752{753	u64 Kpart;754	unsigned long int K, Ndiv, Nmod;755 756	pll_div->div2 = 0;757	Ndiv = target / source;758	if (Ndiv < 6) {759		source >>= 1;760		pll_div->div2 = 1;761		Ndiv = target / source;762	}763 764	if (Ndiv < 6 || Ndiv > 12) {765		printk(KERN_ERR "%s: WM8983 N value is not within"766		       " the recommended range: %lu\n", __func__, Ndiv);767		return -EINVAL;768	}769	pll_div->n = Ndiv;770 771	Nmod = target % source;772	Kpart = FIXED_PLL_SIZE * (u64)Nmod;773 774	do_div(Kpart, source);775 776	K = Kpart & 0xffffffff;777	if ((K % 10) >= 5)778		K += 5;779	K /= 10;780	pll_div->k = K;781	return 0;782}783 784static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,785			  int source, unsigned int freq_in,786			  unsigned int freq_out)787{788	int ret;789	struct snd_soc_component *component;790	struct pll_div pll_div;791 792	component = dai->component;793	if (!freq_in || !freq_out) {794		/* disable the PLL */795		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,796				    WM8983_PLLEN_MASK, 0);797		return 0;798	} else {799		ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);800		if (ret)801			return ret;802 803		/* disable the PLL before re-programming it */804		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,805				    WM8983_PLLEN_MASK, 0);806 807		/* set PLLN and PRESCALE */808		snd_soc_component_write(component, WM8983_PLL_N,809			(pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)810			| pll_div.n);811		/* set PLLK */812		snd_soc_component_write(component, WM8983_PLL_K_3, pll_div.k & 0x1ff);813		snd_soc_component_write(component, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);814		snd_soc_component_write(component, WM8983_PLL_K_1, (pll_div.k >> 18));815		/* enable the PLL */816		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,817					WM8983_PLLEN_MASK, WM8983_PLLEN);818	}819 820	return 0;821}822 823static int wm8983_set_sysclk(struct snd_soc_dai *dai,824			     int clk_id, unsigned int freq, int dir)825{826	struct snd_soc_component *component = dai->component;827	struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component);828 829	switch (clk_id) {830	case WM8983_CLKSRC_MCLK:831		snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,832				    WM8983_CLKSEL_MASK, 0);833		break;834	case WM8983_CLKSRC_PLL:835		snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,836				    WM8983_CLKSEL_MASK, WM8983_CLKSEL);837		break;838	default:839		dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);840		return -EINVAL;841	}842 843	wm8983->sysclk = freq;844	return 0;845}846 847static int wm8983_set_bias_level(struct snd_soc_component *component,848				 enum snd_soc_bias_level level)849{850	struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component);851	int ret;852 853	switch (level) {854	case SND_SOC_BIAS_ON:855	case SND_SOC_BIAS_PREPARE:856		/* VMID at 100k */857		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,858				    WM8983_VMIDSEL_MASK,859				    1 << WM8983_VMIDSEL_SHIFT);860		break;861	case SND_SOC_BIAS_STANDBY:862		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {863			ret = regcache_sync(wm8983->regmap);864			if (ret < 0) {865				dev_err(component->dev, "Failed to sync cache: %d\n", ret);866				return ret;867			}868			/* enable anti-pop features */869			snd_soc_component_update_bits(component, WM8983_OUT4_TO_ADC,870					    WM8983_POBCTRL_MASK | WM8983_DELEN_MASK,871					    WM8983_POBCTRL | WM8983_DELEN);872			/* enable thermal shutdown */873			snd_soc_component_update_bits(component, WM8983_OUTPUT_CTRL,874					    WM8983_TSDEN_MASK, WM8983_TSDEN);875			/* enable BIASEN */876			snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,877					    WM8983_BIASEN_MASK, WM8983_BIASEN);878			/* VMID at 100k */879			snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,880					    WM8983_VMIDSEL_MASK,881					    1 << WM8983_VMIDSEL_SHIFT);882			msleep(250);883			/* disable anti-pop features */884			snd_soc_component_update_bits(component, WM8983_OUT4_TO_ADC,885					    WM8983_POBCTRL_MASK |886					    WM8983_DELEN_MASK, 0);887		}888 889		/* VMID at 500k */890		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,891				    WM8983_VMIDSEL_MASK,892				    2 << WM8983_VMIDSEL_SHIFT);893		break;894	case SND_SOC_BIAS_OFF:895		/* disable thermal shutdown */896		snd_soc_component_update_bits(component, WM8983_OUTPUT_CTRL,897				    WM8983_TSDEN_MASK, 0);898		/* disable VMIDSEL and BIASEN */899		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,900				    WM8983_VMIDSEL_MASK | WM8983_BIASEN_MASK,901				    0);902		/* wait for VMID to discharge */903		msleep(100);904		snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_1, 0);905		snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_2, 0);906		snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_3, 0);907		break;908	}909 910	return 0;911}912 913static int wm8983_probe(struct snd_soc_component *component)914{915	int ret;916	int i;917 918	ret = snd_soc_component_write(component, WM8983_SOFTWARE_RESET, 0);919	if (ret < 0) {920		dev_err(component->dev, "Failed to issue reset: %d\n", ret);921		return ret;922	}923 924	/* set the vol/gain update bits */925	for (i = 0; i < ARRAY_SIZE(vol_update_regs); ++i)926		snd_soc_component_update_bits(component, vol_update_regs[i],927				    0x100, 0x100);928 929	/* mute all outputs and set PGAs to minimum gain */930	for (i = WM8983_LOUT1_HP_VOLUME_CTRL;931	     i <= WM8983_OUT4_MONO_MIX_CTRL; ++i)932		snd_soc_component_update_bits(component, i, 0x40, 0x40);933 934	/* enable soft mute */935	snd_soc_component_update_bits(component, WM8983_DAC_CONTROL,936			    WM8983_SOFTMUTE_MASK,937			    WM8983_SOFTMUTE);938 939	/* enable BIASCUT */940	snd_soc_component_update_bits(component, WM8983_BIAS_CTRL,941			    WM8983_BIASCUT, WM8983_BIASCUT);942	return 0;943}944 945static const struct snd_soc_dai_ops wm8983_dai_ops = {946	.mute_stream = wm8983_dac_mute,947	.hw_params = wm8983_hw_params,948	.set_fmt = wm8983_set_fmt,949	.set_sysclk = wm8983_set_sysclk,950	.set_pll = wm8983_set_pll,951	.no_capture_mute = 1,952};953 954#define WM8983_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \955			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)956 957static struct snd_soc_dai_driver wm8983_dai = {958	.name = "wm8983-hifi",959	.playback = {960		.stream_name = "Playback",961		.channels_min = 2,962		.channels_max = 2,963		.rates = SNDRV_PCM_RATE_8000_48000,964		.formats = WM8983_FORMATS,965	},966	.capture = {967		.stream_name = "Capture",968		.channels_min = 2,969		.channels_max = 2,970		.rates = SNDRV_PCM_RATE_8000_48000,971		.formats = WM8983_FORMATS,972	},973	.ops = &wm8983_dai_ops,974	.symmetric_rate = 1975};976 977static const struct snd_soc_component_driver soc_component_dev_wm8983 = {978	.probe			= wm8983_probe,979	.set_bias_level		= wm8983_set_bias_level,980	.controls		= wm8983_snd_controls,981	.num_controls		= ARRAY_SIZE(wm8983_snd_controls),982	.dapm_widgets		= wm8983_dapm_widgets,983	.num_dapm_widgets	= ARRAY_SIZE(wm8983_dapm_widgets),984	.dapm_routes		= wm8983_audio_map,985	.num_dapm_routes	= ARRAY_SIZE(wm8983_audio_map),986	.suspend_bias_off	= 1,987	.idle_bias_on		= 1,988	.use_pmdown_time	= 1,989	.endianness		= 1,990};991 992static const struct regmap_config wm8983_regmap = {993	.reg_bits = 7,994	.val_bits = 9,995 996	.reg_defaults = wm8983_defaults,997	.num_reg_defaults = ARRAY_SIZE(wm8983_defaults),998	.cache_type = REGCACHE_MAPLE,999	.max_register = WM8983_MAX_REGISTER,1000 1001	.writeable_reg = wm8983_writeable,1002};1003 1004#if defined(CONFIG_SPI_MASTER)1005static int wm8983_spi_probe(struct spi_device *spi)1006{1007	struct wm8983_priv *wm8983;1008	int ret;1009 1010	wm8983 = devm_kzalloc(&spi->dev, sizeof *wm8983, GFP_KERNEL);1011	if (!wm8983)1012		return -ENOMEM;1013 1014	wm8983->regmap = devm_regmap_init_spi(spi, &wm8983_regmap);1015	if (IS_ERR(wm8983->regmap)) {1016		ret = PTR_ERR(wm8983->regmap);1017		dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);1018		return ret;1019	}1020 1021	spi_set_drvdata(spi, wm8983);1022 1023	ret = devm_snd_soc_register_component(&spi->dev,1024				&soc_component_dev_wm8983, &wm8983_dai, 1);1025	return ret;1026}1027 1028static struct spi_driver wm8983_spi_driver = {1029	.driver = {1030		.name = "wm8983",1031	},1032	.probe = wm8983_spi_probe,1033};1034#endif1035 1036#if IS_ENABLED(CONFIG_I2C)1037static int wm8983_i2c_probe(struct i2c_client *i2c)1038{1039	struct wm8983_priv *wm8983;1040	int ret;1041 1042	wm8983 = devm_kzalloc(&i2c->dev, sizeof *wm8983, GFP_KERNEL);1043	if (!wm8983)1044		return -ENOMEM;1045 1046	wm8983->regmap = devm_regmap_init_i2c(i2c, &wm8983_regmap);1047	if (IS_ERR(wm8983->regmap)) {1048		ret = PTR_ERR(wm8983->regmap);1049		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);1050		return ret;1051	}1052 1053	i2c_set_clientdata(i2c, wm8983);1054 1055	ret = devm_snd_soc_register_component(&i2c->dev,1056				&soc_component_dev_wm8983, &wm8983_dai, 1);1057 1058	return ret;1059}1060 1061static const struct i2c_device_id wm8983_i2c_id[] = {1062	{ "wm8983" },1063	{ }1064};1065MODULE_DEVICE_TABLE(i2c, wm8983_i2c_id);1066 1067static struct i2c_driver wm8983_i2c_driver = {1068	.driver = {1069		.name = "wm8983",1070	},1071	.probe = wm8983_i2c_probe,1072	.id_table = wm8983_i2c_id1073};1074#endif1075 1076static int __init wm8983_modinit(void)1077{1078	int ret = 0;1079 1080#if IS_ENABLED(CONFIG_I2C)1081	ret = i2c_add_driver(&wm8983_i2c_driver);1082	if (ret) {1083		printk(KERN_ERR "Failed to register wm8983 I2C driver: %d\n",1084		       ret);1085	}1086#endif1087#if defined(CONFIG_SPI_MASTER)1088	ret = spi_register_driver(&wm8983_spi_driver);1089	if (ret != 0) {1090		printk(KERN_ERR "Failed to register wm8983 SPI driver: %d\n",1091		       ret);1092	}1093#endif1094	return ret;1095}1096module_init(wm8983_modinit);1097 1098static void __exit wm8983_exit(void)1099{1100#if IS_ENABLED(CONFIG_I2C)1101	i2c_del_driver(&wm8983_i2c_driver);1102#endif1103#if defined(CONFIG_SPI_MASTER)1104	spi_unregister_driver(&wm8983_spi_driver);1105#endif1106}1107module_exit(wm8983_exit);1108 1109MODULE_DESCRIPTION("ASoC WM8983 driver");1110MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");1111MODULE_LICENSE("GPL");1112