aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8903.c
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/codecs/wm8903.c
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r--sound/soc/codecs/wm8903.c268
1 files changed, 96 insertions, 172 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index bf08282d5ee5..f5d73ed72cbd 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -213,10 +213,12 @@ static u16 wm8903_reg_defaults[] = {
213}; 213};
214 214
215struct wm8903_priv { 215struct wm8903_priv {
216 struct snd_soc_codec codec; 216
217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)]; 217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
218 218
219 int sysclk; 219 int sysclk;
220 struct i2c_client *control_data;
221 int irq;
220 222
221 /* Reference counts */ 223 /* Reference counts */
222 int class_w_users; 224 int class_w_users;
@@ -252,7 +254,6 @@ static int wm8903_volatile_register(unsigned int reg)
252static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) 254static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
253{ 255{
254 u16 reg[5]; 256 u16 reg[5];
255 struct i2c_client *i2c = codec->control_data;
256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 257 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
257 258
258 BUG_ON(start > 48); 259 BUG_ON(start > 48);
@@ -262,7 +263,7 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 263 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
263 reg[0] | WM8903_WSEQ_ENA); 264 reg[0] | WM8903_WSEQ_ENA);
264 265
265 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 266 dev_dbg(codec->dev, "Starting sequence at %d\n", start);
266 267
267 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3, 268 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
268 start | WM8903_WSEQ_START); 269 start | WM8903_WSEQ_START);
@@ -277,7 +278,7 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); 278 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
278 } while (reg[4] & WM8903_WSEQ_BUSY); 279 } while (reg[4] & WM8903_WSEQ_BUSY);
279 280
280 dev_dbg(&i2c->dev, "Sequence complete\n"); 281 dev_dbg(codec->dev, "Sequence complete\n");
281 282
282 /* Disable the sequencer again if we enabled it */ 283 /* Disable the sequencer again if we enabled it */
283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 284 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
@@ -422,7 +423,6 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
422 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 423 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
423 struct snd_soc_codec *codec = widget->codec; 424 struct snd_soc_codec *codec = widget->codec;
424 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 425 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
425 struct i2c_client *i2c = codec->control_data;
426 u16 reg; 426 u16 reg;
427 int ret; 427 int ret;
428 428
@@ -431,7 +431,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
431 /* Turn it off if we're about to enable bypass */ 431 /* Turn it off if we're about to enable bypass */
432 if (ucontrol->value.integer.value[0]) { 432 if (ucontrol->value.integer.value[0]) {
433 if (wm8903->class_w_users == 0) { 433 if (wm8903->class_w_users == 0) {
434 dev_dbg(&i2c->dev, "Disabling Class W\n"); 434 dev_dbg(codec->dev, "Disabling Class W\n");
435 snd_soc_write(codec, WM8903_CLASS_W_0, reg & 435 snd_soc_write(codec, WM8903_CLASS_W_0, reg &
436 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); 436 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
437 } 437 }
@@ -444,14 +444,14 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
444 /* If we've just disabled the last bypass path turn Class W on */ 444 /* If we've just disabled the last bypass path turn Class W on */
445 if (!ucontrol->value.integer.value[0]) { 445 if (!ucontrol->value.integer.value[0]) {
446 if (wm8903->class_w_users == 1) { 446 if (wm8903->class_w_users == 1) {
447 dev_dbg(&i2c->dev, "Enabling Class W\n"); 447 dev_dbg(codec->dev, "Enabling Class W\n");
448 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 448 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
449 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 449 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
450 } 450 }
451 wm8903->class_w_users--; 451 wm8903->class_w_users--;
452 } 452 }
453 453
454 dev_dbg(&i2c->dev, "Bypass use count now %d\n", 454 dev_dbg(codec->dev, "Bypass use count now %d\n",
455 wm8903->class_w_users); 455 wm8903->class_w_users);
456 456
457 return ret; 457 return ret;
@@ -935,7 +935,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
935static int wm8903_set_bias_level(struct snd_soc_codec *codec, 935static int wm8903_set_bias_level(struct snd_soc_codec *codec,
936 enum snd_soc_bias_level level) 936 enum snd_soc_bias_level level)
937{ 937{
938 struct i2c_client *i2c = codec->control_data;
939 u16 reg, reg2; 938 u16 reg, reg2;
940 939
941 switch (level) { 940 switch (level) {
@@ -974,7 +973,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
974 /* By default no bypass paths are enabled so 973 /* By default no bypass paths are enabled so
975 * enable Class W support. 974 * enable Class W support.
976 */ 975 */
977 dev_dbg(&i2c->dev, "Enabling Class W\n"); 976 dev_dbg(codec->dev, "Enabling Class W\n");
978 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 977 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
979 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 978 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
980 } 979 }
@@ -1228,10 +1227,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1228 struct snd_soc_dai *dai) 1227 struct snd_soc_dai *dai)
1229{ 1228{
1230 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1229 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1231 struct snd_soc_device *socdev = rtd->socdev; 1230 struct snd_soc_codec *codec = rtd->codec;
1232 struct snd_soc_codec *codec = socdev->card->codec;
1233 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1231 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1234 struct i2c_client *i2c = codec->control_data;
1235 struct snd_pcm_runtime *master_runtime; 1232 struct snd_pcm_runtime *master_runtime;
1236 1233
1237 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1234 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1245,7 +1242,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1245 if (wm8903->master_substream) { 1242 if (wm8903->master_substream) {
1246 master_runtime = wm8903->master_substream->runtime; 1243 master_runtime = wm8903->master_substream->runtime;
1247 1244
1248 dev_dbg(&i2c->dev, "Constraining to %d bits\n", 1245 dev_dbg(codec->dev, "Constraining to %d bits\n",
1249 master_runtime->sample_bits); 1246 master_runtime->sample_bits);
1250 1247
1251 snd_pcm_hw_constraint_minmax(substream->runtime, 1248 snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -1264,8 +1261,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream,
1264 struct snd_soc_dai *dai) 1261 struct snd_soc_dai *dai)
1265{ 1262{
1266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1267 struct snd_soc_device *socdev = rtd->socdev; 1264 struct snd_soc_codec *codec = rtd->codec;
1268 struct snd_soc_codec *codec = socdev->card->codec;
1269 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1265 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1270 1266
1271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1267 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1284,10 +1280,8 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1284 struct snd_soc_dai *dai) 1280 struct snd_soc_dai *dai)
1285{ 1281{
1286 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1282 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1287 struct snd_soc_device *socdev = rtd->socdev; 1283 struct snd_soc_codec *codec =rtd->codec;
1288 struct snd_soc_codec *codec = socdev->card->codec;
1289 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1284 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1290 struct i2c_client *i2c = codec->control_data;
1291 int fs = params_rate(params); 1285 int fs = params_rate(params);
1292 int bclk; 1286 int bclk;
1293 int bclk_div; 1287 int bclk_div;
@@ -1306,7 +1300,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1306 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 1300 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1307 1301
1308 if (substream == wm8903->slave_substream) { 1302 if (substream == wm8903->slave_substream) {
1309 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 1303 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
1310 return 0; 1304 return 0;
1311 } 1305 }
1312 1306
@@ -1332,7 +1326,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1332 switch (sample_rates[dsp_config].rate) { 1326 switch (sample_rates[dsp_config].rate) {
1333 case 88200: 1327 case 88200:
1334 case 96000: 1328 case 96000:
1335 dev_err(&i2c->dev, "%dHz unsupported by ADC\n", 1329 dev_err(codec->dev, "%dHz unsupported by ADC\n",
1336 fs); 1330 fs);
1337 return -EINVAL; 1331 return -EINVAL;
1338 1332
@@ -1340,7 +1334,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1340 break; 1334 break;
1341 } 1335 }
1342 1336
1343 dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); 1337 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1344 clock1 &= ~WM8903_SAMPLE_RATE_MASK; 1338 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1345 clock1 |= sample_rates[dsp_config].value; 1339 clock1 |= sample_rates[dsp_config].value;
1346 1340
@@ -1366,7 +1360,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1366 return -EINVAL; 1360 return -EINVAL;
1367 } 1361 }
1368 1362
1369 dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n", 1363 dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n",
1370 wm8903->sysclk, fs); 1364 wm8903->sysclk, fs);
1371 1365
1372 /* We may not have an MCLK which allows us to generate exactly 1366 /* We may not have an MCLK which allows us to generate exactly
@@ -1401,12 +1395,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1401 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT; 1395 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
1402 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT; 1396 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
1403 1397
1404 dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n", 1398 dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
1405 clk_sys_ratios[clk_config].rate, 1399 clk_sys_ratios[clk_config].rate,
1406 clk_sys_ratios[clk_config].mode, 1400 clk_sys_ratios[clk_config].mode,
1407 clk_sys_ratios[clk_config].div); 1401 clk_sys_ratios[clk_config].div);
1408 1402
1409 dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys); 1403 dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
1410 1404
1411 /* We may not get quite the right frequency if using 1405 /* We may not get quite the right frequency if using
1412 * approximate clocks so look for the closest match that is 1406 * approximate clocks so look for the closest match that is
@@ -1428,7 +1422,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1428 aif2 &= ~WM8903_BCLK_DIV_MASK; 1422 aif2 &= ~WM8903_BCLK_DIV_MASK;
1429 aif3 &= ~WM8903_LRCLK_RATE_MASK; 1423 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1430 1424
1431 dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", 1425 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
1432 bclk_divs[bclk_div].ratio / 10, bclk, 1426 bclk_divs[bclk_div].ratio / 10, bclk,
1433 (clk_sys * 10) / bclk_divs[bclk_div].ratio); 1427 (clk_sys * 10) / bclk_divs[bclk_div].ratio);
1434 1428
@@ -1504,8 +1498,8 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1504 1498
1505static irqreturn_t wm8903_irq(int irq, void *data) 1499static irqreturn_t wm8903_irq(int irq, void *data)
1506{ 1500{
1507 struct wm8903_priv *wm8903 = data; 1501 struct snd_soc_codec *codec = data;
1508 struct snd_soc_codec *codec = &wm8903->codec; 1502 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1509 int mic_report; 1503 int mic_report;
1510 int int_pol; 1504 int int_pol;
1511 int int_val = 0; 1505 int int_val = 0;
@@ -1586,8 +1580,8 @@ static struct snd_soc_dai_ops wm8903_dai_ops = {
1586 .set_sysclk = wm8903_set_dai_sysclk, 1580 .set_sysclk = wm8903_set_dai_sysclk,
1587}; 1581};
1588 1582
1589struct snd_soc_dai wm8903_dai = { 1583static struct snd_soc_dai_driver wm8903_dai = {
1590 .name = "WM8903", 1584 .name = "wm8903-hifi",
1591 .playback = { 1585 .playback = {
1592 .stream_name = "Playback", 1586 .stream_name = "Playback",
1593 .channels_min = 2, 1587 .channels_min = 2,
@@ -1605,23 +1599,16 @@ struct snd_soc_dai wm8903_dai = {
1605 .ops = &wm8903_dai_ops, 1599 .ops = &wm8903_dai_ops,
1606 .symmetric_rates = 1, 1600 .symmetric_rates = 1,
1607}; 1601};
1608EXPORT_SYMBOL_GPL(wm8903_dai);
1609 1602
1610static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) 1603static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state)
1611{ 1604{
1612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1613 struct snd_soc_codec *codec = socdev->card->codec;
1614
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1605 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1616 1606
1617 return 0; 1607 return 0;
1618} 1608}
1619 1609
1620static int wm8903_resume(struct platform_device *pdev) 1610static int wm8903_resume(struct snd_soc_codec *codec)
1621{ 1611{
1622 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1623 struct snd_soc_codec *codec = socdev->card->codec;
1624 struct i2c_client *i2c = codec->control_data;
1625 int i; 1612 int i;
1626 u16 *reg_cache = codec->reg_cache; 1613 u16 *reg_cache = codec->reg_cache;
1627 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), 1614 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
@@ -1637,65 +1624,38 @@ static int wm8903_resume(struct platform_device *pdev)
1637 snd_soc_write(codec, i, tmp_cache[i]); 1624 snd_soc_write(codec, i, tmp_cache[i]);
1638 kfree(tmp_cache); 1625 kfree(tmp_cache);
1639 } else { 1626 } else {
1640 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1627 dev_err(codec->dev, "Failed to allocate temporary cache\n");
1641 } 1628 }
1642 1629
1643 return 0; 1630 return 0;
1644} 1631}
1645 1632
1646static struct snd_soc_codec *wm8903_codec; 1633static int wm8903_probe(struct snd_soc_codec *codec)
1647
1648static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1649 const struct i2c_device_id *id)
1650{ 1634{
1651 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); 1635 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1652 struct wm8903_priv *wm8903; 1636 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1653 struct snd_soc_codec *codec;
1654 int ret, i; 1637 int ret, i;
1655 int trigger, irq_pol; 1638 int trigger, irq_pol;
1656 u16 val; 1639 u16 val;
1657 1640
1658 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1659 if (wm8903 == NULL)
1660 return -ENOMEM;
1661
1662 codec = &wm8903->codec;
1663
1664 mutex_init(&codec->mutex);
1665 INIT_LIST_HEAD(&codec->dapm_widgets);
1666 INIT_LIST_HEAD(&codec->dapm_paths);
1667
1668 codec->dev = &i2c->dev;
1669 codec->name = "WM8903";
1670 codec->owner = THIS_MODULE;
1671 codec->bias_level = SND_SOC_BIAS_OFF;
1672 codec->set_bias_level = wm8903_set_bias_level;
1673 codec->dai = &wm8903_dai;
1674 codec->num_dai = 1;
1675 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1676 codec->reg_cache = &wm8903->reg_cache[0];
1677 snd_soc_codec_set_drvdata(codec, wm8903);
1678 codec->volatile_register = wm8903_volatile_register;
1679 init_completion(&wm8903->wseq); 1641 init_completion(&wm8903->wseq);
1680 1642 codec->control_data = wm8903->control_data;
1681 i2c_set_clientdata(i2c, codec);
1682 codec->control_data = i2c;
1683 1643
1684 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1644 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1685 if (ret != 0) { 1645 if (ret != 0) {
1686 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); 1646 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1687 goto err; 1647 return ret;
1688 } 1648 }
1689 1649
1690 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); 1650 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
1691 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1651 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1692 dev_err(&i2c->dev, 1652 dev_err(codec->dev,
1693 "Device with ID register %x is not a WM8903\n", val); 1653 "Device with ID register %x is not a WM8903\n", val);
1694 return -ENODEV; 1654 return -ENODEV;
1695 } 1655 }
1696 1656
1697 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); 1657 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1698 dev_info(&i2c->dev, "WM8903 revision %d\n", 1658 dev_info(codec->dev, "WM8903 revision %d\n",
1699 val & WM8903_CHIP_REV_MASK); 1659 val & WM8903_CHIP_REV_MASK);
1700 1660
1701 wm8903_reset(codec); 1661 wm8903_reset(codec);
@@ -1721,7 +1681,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1721 wm8903->mic_delay = pdata->micdet_delay; 1681 wm8903->mic_delay = pdata->micdet_delay;
1722 } 1682 }
1723 1683
1724 if (i2c->irq) { 1684 if (wm8903->irq) {
1725 if (pdata && pdata->irq_active_low) { 1685 if (pdata && pdata->irq_active_low) {
1726 trigger = IRQF_TRIGGER_LOW; 1686 trigger = IRQF_TRIGGER_LOW;
1727 irq_pol = WM8903_IRQ_POL; 1687 irq_pol = WM8903_IRQ_POL;
@@ -1733,13 +1693,13 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1733 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, 1693 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1734 WM8903_IRQ_POL, irq_pol); 1694 WM8903_IRQ_POL, irq_pol);
1735 1695
1736 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq, 1696 ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
1737 trigger | IRQF_ONESHOT, 1697 trigger | IRQF_ONESHOT,
1738 "wm8903", wm8903); 1698 "wm8903", codec);
1739 if (ret != 0) { 1699 if (ret != 0) {
1740 dev_err(&i2c->dev, "Failed to request IRQ: %d\n", 1700 dev_err(codec->dev, "Failed to request IRQ: %d\n",
1741 ret); 1701 ret);
1742 goto err; 1702 return ret;
1743 } 1703 }
1744 1704
1745 /* Enable write sequencer interrupts */ 1705 /* Enable write sequencer interrupts */
@@ -1781,133 +1741,97 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1781 val |= WM8903_DAC_MUTEMODE; 1741 val |= WM8903_DAC_MUTEMODE;
1782 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); 1742 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val);
1783 1743
1784 wm8903_dai.dev = &i2c->dev; 1744 snd_soc_add_controls(codec, wm8903_snd_controls,
1785 wm8903_codec = codec; 1745 ARRAY_SIZE(wm8903_snd_controls));
1786 1746 wm8903_add_widgets(codec);
1787 ret = snd_soc_register_codec(codec);
1788 if (ret != 0) {
1789 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1790 goto err_irq;
1791 }
1792
1793 ret = snd_soc_register_dai(&wm8903_dai);
1794 if (ret != 0) {
1795 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1796 goto err_codec;
1797 }
1798
1799 return ret;
1800 1747
1801err_codec:
1802 snd_soc_unregister_codec(codec);
1803err_irq:
1804 if (i2c->irq)
1805 free_irq(i2c->irq, wm8903);
1806err:
1807 wm8903_codec = NULL;
1808 kfree(wm8903);
1809 return ret; 1748 return ret;
1810} 1749}
1811 1750
1812static __devexit int wm8903_i2c_remove(struct i2c_client *client) 1751/* power down chip */
1752static int wm8903_remove(struct snd_soc_codec *codec)
1813{ 1753{
1814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1754 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1815 struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec); 1755 return 0;
1756}
1816 1757
1817 snd_soc_unregister_dai(&wm8903_dai); 1758static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1818 snd_soc_unregister_codec(codec); 1759 .probe = wm8903_probe,
1760 .remove = wm8903_remove,
1761 .suspend = wm8903_suspend,
1762 .resume = wm8903_resume,
1763 .set_bias_level = wm8903_set_bias_level,
1764 .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults),
1765 .reg_word_size = sizeof(u16),
1766 .reg_cache_default = wm8903_reg_defaults,
1767 .volatile_register = wm8903_volatile_register,
1768};
1819 1769
1820 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1770#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1771static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1772 const struct i2c_device_id *id)
1773{
1774 struct wm8903_priv *wm8903;
1775 int ret;
1821 1776
1822 if (client->irq) 1777 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1823 free_irq(client->irq, priv); 1778 if (wm8903 == NULL)
1779 return -ENOMEM;
1824 1780
1825 kfree(priv); 1781 i2c_set_clientdata(i2c, wm8903);
1782 wm8903->control_data = i2c;
1783 wm8903->irq = i2c->irq;
1826 1784
1827 wm8903_codec = NULL; 1785 ret = snd_soc_register_codec(&i2c->dev,
1828 wm8903_dai.dev = NULL; 1786 &soc_codec_dev_wm8903, &wm8903_dai, 1);
1787 if (ret < 0)
1788 kfree(wm8903);
1789 return ret;
1790}
1829 1791
1792static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1793{
1794 snd_soc_unregister_codec(&client->dev);
1795 kfree(i2c_get_clientdata(client));
1830 return 0; 1796 return 0;
1831} 1797}
1832 1798
1833/* i2c codec control layer */
1834static const struct i2c_device_id wm8903_i2c_id[] = { 1799static const struct i2c_device_id wm8903_i2c_id[] = {
1835 { "wm8903", 0 }, 1800 { "wm8903", 0 },
1836 { } 1801 { }
1837}; 1802};
1838MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); 1803MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1839 1804
1840static struct i2c_driver wm8903_i2c_driver = { 1805static struct i2c_driver wm8903_i2c_driver = {
1841 .driver = { 1806 .driver = {
1842 .name = "WM8903", 1807 .name = "wm8903-codec",
1843 .owner = THIS_MODULE, 1808 .owner = THIS_MODULE,
1844 }, 1809 },
1845 .probe = wm8903_i2c_probe, 1810 .probe = wm8903_i2c_probe,
1846 .remove = __devexit_p(wm8903_i2c_remove), 1811 .remove = __devexit_p(wm8903_i2c_remove),
1847 .id_table = wm8903_i2c_id, 1812 .id_table = wm8903_i2c_id,
1848}; 1813};
1814#endif
1849 1815
1850static int wm8903_probe(struct platform_device *pdev) 1816static int __init wm8903_modinit(void)
1851{ 1817{
1852 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1853 int ret = 0; 1818 int ret = 0;
1854 1819#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1855 if (!wm8903_codec) { 1820 ret = i2c_add_driver(&wm8903_i2c_driver);
1856 dev_err(&pdev->dev, "I2C device not yet probed\n"); 1821 if (ret != 0) {
1857 goto err; 1822 printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
1858 } 1823 ret);
1859
1860 socdev->card->codec = wm8903_codec;
1861
1862 /* register pcms */
1863 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1864 if (ret < 0) {
1865 dev_err(&pdev->dev, "failed to create pcms\n");
1866 goto err;
1867 } 1824 }
1868 1825#endif
1869 snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls,
1870 ARRAY_SIZE(wm8903_snd_controls));
1871 wm8903_add_widgets(socdev->card->codec);
1872
1873 return ret; 1826 return ret;
1874
1875err:
1876 return ret;
1877}
1878
1879/* power down chip */
1880static int wm8903_remove(struct platform_device *pdev)
1881{
1882 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1883 struct snd_soc_codec *codec = socdev->card->codec;
1884
1885 if (codec->control_data)
1886 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1887
1888 snd_soc_free_pcms(socdev);
1889 snd_soc_dapm_free(socdev);
1890
1891 return 0;
1892}
1893
1894struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1895 .probe = wm8903_probe,
1896 .remove = wm8903_remove,
1897 .suspend = wm8903_suspend,
1898 .resume = wm8903_resume,
1899};
1900EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1901
1902static int __init wm8903_modinit(void)
1903{
1904 return i2c_add_driver(&wm8903_i2c_driver);
1905} 1827}
1906module_init(wm8903_modinit); 1828module_init(wm8903_modinit);
1907 1829
1908static void __exit wm8903_exit(void) 1830static void __exit wm8903_exit(void)
1909{ 1831{
1832#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1910 i2c_del_driver(&wm8903_i2c_driver); 1833 i2c_del_driver(&wm8903_i2c_driver);
1834#endif
1911} 1835}
1912module_exit(wm8903_exit); 1836module_exit(wm8903_exit);
1913 1837