brintos

brintos / linux-shallow public Read only

0
0
Text · 22.7 KiB · a07a443 Raw
950 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * wm2000.c  --  WM2000 ALSA Soc Audio driver4 *5 * Copyright 2008-2011 Wolfson Microelectronics PLC.6 *7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>8 *9 * The download image for the WM2000 will be requested as10 * 'wm2000_anc.bin' by default (overridable via platform data) at11 * runtime and is expected to be in flat binary format.  This is12 * generated by Wolfson configuration tools and includes13 * system-specific calibration information.  If supplied as a14 * sequence of ASCII-encoded hexidecimal bytes this can be converted15 * into a flat binary with a command such as this on the command line:16 *17 * perl -e 'while (<>) { s/[\r\n]+// ; printf("%c", hex($_)); }'18 *                 < file  > wm2000_anc.bin19 */20 21#include <linux/module.h>22#include <linux/moduleparam.h>23#include <linux/kernel.h>24#include <linux/init.h>25#include <linux/firmware.h>26#include <linux/clk.h>27#include <linux/delay.h>28#include <linux/pm.h>29#include <linux/i2c.h>30#include <linux/regmap.h>31#include <linux/debugfs.h>32#include <linux/regulator/consumer.h>33#include <linux/slab.h>34#include <sound/core.h>35#include <sound/pcm.h>36#include <sound/pcm_params.h>37#include <sound/soc.h>38#include <sound/initval.h>39#include <sound/tlv.h>40 41#include <sound/wm2000.h>42 43#include "wm2000.h"44 45#define WM2000_NUM_SUPPLIES 346 47static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = {48	"SPKVDD",49	"DBVDD",50	"DCVDD",51};52 53enum wm2000_anc_mode {54	ANC_ACTIVE = 0,55	ANC_BYPASS = 1,56	ANC_STANDBY = 2,57	ANC_OFF = 3,58};59 60struct wm2000_priv {61	struct i2c_client *i2c;62	struct regmap *regmap;63	struct clk *mclk;64 65	struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES];66 67	enum wm2000_anc_mode anc_mode;68 69	unsigned int anc_active:1;70	unsigned int anc_eng_ena:1;71	unsigned int spk_ena:1;72 73	unsigned int speech_clarity:1;74 75	int anc_download_size;76	char *anc_download;77 78	struct mutex lock;79};80 81static int wm2000_write(struct i2c_client *i2c, unsigned int reg,82			unsigned int value)83{84	struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c);85	return regmap_write(wm2000->regmap, reg, value);86}87 88static void wm2000_reset(struct wm2000_priv *wm2000)89{90	struct i2c_client *i2c = wm2000->i2c;91 92	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);93	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);94	wm2000_write(i2c, WM2000_REG_ID1, 0);95 96	wm2000->anc_mode = ANC_OFF;97}98 99static int wm2000_poll_bit(struct i2c_client *i2c,100			   unsigned int reg, u8 mask)101{102	struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c);103	int timeout = 4000;104	unsigned int val;105 106	regmap_read(wm2000->regmap, reg, &val);107 108	while (!(val & mask) && --timeout) {109		msleep(1);110		regmap_read(wm2000->regmap, reg, &val);111	}112 113	if (timeout == 0)114		return 0;115	else116		return 1;117}118 119static int wm2000_power_up(struct i2c_client *i2c, int analogue)120{121	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);122	unsigned long rate;123	unsigned int val;124	int ret;125 126	if (WARN_ON(wm2000->anc_mode != ANC_OFF))127		return -EINVAL;128 129	dev_dbg(&i2c->dev, "Beginning power up\n");130 131	ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);132	if (ret != 0) {133		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);134		return ret;135	}136 137	rate = clk_get_rate(wm2000->mclk);138	if (rate <= 13500000) {139		dev_dbg(&i2c->dev, "Disabling MCLK divider\n");140		wm2000_write(i2c, WM2000_REG_SYS_CTL2,141			     WM2000_MCLK_DIV2_ENA_CLR);142	} else {143		dev_dbg(&i2c->dev, "Enabling MCLK divider\n");144		wm2000_write(i2c, WM2000_REG_SYS_CTL2,145			     WM2000_MCLK_DIV2_ENA_SET);146	}147 148	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);149	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_SET);150 151	/* Wait for ANC engine to become ready */152	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,153			     WM2000_ANC_ENG_IDLE)) {154		dev_err(&i2c->dev, "ANC engine failed to reset\n");155		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);156		return -ETIMEDOUT;157	}158 159	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,160			     WM2000_STATUS_BOOT_COMPLETE)) {161		dev_err(&i2c->dev, "ANC engine failed to initialise\n");162		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);163		return -ETIMEDOUT;164	}165 166	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);167 168	/* Open code download of the data since it is the only bulk169	 * write we do. */170	dev_dbg(&i2c->dev, "Downloading %d bytes\n",171		wm2000->anc_download_size - 2);172 173	ret = i2c_master_send(i2c, wm2000->anc_download,174			      wm2000->anc_download_size);175	if (ret < 0) {176		dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);177		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);178		return ret;179	}180	if (ret != wm2000->anc_download_size) {181		dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",182			ret, wm2000->anc_download_size);183		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);184		return -EIO;185	}186 187	dev_dbg(&i2c->dev, "Download complete\n");188 189	if (analogue) {190		wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4);191 192		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,193			     WM2000_MODE_ANA_SEQ_INCLUDE |194			     WM2000_MODE_MOUSE_ENABLE |195			     WM2000_MODE_THERMAL_ENABLE);196	} else {197		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,198			     WM2000_MODE_MOUSE_ENABLE |199			     WM2000_MODE_THERMAL_ENABLE);200	}201 202	ret = regmap_read(wm2000->regmap, WM2000_REG_SPEECH_CLARITY, &val);203	if (ret != 0) {204		dev_err(&i2c->dev, "Unable to read Speech Clarity: %d\n", ret);205		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);206		return ret;207	}208	if (wm2000->speech_clarity)209		val |= WM2000_SPEECH_CLARITY;210	else211		val &= ~WM2000_SPEECH_CLARITY;212	wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, val);213 214	wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);215	wm2000_write(i2c, WM2000_REG_SYS_START1, 0x02);216 217	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);218 219	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,220			     WM2000_STATUS_MOUSE_ACTIVE)) {221		dev_err(&i2c->dev, "Timed out waiting for device\n");222		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);223		return -ETIMEDOUT;224	}225 226	dev_dbg(&i2c->dev, "ANC active\n");227	if (analogue)228		dev_dbg(&i2c->dev, "Analogue active\n");229	wm2000->anc_mode = ANC_ACTIVE;230 231	return 0;232}233 234static int wm2000_power_down(struct i2c_client *i2c, int analogue)235{236	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);237 238	if (analogue) {239		wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4);240		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,241			     WM2000_MODE_ANA_SEQ_INCLUDE |242			     WM2000_MODE_POWER_DOWN);243	} else {244		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,245			     WM2000_MODE_POWER_DOWN);246	}247 248	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,249			     WM2000_STATUS_POWER_DOWN_COMPLETE)) {250		dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");251		return -ETIMEDOUT;252	}253 254	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,255			     WM2000_ANC_ENG_IDLE)) {256		dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");257		return -ETIMEDOUT;258	}259 260	regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);261 262	dev_dbg(&i2c->dev, "powered off\n");263	wm2000->anc_mode = ANC_OFF;264 265	return 0;266}267 268static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)269{270	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);271 272	if (WARN_ON(wm2000->anc_mode != ANC_ACTIVE))273		return -EINVAL;274 275	if (analogue) {276		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,277			     WM2000_MODE_ANA_SEQ_INCLUDE |278			     WM2000_MODE_THERMAL_ENABLE |279			     WM2000_MODE_BYPASS_ENTRY);280	} else {281		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,282			     WM2000_MODE_THERMAL_ENABLE |283			     WM2000_MODE_BYPASS_ENTRY);284	}285 286	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,287			     WM2000_STATUS_ANC_DISABLED)) {288		dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");289		return -ETIMEDOUT;290	}291 292	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,293			     WM2000_ANC_ENG_IDLE)) {294		dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");295		return -ETIMEDOUT;296	}297 298	wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);299	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);300 301	wm2000->anc_mode = ANC_BYPASS;302	dev_dbg(&i2c->dev, "bypass enabled\n");303 304	return 0;305}306 307static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)308{309	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);310 311	if (WARN_ON(wm2000->anc_mode != ANC_BYPASS))312		return -EINVAL;313	314	wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);315 316	if (analogue) {317		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,318			     WM2000_MODE_ANA_SEQ_INCLUDE |319			     WM2000_MODE_MOUSE_ENABLE |320			     WM2000_MODE_THERMAL_ENABLE);321	} else {322		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,323			     WM2000_MODE_MOUSE_ENABLE |324			     WM2000_MODE_THERMAL_ENABLE);325	}326 327	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);328	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);329 330	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,331			     WM2000_STATUS_MOUSE_ACTIVE)) {332		dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");333		return -ETIMEDOUT;334	}335 336	wm2000->anc_mode = ANC_ACTIVE;337	dev_dbg(&i2c->dev, "MOUSE active\n");338 339	return 0;340}341 342static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)343{344	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);345 346	if (WARN_ON(wm2000->anc_mode != ANC_ACTIVE))347		return -EINVAL;348 349	if (analogue) {350		wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4);351 352		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,353			     WM2000_MODE_ANA_SEQ_INCLUDE |354			     WM2000_MODE_THERMAL_ENABLE |355			     WM2000_MODE_STANDBY_ENTRY);356	} else {357		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,358			     WM2000_MODE_THERMAL_ENABLE |359			     WM2000_MODE_STANDBY_ENTRY);360	}361 362	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,363			     WM2000_STATUS_ANC_DISABLED)) {364		dev_err(&i2c->dev,365			"Timed out waiting for ANC disable after 1ms\n");366		return -ETIMEDOUT;367	}368 369	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) {370		dev_err(&i2c->dev,371			"Timed out waiting for standby\n");372		return -ETIMEDOUT;373	}374 375	wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);376	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);377 378	wm2000->anc_mode = ANC_STANDBY;379	dev_dbg(&i2c->dev, "standby\n");380	if (analogue)381		dev_dbg(&i2c->dev, "Analogue disabled\n");382 383	return 0;384}385 386static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)387{388	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);389 390	if (WARN_ON(wm2000->anc_mode != ANC_STANDBY))391		return -EINVAL;392 393	wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);394 395	if (analogue) {396		wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4);397 398		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,399			     WM2000_MODE_ANA_SEQ_INCLUDE |400			     WM2000_MODE_THERMAL_ENABLE |401			     WM2000_MODE_MOUSE_ENABLE);402	} else {403		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,404			     WM2000_MODE_THERMAL_ENABLE |405			     WM2000_MODE_MOUSE_ENABLE);406	}407 408	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);409	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);410 411	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,412			     WM2000_STATUS_MOUSE_ACTIVE)) {413		dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");414		return -ETIMEDOUT;415	}416 417	wm2000->anc_mode = ANC_ACTIVE;418	dev_dbg(&i2c->dev, "MOUSE active\n");419	if (analogue)420		dev_dbg(&i2c->dev, "Analogue enabled\n");421 422	return 0;423}424 425typedef int (*wm2000_mode_fn)(struct i2c_client *i2c, int analogue);426 427static struct {428	enum wm2000_anc_mode source;429	enum wm2000_anc_mode dest;430	int analogue;431	wm2000_mode_fn step[2];432} anc_transitions[] = {433	{434		.source = ANC_OFF,435		.dest = ANC_ACTIVE,436		.analogue = 1,437		.step = {438			wm2000_power_up,439		},440	},441	{442		.source = ANC_OFF,443		.dest = ANC_STANDBY,444		.step = {445			wm2000_power_up,446			wm2000_enter_standby,447		},448	},449	{450		.source = ANC_OFF,451		.dest = ANC_BYPASS,452		.analogue = 1,453		.step = {454			wm2000_power_up,455			wm2000_enter_bypass,456		},457	},458	{459		.source = ANC_ACTIVE,460		.dest = ANC_BYPASS,461		.analogue = 1,462		.step = {463			wm2000_enter_bypass,464		},465	},466	{467		.source = ANC_ACTIVE,468		.dest = ANC_STANDBY,469		.analogue = 1,470		.step = {471			wm2000_enter_standby,472		},473	},474	{475		.source = ANC_ACTIVE,476		.dest = ANC_OFF,477		.analogue = 1,478		.step = {479			wm2000_power_down,480		},481	},482	{483		.source = ANC_BYPASS,484		.dest = ANC_ACTIVE,485		.analogue = 1,486		.step = {487			wm2000_exit_bypass,488		},489	},490	{491		.source = ANC_BYPASS,492		.dest = ANC_STANDBY,493		.analogue = 1,494		.step = {495			wm2000_exit_bypass,496			wm2000_enter_standby,497		},498	},499	{500		.source = ANC_BYPASS,501		.dest = ANC_OFF,502		.step = {503			wm2000_exit_bypass,504			wm2000_power_down,505		},506	},507	{508		.source = ANC_STANDBY,509		.dest = ANC_ACTIVE,510		.analogue = 1,511		.step = {512			wm2000_exit_standby,513		},514	},515	{516		.source = ANC_STANDBY,517		.dest = ANC_BYPASS,518		.analogue = 1,519		.step = {520			wm2000_exit_standby,521			wm2000_enter_bypass,522		},523	},524	{525		.source = ANC_STANDBY,526		.dest = ANC_OFF,527		.step = {528			wm2000_exit_standby,529			wm2000_power_down,530		},531	},532};533 534static int wm2000_anc_transition(struct wm2000_priv *wm2000,535				 enum wm2000_anc_mode mode)536{537	struct i2c_client *i2c = wm2000->i2c;538	int i, j;539	int ret = 0;540 541	if (wm2000->anc_mode == mode)542		return 0;543 544	for (i = 0; i < ARRAY_SIZE(anc_transitions); i++)545		if (anc_transitions[i].source == wm2000->anc_mode &&546		    anc_transitions[i].dest == mode)547			break;548	if (i == ARRAY_SIZE(anc_transitions)) {549		dev_err(&i2c->dev, "No transition for %d->%d\n",550			wm2000->anc_mode, mode);551		return -EINVAL;552	}553 554	/* Maintain clock while active */555	if (anc_transitions[i].source == ANC_OFF) {556		ret = clk_prepare_enable(wm2000->mclk);557		if (ret != 0) {558			dev_err(&i2c->dev, "Failed to enable MCLK: %d\n", ret);559			return ret;560		}561	}562 563	for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {564		if (!anc_transitions[i].step[j])565			break;566		ret = anc_transitions[i].step[j](i2c,567						 anc_transitions[i].analogue);568		if (ret != 0)569			break;570	}571 572	if (anc_transitions[i].dest == ANC_OFF)573		clk_disable_unprepare(wm2000->mclk);574 575	return ret;576}577 578static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)579{580	struct i2c_client *i2c = wm2000->i2c;581	enum wm2000_anc_mode mode;582 583	if (wm2000->anc_eng_ena && wm2000->spk_ena)584		if (wm2000->anc_active)585			mode = ANC_ACTIVE;586		else587			mode = ANC_BYPASS;588	else589		mode = ANC_STANDBY;590 591	dev_dbg(&i2c->dev, "Set mode %d (enabled %d, mute %d, active %d)\n",592		mode, wm2000->anc_eng_ena, !wm2000->spk_ena,593		wm2000->anc_active);594 595	return wm2000_anc_transition(wm2000, mode);596}597 598static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,599			       struct snd_ctl_elem_value *ucontrol)600{601	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);602	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);603 604	ucontrol->value.integer.value[0] = wm2000->anc_active;605 606	return 0;607}608 609static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,610			       struct snd_ctl_elem_value *ucontrol)611{612	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);613	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);614	unsigned int anc_active = ucontrol->value.integer.value[0];615	int ret;616 617	if (anc_active > 1)618		return -EINVAL;619 620	mutex_lock(&wm2000->lock);621 622	wm2000->anc_active = anc_active;623 624	ret = wm2000_anc_set_mode(wm2000);625 626	mutex_unlock(&wm2000->lock);627 628	return ret;629}630 631static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,632			      struct snd_ctl_elem_value *ucontrol)633{634	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);635	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);636 637	ucontrol->value.integer.value[0] = wm2000->spk_ena;638 639	return 0;640}641 642static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,643			      struct snd_ctl_elem_value *ucontrol)644{645	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);646	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);647	unsigned int val = ucontrol->value.integer.value[0];648	int ret;649 650	if (val > 1)651		return -EINVAL;652 653	mutex_lock(&wm2000->lock);654 655	wm2000->spk_ena = val;656 657	ret = wm2000_anc_set_mode(wm2000);658 659	mutex_unlock(&wm2000->lock);660 661	return ret;662}663 664static const struct snd_kcontrol_new wm2000_controls[] = {665	SOC_SINGLE("ANC Volume", WM2000_REG_ANC_GAIN_CTRL, 0, 255, 0),666	SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,667			    wm2000_anc_mode_get,668			    wm2000_anc_mode_put),669	SOC_SINGLE_BOOL_EXT("WM2000 Switch", 0,670			    wm2000_speaker_get,671			    wm2000_speaker_put),672};673 674static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,675				  struct snd_kcontrol *kcontrol, int event)676{677	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);678	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);679	int ret;680 681	mutex_lock(&wm2000->lock);682 683	if (SND_SOC_DAPM_EVENT_ON(event))684		wm2000->anc_eng_ena = 1;685 686	if (SND_SOC_DAPM_EVENT_OFF(event))687		wm2000->anc_eng_ena = 0;688 689	ret = wm2000_anc_set_mode(wm2000);690 691	mutex_unlock(&wm2000->lock);692 693	return ret;694}695 696static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {697/* Externally visible pins */698SND_SOC_DAPM_OUTPUT("SPKN"),699SND_SOC_DAPM_OUTPUT("SPKP"),700 701SND_SOC_DAPM_INPUT("LINN"),702SND_SOC_DAPM_INPUT("LINP"),703 704SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,705		   wm2000_anc_power_event,706		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),707};708 709/* Target, Path, Source */710static const struct snd_soc_dapm_route wm2000_audio_map[] = {711	{ "SPKN", NULL, "ANC Engine" },712	{ "SPKP", NULL, "ANC Engine" },713	{ "ANC Engine", NULL, "LINN" },714	{ "ANC Engine", NULL, "LINP" },715};716 717#ifdef CONFIG_PM718static int wm2000_suspend(struct snd_soc_component *component)719{720	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);721 722	return wm2000_anc_transition(wm2000, ANC_OFF);723}724 725static int wm2000_resume(struct snd_soc_component *component)726{727	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);728 729	return wm2000_anc_set_mode(wm2000);730}731#else732#define wm2000_suspend NULL733#define wm2000_resume NULL734#endif735 736static bool wm2000_readable_reg(struct device *dev, unsigned int reg)737{738	switch (reg) {739	case WM2000_REG_SYS_START:740	case WM2000_REG_ANC_GAIN_CTRL:741	case WM2000_REG_MSE_TH1:742	case WM2000_REG_MSE_TH2:743	case WM2000_REG_SPEECH_CLARITY:744	case WM2000_REG_SYS_WATCHDOG:745	case WM2000_REG_ANA_VMID_PD_TIME:746	case WM2000_REG_ANA_VMID_PU_TIME:747	case WM2000_REG_CAT_FLTR_INDX:748	case WM2000_REG_CAT_GAIN_0:749	case WM2000_REG_SYS_STATUS:750	case WM2000_REG_SYS_MODE_CNTRL:751	case WM2000_REG_SYS_START0:752	case WM2000_REG_SYS_START1:753	case WM2000_REG_ID1:754	case WM2000_REG_ID2:755	case WM2000_REG_REVISON:756	case WM2000_REG_SYS_CTL1:757	case WM2000_REG_SYS_CTL2:758	case WM2000_REG_ANC_STAT:759	case WM2000_REG_IF_CTL:760	case WM2000_REG_ANA_MIC_CTL:761	case WM2000_REG_SPK_CTL:762		return true;763	default:764		return false;765	}766}767 768static const struct regmap_config wm2000_regmap = {769	.reg_bits = 16,770	.val_bits = 8,771 772	.max_register = WM2000_REG_SPK_CTL,773	.readable_reg = wm2000_readable_reg,774};775 776static int wm2000_probe(struct snd_soc_component *component)777{778	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);779 780	/* This will trigger a transition to standby mode by default */781	wm2000_anc_set_mode(wm2000);782 783	return 0;784}785 786static void wm2000_remove(struct snd_soc_component *component)787{788	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);789 790	wm2000_anc_transition(wm2000, ANC_OFF);791}792 793static const struct snd_soc_component_driver soc_component_dev_wm2000 = {794	.probe			= wm2000_probe,795	.remove			= wm2000_remove,796	.suspend		= wm2000_suspend,797	.resume			= wm2000_resume,798	.controls		= wm2000_controls,799	.num_controls		= ARRAY_SIZE(wm2000_controls),800	.dapm_widgets		= wm2000_dapm_widgets,801	.num_dapm_widgets	= ARRAY_SIZE(wm2000_dapm_widgets),802	.dapm_routes		= wm2000_audio_map,803	.num_dapm_routes	= ARRAY_SIZE(wm2000_audio_map),804	.idle_bias_on		= 1,805	.use_pmdown_time	= 1,806};807 808static int wm2000_i2c_probe(struct i2c_client *i2c)809{810	struct wm2000_priv *wm2000;811	struct wm2000_platform_data *pdata;812	const char *filename;813	const struct firmware *fw = NULL;814	int ret, i;815	unsigned int reg;816	u16 id;817 818	wm2000 = devm_kzalloc(&i2c->dev, sizeof(*wm2000), GFP_KERNEL);819	if (!wm2000)820		return -ENOMEM;821 822	mutex_init(&wm2000->lock);823 824	dev_set_drvdata(&i2c->dev, wm2000);825 826	wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap);827	if (IS_ERR(wm2000->regmap)) {828		ret = PTR_ERR(wm2000->regmap);829		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",830			ret);831		goto out;832	}833 834	for (i = 0; i < WM2000_NUM_SUPPLIES; i++)835		wm2000->supplies[i].supply = wm2000_supplies[i];836 837	ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES,838				      wm2000->supplies);839	if (ret != 0) {840		dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret);841		return ret;842	}843 844	ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);845	if (ret != 0) {846		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);847		return ret;848	}849 850	/* Verify that this is a WM2000 */851	ret = regmap_read(wm2000->regmap, WM2000_REG_ID1, &reg);852	if (ret != 0) {853		dev_err(&i2c->dev, "Unable to read ID1: %d\n", ret);854		return ret;855	}856	id = reg << 8;857	ret = regmap_read(wm2000->regmap, WM2000_REG_ID2, &reg);858	if (ret != 0) {859		dev_err(&i2c->dev, "Unable to read ID2: %d\n", ret);860		return ret;861	}862	id |= reg & 0xff;863 864	if (id != 0x2000) {865		dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);866		ret = -ENODEV;867		goto err_supplies;868	}869 870	ret = regmap_read(wm2000->regmap, WM2000_REG_REVISON, &reg);871	if (ret != 0) {872		dev_err(&i2c->dev, "Unable to read Revision: %d\n", ret);873		return ret;874	}875	dev_info(&i2c->dev, "revision %c\n", reg + 'A');876 877	wm2000->mclk = devm_clk_get(&i2c->dev, "MCLK");878	if (IS_ERR(wm2000->mclk)) {879		ret = PTR_ERR(wm2000->mclk);880		dev_err(&i2c->dev, "Failed to get MCLK: %d\n", ret);881		goto err_supplies;882	}883 884	filename = "wm2000_anc.bin";885	pdata = dev_get_platdata(&i2c->dev);886	if (pdata) {887		wm2000->speech_clarity = !pdata->speech_enh_disable;888 889		if (pdata->download_file)890			filename = pdata->download_file;891	}892 893	ret = request_firmware(&fw, filename, &i2c->dev);894	if (ret != 0) {895		dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);896		goto err_supplies;897	}898 899	/* Pre-cook the concatenation of the register address onto the image */900	wm2000->anc_download_size = fw->size + 2;901	wm2000->anc_download = devm_kzalloc(&i2c->dev,902					    wm2000->anc_download_size,903					    GFP_KERNEL);904	if (wm2000->anc_download == NULL) {905		ret = -ENOMEM;906		goto err_supplies;907	}908 909	wm2000->anc_download[0] = 0x80;910	wm2000->anc_download[1] = 0x00;911	memcpy(wm2000->anc_download + 2, fw->data, fw->size);912 913	wm2000->anc_eng_ena = 1;914	wm2000->anc_active = 1;915	wm2000->spk_ena = 1;916	wm2000->i2c = i2c;917 918	wm2000_reset(wm2000);919 920	ret = devm_snd_soc_register_component(&i2c->dev,921					&soc_component_dev_wm2000, NULL, 0);922 923err_supplies:924	regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);925 926out:927	release_firmware(fw);928	return ret;929}930 931static const struct i2c_device_id wm2000_i2c_id[] = {932	{ "wm2000" },933	{ }934};935MODULE_DEVICE_TABLE(i2c, wm2000_i2c_id);936 937static struct i2c_driver wm2000_i2c_driver = {938	.driver = {939		.name = "wm2000",940	},941	.probe = wm2000_i2c_probe,942	.id_table = wm2000_i2c_id,943};944 945module_i2c_driver(wm2000_i2c_driver);946 947MODULE_DESCRIPTION("ASoC WM2000 driver");948MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");949MODULE_LICENSE("GPL");950